text:
<?xml version="1.0" encoding="UTF-8"?>

<idea-plugin url="http://github.com/vsch/idea-multimarkdown" xmlns:xi="http://www.w3.org/2001/XInclude">
    <id>com.vladsch.idea.multimarkdown</id>
    <name>Markdown Navigator Basic</name>
    <category>Custom Languages</category>
    <vendor email="vladimir.schneider@gmail.com" url="http://www.vladsch.com">Vladimir Schneider</vendor>
    <depends>com.intellij.modules.lang</depends>
    <depends>Git4Idea</depends>
    <depends optional="true" config-file="plugin-intellilang.xml">org.intellij.intelliLang</depends>
    <depends optional="true" config-file="plugin-java.xml">com.intellij.java</depends>
    <depends optional="true" config-file="plugin-grazie.xml">tanvd.grazi</depends>
    <depends optional="true" config-file="plugin-images.xml">com.intellij.platform.images</depends>

    <resource-bundle>com.vladsch.md.nav.localization.strings</resource-bundle>

    <version>3.0.201.105.Legacy</version>
    <idea-version since-build="201"/>

    <description><![CDATA[

Markdown language support for IntelliJ platform

Markdown Navigator enhanced edition

                available in JetBrains Marketplace or with a legacy license.

Document with pleasure!

Work with Markdown files like you do with other languages in the IDE, by getting full support
                for:

Paste images into documents for fast screen capture links

Drag & Drop files and images for fast link insertion

Formatting to cleanup documents with a key stroke

Navigation and Find Usages to find references without effort

Copy Markdown as JIRA, YouTrack or HTML formatted text

Convert HTML to Markdown by pasting it into a Markdown document.

Export to HTML or PDF to share with others

Refactoring of all referencing elements:

files ⟺ links

headings ⟺ ref anchors

footnotes ⟺ footnote refs

references ⟺ ref links/ref images

Completions to reduce typing:

link address ⇐ files

ref anchors ⇐ headings

footnote refs ⇐ footnotes

ref links/ref images ⇐ references

link text ⇐ ref anchor/link address

Error and Warning annotations to help catch mistakes early

Intention actions for fast results with less effort

Wrap on Typing to keep it nicely formatted as you edit

GitHub style rendering that you are used to, out of the box

GitLab parsing and rendering extensions

Math extension using Katex

Charts extension using Mermaid

Math block and inline rendering by Katex or codecogs.com

PlantUML fenced code rendering by PlantUML or gravizo.com

Fast typing response for distraction free editing

Fully customizable to adjust to your preferences and project needs

        ]]></description>

    <change-notes><![CDATA[

3.0.201.105 - Bug Fix Release

Fix: HTML to Md converter to convert empty a tags to empty link text links.

Add: HTML Generation option Use URL as default title.

3.0.201.103 - Bug Fix Release

Fix: fix link refs to Java/Kotlin files for 2020.2 and AndroidStudio

3.0.201.101 - Bug Fix Release

Fix: javafx tools debugger to handle failure when running Java 14 with
                        alternate JavaFX Implementation.

3.0.201.99 - Bug Fix Release

Fix: erroneous optimized TOC levels options for single level headings.

Fix: add anchor links settings migrated flag.

Fix: smart edit chars: *, _, ~ and `, on space to delete
                    auto-inserted char and allow space processing to proceed. Otherwise,
                    auto-wrap on space only does not wrap after auto-inserted character is
                    replaced by a space.

3.0.201.97 - Bug Fix Release

Fix: diagnostic/4988, IndexOutOfBoundsException in
                    MoveColumnLeftAction

Fix: diagnostic/4985, IndexOutOfBoundsException in
                    MdFoldingVisitor.updateHeadingRanges()

Fix: diagnostic/4975, AlreadyDisposedException in
                    HtmlRendererExtension.addRenderingProfileOptions

Fix: anchor links setting migration would reset new settings flag.

3.0.201.95 - Bug Fix Release

Fix: remove 2020.1.2 API use

3.0.201.93 - Bug Fix Release

Fix: multi-file drop could mess up links for files after the first
                    dropped file.

Fix: spurious reset of enhanced settings to defaults.

Fix: clean up deprecated API use.

Fix: TOC levels parsing to match optimized levels syntax.

Fix: Move Anchor links option from Parser to HTML settings.

3.0.201.91 - Bug Fix Release

Add: editor visual guides field to code style wrapping tab

Fix:
                    #848, Markdown panel does not appear on scratch files - Pycharm 2020.1 Pro,
                    reverted file type test code for editor provider to file language type
                    test which works for scratch files created via New File action in
                    Scratches directory.

Fix: make all plugin topics to not broadcast to parent/child message
                    buses.

Fix:
                    #844, Jekyll include elements do not show included content in preview

Fix:
                    #828, Memory leak when project is closed due to MdProjectSettings

Fix: Tab/Back-Tab list indentation for items at end of file, without
                    an EOL and for empty list items with no space after marker.

Fix: paragraph wrapping context at end of line after editing.

3.0.201.89 - Bug Fix Release

Fix: diagnostic/4558, concurrent modification in fenced code
                    conversion manager.

Fix:
                    #840, Edit Table of Contents style intention dialog has no effect,
                    toc style edit ignores title level setting if title text has leading
                    # chars.

Fix: wrap on typing removing footnote and definition prefix, resulting
                    in indented code instead of the original element.

3.0.201.87 - Bug Fix Release

Add: Inspections for math, mermaid and plantuml to enable required
                    settings if with code fenced elements for these are found in the file.

Fix: diagnostic/4843, tracked position mismatch after wrapping.

Fix:
                    #840, Edit Table of Contents style intention dialog has no effect,
                    missing update of title level in form

3.0.201.85 - Bug Fix EAP Release

Fix: #840, Edit Table of Contents style intention dialog has no effect, introduced in code
                    refactoring

Fix: CSS Script requirement validation done by image converter extensions

Add: GitLab mermaid link from Parser mermaid to fenced code mermaid

Add: GitLab math link from Parser math to fenced code math

3.0.201.83 - Bug Fix EAP Release

Fix: diagnostic/4707

Fix: diagnostic/4550

Fix: diagnostic/4640

Fix: reversed line marker for flexmark spec example FILE_EOL and NO_FILE_EOL options.

Fix: update Show heading id label text on license state change

3.0.201.81 - 2020.1 Bug Fix EAP Release

Fix: multiline URL image links should not wrap

Fix: for image-to-fenced code and image-to-inline math conversion, accept http:// url prefix
                    as equivalent to https://

Fix: GitHub header id generation compatibility:

Add Emoji shortcuts

Fix ref link images should not trim trailing spaces in reference or

3.0.201.79 - 2020.1 EAP Bug Fix & Enhancement EAP Release

Fix: wiki links should not be wrapped during formatting.

Fix: Link map default map content for Link Address Element

Add: Preferences dialog Menu Split proportion for configurable tree menu to allow full
                    control of preferences dialog layout for screenshot capture.

Fix: exception report settings saved twice in plugin shared settings.

Add: kroki.io fenced code rendering extension

Fix: update plantuml to version asl-1.2020.6

Add: JLatexMath library and option to math image
                    rendering.

Fix: add Fenced Code settings pane under HTML Generation

Fix: change UML rendering to use fenced code image rendering EP

Fix: change Math rendering to use fenced code image rendering EP

Fix: change HTML Settings to use new fenced code image rendering EP

3.0.201.75 - 2020.1 EAP Bug Fix EAP Release

Add: GrammarCheckingStrategy for Grazie support in Markdown files.

Add: Ignore casing of simple list item text in editor settings to ignore capitalization of
                    single line text for list item and definition paragraphs.

Fix: compatibility for 2020.2 snapshot

Fix: Project file monitor not checking that alarm is disposed.

Fix: use of IDE resource bundle in code style

Fix: update to flexmark-java 0.61.0

3.0.xxx.72 - 2019.x Bug Fix Release

Fix: add border around legacy license code text area to identify it in settings

Fix: diagnostic/4566, IndexOutOfBoundsException: MdLanguageInjector.getLanguagesToInject

Add: ability to collapse extension settings sections to allow to minimize needed real-estate
                    in settings dialog.

Fix: HTML Generation, Head Top checkbox does not change settings and does not save.

Fix: HTML Generation sections should have scroll pane, otherwise section are hidden if
                    dialog is not big enough

Fix: repo relative images do not get resolved in preview

3.0.xxx.68 - EAP Release

Fix: regression bug, #818, broken TOC links

3.0.197.64 - 2019.3 Compatibility Release

Add: div based HTML tables based on hard-coded class names

3.0.197.62 - 2019.3 Compatibility Release

Fix: change version numbers to be compatible between marketplace and legacy versions.

Fix: marketplace licensed plugin for EAP IDE versions.

3.0.193.60 - 2019.3 Compatibility Release

Add: lic dist versions for marketplace licensing

Fix: move licensing to own class

Fix: broken Markdown to HTML intention

Fix: change references keep to first so sort unused last does not toggle references

Fix: for Copy Markdown as HTML Mime Content action to use current file’s profile parser
                    settings instead of the COPY_HTML_MIME profile parser settings

Fix: use own icons for table dialogs

Fix: Formatter equalize trailing marker should not add marker if there is none

Fix: toc dropping apostrophe from heading text if text only TOC option and typographic
                    apostrophes are enabled.

Fix: update to cleaned up flexmark-java

Fix: missing add ignore annotation to links and reference definitions

Fix: missing prepare file for write in quick fixes

Fix: Add spec test selection is not available in list items

Fix: GitHub page displayed in preview without option being selected

Fix: flexmark debug extensions settings not saved.

Fix: #767, Do not highlight [DONE] as error, adding a reference map to empty text will
                    disable these references from being unresolved and also render them as text.

Add: #779, Ignore character casing when checking for matching header

Fix: change MdProjectRemoteContentCache to project component

Fix: typing before/after table caption

Fix: convert parser tests to light platform test case

Fix: remove tail blank line generation in formatter after fenced code when last child item

Fix: Remove unused static LOG in classes

Fix: document removed free features from basic version. Intentions are mostly enhanced.

Fix: GitHub issue completion when # is at start of line, parsed as header level not
                    paragraph text.

Fix: move references to enh implementation from basic sources

Fix: complete remove move refs to enh sources from basic psi dir

Fix: remove flexmark plugin refs from enh and basic sources

Add: flexmark document and structure view icons to basic icons

Fix: make MdHighlighterColors a service to prevent multiple instance in the application

Fix: restore GitHubTableInspection and add tests

Fix: split basic/enh resources

Fix: table element formatting

Fix: format document with actual char width

Fix: code style settings preview with actual char width

Fix: cleanup unused icons

Fix: move flexmark intention icon to flexmark icons

Fix: sort extensions by name and add extension name to settings forms based on extension
                    provided name

Fix: add md nav enh heading to exception reports settings

Fix: move all intentions using enh features to enh plugin.

Fix: split plugin.xml into components and add xmlmerge java utility to merge them into
                    single plugin.xml file to allow sharing parts between enh and basic plugins.

Fix: rename dir idea/multimarkdown to md/nav

Fix: message bus creation compatibility with 2020.1 and 2019.3.

Fix: typing > in prefix removes first x characters where x is the size of indentation before
                    >

Fix: backspacing over > after list item prefix should remove block quote not the list item

Fix: typing space at start of indented child paragraph would unindent the paragraph instead of
                    indenting it.

Fix: doubling of typed character when typing at start of indented child paragraph.

Fix: on file save toc update did not resolve duped heading ids.

Fix: add 250ms delay to ProjectFileMonitor invoking file test to allow the IDE to detect and
                    sync modified jars.

Fix: diagnostic/4450, Write access is allowed inside write-action only, inside
                    MdPasteHandler

Fix: diagnostic/4462, IndexOutOfBoundsException: MdStripTrailingSpacesSmartFilter

Fix: split parser settings into extensions

Fix: split flexmark debug settings to extension

Fix: split enh and flexmark color settings into extensions

Fix: when pasting selection reference over the link address of link whose text matches
                    selection link ref text pattern then replace the link element not just the address and anchor
                    ref.

Fix: remove SimToc annotation for title string needs space. No longer true for updated
                    flexmark-java parser.

Add: MdTabOverride/MdBackTabOverride option to treat empty items differently:

treat empty items as having no children, should only indent/unindent the item in all cases.

should roll-over between highest and lowest indentation level when the item can no longer be
                            indented to allow tab to be used to adjust sub-item to parent item

Fix: replace Psi based TOC update on save by flexmark-java library based update.

Add: MdOnSaveFileUpdater test

Fix: fix TOC update on save to use parser defined list indent instead of 4 fixed.

Fix: change EAP update channel to JetBrains plugin repository EAP channel

Fix: add task item prefix to disable wrap prefix patterns to allow typing task item with wrap
                    on typing enabled.

Fix: LineAppendable should not remove leading EOL with 0 flags nor do any space trimming
                    when appending content to an appendable. Was causing injected language processing to generate
                    exception.

Fix: wrap on typing caret position recovery.

Fix: missing typing disabled pattern for ATX heading

Fix: assertion failure in MdCodeStyleSettings which could cause settings load issues.

Fix: preserve task items and spec example order in structure view

Fix: use EditorScrollingPositionKeeper to restore caret vertical position after doc format.

Fix: replace formatter with flexmark-java format module

Fix: replace wrap on typing with flexmark-java document format for paragraph

Fix: replace use of BasedSequence by BasedSequence and accumulate lines in
                    LineAppendable

Fix: * [ ] d| backspace of last char after indented task item, caret jumps to start of
                    line.

Fix: move remote content fetch to background tasks.

Fix: NPE on virtualFile being null for formatting documents in code style settings.

Fix: MdRemoteContentCache, wrong setting used for remote content cache limit causing content
                    fetch task limit to be exceeded. This also addresses diagnostic/4425.

Fix: show editor tooltip when format document or element results in no changes.

Fix: getEditorTextWithCaretMarkup is broken for selection with caret pos.

Fix: formatting of flexmark spec files

Fix: example with ast not adding EOL before example break

Fix: example number not incremented

Fix: set min keep blank lines to 2 for spec test files

Fix: replace Psi based formatter with flexmark formatter.

Fix: caret tracking for multi-caret mode doc format

        ]]></change-notes>

    <extensionPoints>
        <extensionPoint interface="com.vladsch.md.nav.editor.util.HtmlPanelProvider" name="html.panel.provider"/>
        <extensionPoint interface="com.vladsch.md.nav.editor.util.HtmlGeneratorProvider" name="html.generator.provider"/>
        <extensionPoint interface="com.vladsch.md.nav.editor.util.HtmlScriptResourceProvider" name="html.script.provider"/>
        <extensionPoint interface="com.vladsch.md.nav.editor.util.HtmlCssResourceProvider" name="html.css.provider"/>
        <extensionPoint interface="com.vladsch.md.nav.actions.api.MdCaretContextInfoHandler" name="caretContextInfoHandler"/>
        <extensionPoint interface="com.vladsch.md.nav.editor.api.MdEditorCustomizationProvider" name="editorCustomizationProvider"/>
        <extensionPoint interface="com.vladsch.md.nav.editor.api.MdHtmlGeneratorExtension" name="htmlGeneratorExtension"/>
        <extensionPoint interface="com.vladsch.md.nav.language.completion.MdElementCompletion" name="element.completionProvider"/>
        <extensionPoint interface="com.vladsch.md.nav.settings.api.MdSettingsExtensionProvider" name="settingsExtension"/>
        <extensionPoint interface="com.vladsch.md.nav.settings.api.MdProjectSettingsExtensionProvider" name="projectSettingsExtension"/>
        <extensionPoint interface="com.vladsch.md.nav.settings.api.MdProjectSettingsExtensionHandler" name="projectSettingsHandler"/>
        <extensionPoint interface="com.vladsch.md.nav.settings.api.MdApplicationSettingsExtensionProvider" name="applicationSettingsExtension"/>
        <extensionPoint interface="com.vladsch.md.nav.settings.api.MdApplicationRestartRequiredProvider" name="applicationRestartRequired"/>
        <extensionPoint interface="com.vladsch.md.nav.settings.api.MdSettingsFormExtensionProvider" name="settingsConfigurableExtension"/>
        <extensionPoint interface="com.vladsch.md.nav.settings.api.MdExtensionInfoProvider" name="extensionInfoProvider"/>
        <extensionPoint interface="com.vladsch.md.nav.settings.api.MdRenderingProfileManagerFactory" name="renderingProfileManagerFactory"/>
        <extensionPoint interface="com.vladsch.md.nav.language.api.MdCodeStyleConfigurableProvider" name="codeStyleConfigurableProvider"/>
        <extensionPoint interface="com.vladsch.md.nav.language.api.MdLanguageProvider" name="languageProvider"/>
        <extensionPoint interface="com.vladsch.md.nav.highlighter.api.MdColorSettingsExtension" name="colorSettingsExtension"/>
        <extensionPoint interface="com.vladsch.md.nav.language.api.MdFoldingBuilderProvider" name="foldingBuilderProvider"/>
        <extensionPoint interface="com.vladsch.md.nav.spellchecking.api.MdSpellcheckingIdentifierTokenizer" name="spellcheckingIdentifierTokenizer"/>
        <extensionPoint interface="com.vladsch.md.nav.psi.api.MdBlockPrefixProvider" name="blockPrefixProvider"/>
        <extensionPoint interface="com.vladsch.md.nav.psi.api.MdTypeFactory" name="elementTypeFactory"/>
        <extensionPoint interface="com.vladsch.md.nav.psi.api.MdElementTextProvider" name="elementTextProvider"/>
        <extensionPoint interface="com.vladsch.md.nav.parser.api.MdParserExtension" name="parserExtension"/>
        <extensionPoint interface="com.vladsch.md.nav.parser.cache.data.dependency.DataDependencyProvider" name="dataDependencyProvider"/>
        <extensionPoint interface="com.vladsch.md.nav.language.api.MdStripTrailingSpacesExtension" name="stripTrailingSpacesExtension"/>
        <extensionPoint interface="com.vladsch.md.nav.language.api.MdLineMarkerExtension" name="lineMarkerExtension"/>
        <extensionPoint interface="com.vladsch.md.nav.vcs.api.MdOnProjectSettingsChangedActivityProvider" name="projectSettingsChangedActivity"/>
        <extensionPoint interface="com.vladsch.md.nav.actions.api.MdElementContextInfoProvider" name="elementContextInfoProvider"/>
        <extensionPoint interface="com.vladsch.md.nav.actions.api.MdFormatElementHandler" name="formatElementHandler"/>
        <extensionPoint interface="com.vladsch.md.nav.language.api.MdLinkRefCompletionExtension" name="linkRefCompletionExtension"/>
        <extensionPoint interface="com.vladsch.md.nav.editor.api.MdPreviewCustomizationProvider" name="previewCustomizationProvider"/>
        <extensionPoint interface="com.vladsch.md.nav.psi.api.MdTextMapElementTypeProvider" name="textMapElementTypeProvider"/>
        <extensionPoint interface="com.vladsch.md.nav.parser.api.MdLinkMapProvider" name="linkMapProvider"/>
        <extensionPoint interface="com.vladsch.md.nav.settings.api.MdRenderingProfileSynchronizerExtension" name="renderingProfileSynchronizerExtension"/>
        <extensionPoint interface="com.vladsch.md.nav.editor.api.MdFormatCustomizationProvider" name="formatCustomizationProvider"/>
        <extensionPoint interface="com.vladsch.md.nav.parser.api.MdFencedCodeImageConverter" name="codeFenceImageConverter"/>
        <extensionPoint interface="com.vladsch.md.nav.settings.api.MdRenderingProfileValidator" name="renderingProfileValidator"/>
    </extensionPoints>

    <extensions defaultExtensionNs="com.intellij">
        <applicationService serviceImplementation="com.vladsch.md.nav.MdImageCache"/>
        <applicationService serviceImplementation="com.vladsch.md.nav.MdResourceResolverImpl"/>
        <applicationService serviceImplementation="com.vladsch.md.nav.parser.cache.CachedData"/>
        <applicationService serviceImplementation="com.vladsch.md.nav.settings.MdApplicationLocalSettings"/>
        <applicationService serviceImplementation="com.vladsch.md.nav.settings.MdApplicationSettings"/>
        <applicationService serviceImplementation="com.vladsch.md.nav.settings.MdApplicationSharedSettings"/>
        <applicationService serviceImplementation="com.vladsch.md.nav.util.MdCancelableJobScheduler"/>
        <applicationService serviceImplementation="com.vladsch.md.nav.highlighter.MdHighlighterColors"/>
        <applicationService serviceImplementation="com.vladsch.md.nav.parser.LexParserState"/>

        <projectService serviceImplementation="com.vladsch.md.nav.parser.cache.data.ProjectCachedData"/>
        <projectService serviceImplementation="com.vladsch.md.nav.parser.cache.ProjectFileMonitor"/>
        <projectService serviceImplementation="com.vladsch.md.nav.settings.MdProjectSettingsManager"/>
        <projectService serviceImplementation="com.vladsch.md.nav.settings.MdRenderingProfileManager"/>
        <projectService serviceImplementation="com.vladsch.md.nav.settings.RenderingProfileSynchronizer"/>
        <projectService serviceImplementation="com.vladsch.md.nav.parser.flexmark.MdFencedCodeImageConversionManager"/>

        <projectService serviceImplementation="com.vladsch.md.nav.vcs.MdLinkResolverManager"/>

        <schemeExporter
              name="Intellij IDEA color scheme, reduced markdown (.icls)"
              schemeClass="com.intellij.openapi.editor.colors.EditorColorsScheme"
              implementationClass="com.vladsch.md.nav.highlighter.MdColorSchemeExporter"
              order="first"/>

        <lang.elementManipulator forClass="com.vladsch.md.nav.psi.element.MdAttributeIdValue" implementationClass="com.vladsch.md.nav.psi.manipulator.MdAttributeIdValueManipulator"/>
        <lang.elementManipulator forClass="com.vladsch.md.nav.psi.element.MdEnumeratedReferenceId" implementationClass="com.vladsch.md.nav.psi.manipulator.MdEnumeratedReferenceTypeManipulator"/>
        <lang.elementManipulator forClass="com.vladsch.md.nav.psi.element.MdImageMultiLineUrlContentImpl" implementationClass="com.vladsch.md.nav.psi.manipulator.MdImageMultiLineUrlContentManipulator"/>
        <lang.elementManipulator forClass="com.vladsch.md.nav.psi.element.MdHtmlBlock" implementationClass="com.vladsch.md.nav.psi.manipulator.MdHtmlBlockManipulator"/>
        <lang.elementManipulator forClass="com.vladsch.md.nav.psi.element.MdVerbatim" implementationClass="com.vladsch.md.nav.psi.manipulator.MdVerbatimManipulator"/>
        <lang.elementManipulator forClass="com.vladsch.md.nav.psi.element.MdJekyllFrontMatterBlock" implementationClass="com.vladsch.md.nav.psi.manipulator.MdJekyllFrontMatterBlockManipulator"/>
        <lang.elementManipulator forClass="com.vladsch.md.nav.psi.element.MdInlineGitLabMath" implementationClass="com.vladsch.md.nav.psi.manipulator.MdInlineGitLabMathManipulator"/>
        <lang.elementManipulator forClass="com.vladsch.md.nav.psi.element.MdInlineCode" implementationClass="com.vladsch.md.nav.psi.manipulator.MdInlineCodeManipulator"/>
        <lang.elementManipulator forClass="com.vladsch.md.nav.psi.element.MdReference" implementationClass="com.vladsch.md.nav.psi.manipulator.MdReferenceManipulator"/>
        <lang.elementManipulator forClass="com.vladsch.md.nav.psi.element.MdFootnote" implementationClass="com.vladsch.md.nav.psi.manipulator.MdReferenceManipulator"/>
        <lang.elementManipulator forClass="com.vladsch.md.nav.psi.element.MdMacro" implementationClass="com.vladsch.md.nav.psi.manipulator.MdReferenceManipulator"/>
        <lang.elementManipulator forClass="com.vladsch.md.nav.psi.element.MdReferencingElementReference" implementationClass="com.vladsch.md.nav.psi.manipulator.MdReferencingElementManipulator"/>
        <lang.elementManipulator forClass="com.vladsch.md.nav.psi.text.MdPlainTextElementImpl" implementationClass="com.vladsch.md.nav.psi.text.MdPlainTextElementManipulator"/>
        <lang.elementManipulator forClass="com.vladsch.md.nav.psi.element.MdRenameElement" implementationClass="com.vladsch.md.nav.psi.manipulator.MdRenameElementManipulator"/>

        <stubIndex implementation="com.vladsch.md.nav.psi.index.MdLinkElementIndex"/>
        <stubIndex implementation="com.vladsch.md.nav.psi.index.MdPlainTextElementIndex"/>
        <stubIndex implementation="com.vladsch.md.nav.psi.index.MdReferenceableTextIndex"/>

        <vetoRenameCondition implementation="com.vladsch.md.nav.psi.manipulator.MdNamedElementVetoRename"/>
        <vetoRenameCondition implementation="com.vladsch.md.nav.psi.manipulator.MdRenameElementVetoRename"/>

        <stripTrailingSpacesFilterFactory implementation="com.vladsch.md.nav.language.MdStripTrailingSpacesFilterFactory"/>
        <multiHostInjector implementation="com.vladsch.md.nav.language.injection.MdLanguageInjector"/>

        <webHelpProvider implementation="com.vladsch.md.nav.settings.MdWebHelpTopicProvider"/>

        <fileEditorProvider implementation="com.vladsch.md.nav.editor.MdSplitEditorProvider"/>

        <editorNotificationProvider implementation="com.vladsch.md.nav.inspections.JekyllFrontMatterFoundNotificationProvider"/>
        <editorNotificationProvider implementation="com.vladsch.md.nav.inspections.LineSeparatorFoundNotificationProvider"/>
        <editorNotificationProvider implementation="com.vladsch.md.nav.inspections.AutoLinksEnabledInLargeFileNotificationProvider"/>
        <editorNotificationProvider implementation="com.vladsch.md.nav.inspections.PlantUmlParserExtensionNotificationProvider"/>

        <editorHighlighterProvider filetype="Markdown" implementationClass="com.vladsch.md.nav.highlighter.MdEditorHighlighterProvider"/>

        <liveTemplateContext implementation="com.vladsch.md.nav.language.template.MarkdownTemplateContextType$Generic"/>

        <lang.foldingBuilder language="Markdown" implementationClass="com.vladsch.md.nav.language.folding.MdFoldingBuilder"/>
        <codeFoldingOptionsProvider instance="com.vladsch.md.nav.language.folding.MdCodeFoldingOptionsProvider"/>
        <applicationService serviceImplementation="com.vladsch.md.nav.language.folding.MdFoldingSettings"/>

        <langCodeStyleSettingsProvider implementation="com.vladsch.md.nav.language.MdLanguageCodeStyleSettingsProvider"/>
        <codeStyleSettingsProvider implementation="com.vladsch.md.nav.language.MdNavigatorCodeStyleSettingsProvider"/>
        <lookup.charFilter implementation="com.vladsch.md.nav.language.completion.util.MdCompletionCharFilter" order="first" id="md_navigator_no_char_completion"/>

        <typedHandler implementation="com.vladsch.md.nav.actions.handlers.TypedCharHandler" order="first"/>
        <backspaceHandlerDelegate implementation="com.vladsch.md.nav.actions.handlers.BackspaceHandler" order="first"/>
        <joinLinesHandler implementation="com.vladsch.md.nav.actions.handlers.JoinLinesHandler" order="first"/>

        <externalAnnotator language="Markdown" implementationClass="com.vladsch.md.nav.annotator.MdExternalAnnotator"/>
        <braceMatcher filetype="Markdown" implementationClass="com.vladsch.md.nav.language.MdBraceMatcher"/>
        <todoIndexer filetype="Markdown" implementationClass="com.vladsch.md.nav.todo.MdTodoIndexer"/>

        <colorSettingsPage implementation="com.vladsch.md.nav.highlighter.MdColorSettingsPage"/>
        <completion.contributor language="Markdown" implementationClass="com.vladsch.md.nav.language.completion.MdCompletionContributor"/>
        <lang.commenter language="Markdown" implementationClass="com.vladsch.md.nav.language.MdCommenter"/>
        <lang.findUsagesProvider language="Markdown" implementationClass="com.vladsch.md.nav.language.MdFindUsagesProvider"/>
        <lang.namesValidator language="Markdown" implementationClass="com.vladsch.md.nav.language.MdNamesValidator"/>
        <lang.parserDefinition language="Markdown" implementationClass="com.vladsch.md.nav.parser.MdParserDefinition"/>
        <lang.refactoringSupport language="Markdown" implementationClass="com.vladsch.md.nav.language.MdRefactoringSupportProvider"/>
        <lang.syntaxHighlighterFactory key="Markdown" language="Markdown" implementationClass="com.vladsch.md.nav.highlighter.MdSyntaxHighlighterFactory"/>
        <spellchecker.support language="Markdown" implementationClass="com.vladsch.md.nav.spellchecking.MdSpellcheckingStrategy"/>
        <fileIconProvider implementation="com.vladsch.md.nav.MdFileIconProvider"/>

        <codeInsight.lineMarkerProvider language="Markdown" implementationClass="com.vladsch.md.nav.language.MdLineMarkerProvider"/>
        <lang.psiStructureViewFactory language="Markdown" id="MdStructureViewFactory" implementationClass="com.vladsch.md.nav.language.structure.MdStructureViewFactory"/>
        <iconLayerProvider implementation="com.vladsch.md.nav.MdWikiDirectoryOverlayProvider" order="last"/>
        <problemFileHighlightFilter implementation="com.vladsch.md.nav.language.MdProblemFileHighlightFilter"/>

        <treeStructureProvider implementation="com.vladsch.md.nav.language.projectView.MdTreeStructureProvider"/>

        <qualifiedNameProvider implementation="com.vladsch.md.nav.language.MdQualifiedNameProvider"/>

        <additionalTextAttributes scheme="Darcula" file="com/vladsch/md/nav/colorSchemes/MarkdownDarcula.xml"/>
        <additionalTextAttributes scheme="Default" file="com/vladsch/md/nav/colorSchemes/MarkdownDefault.xml"/>

        <defaultLiveTemplates file="liveTemplates/Markdown.xml"/>
        <defaultLiveTemplates file="liveTemplates/surround.xml"/>
        <fileType name="Markdown" extensions="md;markdown;mkd" language="Markdown" implementationClass="com.vladsch.md.nav.MdFileType" fieldName="INSTANCE"/>
    </extensions>

    <application-components>
        <component>
            <implementation-class>com.vladsch.md.nav.MdPlugin</implementation-class>
        </component>
        <component>
            <implementation-class>com.vladsch.md.nav.settings.MdApplicationRestartManager</implementation-class>
        </component>
    </application-components>

    <project-components>
        <component>
            <implementation-class>com.vladsch.md.nav.MdProjectComponent</implementation-class>
        </component>
    </project-components>

    <extensions defaultExtensionNs="com.vladsch.idea.multimarkdown">

        <parserExtension id="MdEmojiParserExtension" implementation="com.vladsch.md.nav.parser.parserExtensions.MdEmojiParserExtension"/>
        <parserExtension id="MdJekyllExtension" implementation="com.vladsch.md.nav.parser.parserExtensions.MdJekyllExtension"/>
        <parserExtension id="MdWikiLinkParserExtension" implementation="com.vladsch.md.nav.parser.parserExtensions.MdWikiLinkParserExtension"/>
        <textMapElementTypeProvider implementation="com.vladsch.md.nav.psi.util.BasicTextMapElementTypeProvider"/>
        <renderingProfileValidator implementation="com.vladsch.md.nav.parser.flexmark.MdPlantUmlConversionSettingsMigration"/>
        <renderingProfileValidator implementation="com.vladsch.md.nav.parser.flexmark.MdFencedCodeImageProfileValidator" order="last"/>
        <codeFenceImageConverter implementation="com.vladsch.md.nav.parser.flexmark.MdFencedCodePlantUmlConverter"/>
        <editorCustomizationProvider implementation="com.vladsch.md.nav.editor.MdEditorCustomizationProvider"/>
        <renderingProfileValidator implementation="com.vladsch.md.nav.parser.MdAnchorLinksSettingsMigration"/>

        <applicationRestartRequired implementation="com.vladsch.md.nav.settings.MdHighlighterChangedRestartProvider"/>
        <editorCustomizationProvider implementation="com.vladsch.md.nav.actions.handlers.util.SmartInsertEditorRangeHighlighterProvider"/>

        <element.completionProvider implementation="com.vladsch.md.nav.language.completion.CodeFenceLanguageCompletion"/>
        <element.completionProvider implementation="com.vladsch.md.nav.language.completion.EmojiShortcutCompletion"/>
        <element.completionProvider implementation="com.vladsch.md.nav.language.completion.LinkRefCompletion"/>
        <element.completionProvider implementation="com.vladsch.md.nav.language.completion.ReferenceLinkCompletion"/>
    </extensions>

    <extensions defaultExtensionNs="com.intellij">
        <applicationService serviceImplementation="com.vladsch.md.nav.flex.FlexmarkModuleLocalSettings"/>
        <projectService serviceImplementation="com.vladsch.md.nav.flex.settings.FlexmarkProjectSettingsManager"/>

        <lang.elementManipulator forClass="com.vladsch.md.nav.flex.psi.FlexmarkFrontMatterBlock" implementationClass="com.vladsch.md.nav.flex.psi.FlexmarkFrontMatterBlockManipulator"/>
        <lang.elementManipulator forClass="com.vladsch.md.nav.flex.psi.FlexmarkExampleOption" implementationClass="com.vladsch.md.nav.flex.language.FlexmarkExampleOptionManipulator"/>
        <stubIndex implementation="com.vladsch.md.nav.flex.psi.index.FlexmarkExampleOptionIndex"/>
        <fileBasedIndex implementation="com.vladsch.md.nav.flex.psi.index.FlexmarkFileIndex"/>
        <applicationService serviceImplementation="com.vladsch.md.nav.flex.language.folding.MdFlexmarkFoldingSettings"/>
    </extensions>

    <extensions defaultExtensionNs="com.vladsch.idea.multimarkdown">
        <settingsExtension implementation="com.vladsch.md.nav.flex.settings.FlexmarkHtmlSettingsExtensionProvider"/>
        <settingsExtension implementation="com.vladsch.md.nav.flex.settings.FlexmarkDebugSettingsExtensionProvider"/>

        <settingsConfigurableExtension implementation="com.vladsch.md.nav.flex.settings.FlexmarkHtmlSettingsFormProvider"/>
        <settingsConfigurableExtension implementation="com.vladsch.md.nav.flex.settings.FlexmarkParserSettingsFormProvider"/>
        <settingsConfigurableExtension implementation="com.vladsch.md.nav.flex.settings.FlexmarkDebugSettingsFormProvider"/>

        <colorSettingsExtension implementation="com.vladsch.md.nav.flex.highlighter.FlexmarkColorSettingsExtension"/>

        <parserExtension id="MdSpecExampleParserExtension" implementation="com.vladsch.md.nav.flex.parser.MdSpecExampleParserExtension" order="after MdJekyllExtension"/>
        <textMapElementTypeProvider implementation="com.vladsch.md.nav.flex.psi.util.FlexTextMapElementTypeProvider"/>

        <lineMarkerExtension implementation="com.vladsch.md.nav.flex.language.MdFlexmarkLineMarkerExtension"/>

        <foldingBuilderProvider id="MdEnhFoldingBuilderProvider" implementation="com.vladsch.md.nav.flex.language.folding.MdFlexmarkFoldingBuilderProvider"/>

        <stripTrailingSpacesExtension implementation="com.vladsch.md.nav.flex.parser.MdSpecExampleStripTrailingSpacesExtension"/>

        <editorCustomizationProvider implementation="com.vladsch.md.nav.flex.editor.FlexmarkEditorRangeHighlighterProvider"/>

        <element.completionProvider implementation="com.vladsch.md.nav.flex.language.FlexmarkOptionsKeywordCompletion"/>
    </extensions>

    <actions>
        <action class="com.vladsch.md.nav.actions.styling.ToggleWrapOnTypingAction"
                id="MarkdownNavigator.ToggleWrapOnTyping"
                text="Wrap on Typing"
                description="Toggles wrap on typing mode"
                icon="MdIcons.EditorActions.Wrap_on_typing">
        </action>

        <action class="com.vladsch.md.nav.actions.styling.ToggleBoldAction"
                id="MarkdownNavigator.ToggleBold"
                text="Toggle Bold Mode"
                description="Toggles bold mode on caret/selection"
                icon="MdIcons.EditorActions.Bold">
            <keyboard-shortcut first-keystroke="meta b" keymap="$default"/>
        </action>

        <action class="com.vladsch.md.nav.actions.styling.ToggleItalicAction"
                id="MarkdownNavigator.ToggleItalic"
                text="Toggle Italic Mode"
                description="Toggles italic mode on caret/selection"
                icon="MdIcons.EditorActions.Italic">
            <keyboard-shortcut first-keystroke="meta i" keymap="$default"/>
        </action>

        <action class="com.vladsch.md.nav.actions.styling.ToggleStrikeThroughAction"
                id="MarkdownNavigator.ToggleStrikeThrough"
                text="Toggle Strike Through Mode"
                description="Toggles strike through mode on caret/selection"
                icon="MdIcons.EditorActions.Strike_through">
        </action>

        <action class="com.vladsch.md.nav.actions.styling.ToggleUnderlineAction"
                id="MarkdownNavigator.ToggleUnderline"
                text="Toggle Underline Mode"
                description="Toggles underline mode on caret/selection"
                icon="MdIcons.EditorActions.Underline">
        </action>

        <action class="com.vladsch.md.nav.actions.styling.ToggleSuperscriptAction"
                id="MarkdownNavigator.ToggleSuperscript"
                text="Toggle Superscript Mode"
                description="Toggles superscript mode on caret/selection"
                icon="MdIcons.EditorActions.Superscript">
        </action>

        <action class="com.vladsch.md.nav.actions.styling.ToggleSubscriptAction"
                id="MarkdownNavigator.ToggleSubscript"
                text="Toggle Subscript Mode"
                description="Toggles subscript mode on caret/selection"
                icon="MdIcons.EditorActions.Subscript">
        </action>

        <action class="com.vladsch.md.nav.actions.styling.ToggleCodeSpanAction"
                id="MarkdownNavigator.ToggleCodeSpan"
                text="Toggle Monospaced (Code Span) Mode"
                description="Toggles monospaced mode (rendered as code span) on caret/selection"
                icon="MdIcons.EditorActions.Code_span">
            <keyboard-shortcut first-keystroke="meta o" keymap="$default"/>
        </action>

        <action class="com.vladsch.md.nav.actions.styling.InsertLinkAction"
                id="MarkdownNavigator.InsertLink"
                text="Insert Link"
                description="Insert link on caret/selection"
                icon="MdIcons.EditorActions.Link">
            <keyboard-shortcut first-keystroke="meta l" keymap="$default"/>
        </action>

        <action class="com.vladsch.md.nav.actions.styling.BlockQuoteRemoveAction"
                id="MarkdownNavigator.BlockQuoteRemove"
                text="Decrease Quote Level"
                description="Decrease quote level for item or selection"
                icon="MdIcons.EditorActions.Quote_remove">
        </action>

        <action class="com.vladsch.md.nav.actions.styling.BlockQuoteAddAction"
                id="MarkdownNavigator.BlockQuoteAdd"
                text="Increase Quote Level"
                description="Increase quote level for item or selection"
                icon="MdIcons.EditorActions.Quote_add">
        </action>

        <action class="com.vladsch.md.nav.actions.styling.HeaderLevelUpAction"
                id="MarkdownNavigator.HeaderLevelUp"
                text="Heading Level up"
                description="Increases the heading level on caret/selection"
                icon="MdIcons.EditorActions.Header_level_up">
        </action>

        <action class="com.vladsch.md.nav.actions.styling.HeaderLevelDownAction"
                id="MarkdownNavigator.HeaderLevelDown"
                text="Heading Level down"
                description="Increases the heading level on caret/selection"
                icon="MdIcons.EditorActions.Header_level_down">
        </action>

        <action class="com.vladsch.md.nav.actions.styling.HeaderToggleTypeAction"
                id="MarkdownNavigator.HeaderToggleType"
                text="Toggle Heading Type"
                description="Toggle heading type between setext and atx"
                icon="MdIcons.EditorActions.Header_toggle_type">
        </action>

        <action class="com.vladsch.md.nav.actions.styling.ListUnIndentAction"
                id="MarkdownNavigator.ListUnIndent"
                text="Decrease List Level"
                description="Decrease list item's level"
                icon="MdIcons.EditorActions.List_unindent">
            <keyboard-shortcut first-keystroke="meta y" keymap="$default"/>
        </action>

        <action class="com.vladsch.md.nav.actions.styling.ListIndentAction"
                id="MarkdownNavigator.ListIndent"
                text="Increase List Level"
                description="Increase a list item's level"
                icon="MdIcons.EditorActions.List_indent">
            <keyboard-shortcut first-keystroke="meta u" keymap="$default"/>
        </action>

        <action class="com.vladsch.md.nav.actions.styling.ListTightAction"
                id="MarkdownNavigator.ListTight"
                text="Single Space List"
                description="Single space list items"
                icon="MdIcons.EditorActions.List_tight">
        </action>

        <action class="com.vladsch.md.nav.actions.styling.ListLooseAction"
                id="MarkdownNavigator.ListLoose"
                text="Double Space List"
                description="Double space list items"
                icon="MdIcons.EditorActions.List_loose">
        </action>

        <action class="com.vladsch.md.nav.actions.styling.ListBulletItemsAction"
                id="MarkdownNavigator.ListBulletItems"
                text="Toggle Bullet List Item"
                description="Make into bullet list"
                icon="MdIcons.EditorActions.List_bullet_items">
        </action>

        <action class="com.vladsch.md.nav.actions.styling.ListOrderedItemsAction"
                id="MarkdownNavigator.ListOrderedItems"
                text="Toggle Ordered List Item"
                description="Make into an ordered list"
                icon="MdIcons.EditorActions.List_ordered_items">
        </action>

        <action class="com.vladsch.md.nav.actions.styling.ListTaskItemsAction"
                id="MarkdownNavigator.ListTaskItems"
                text="Toggle Task List Item"
                description="Make into a task list"
                icon="MdIcons.EditorActions.List_task_items">
        </action>

        <action class="com.vladsch.md.nav.actions.styling.ListToggleTaskItemDoneAction"
                id="MarkdownNavigator.ListToggleTaskItemDone"
                text="Toggle Task Item Done"
                description="Toggle task list item's done status"
                icon="MdIcons.EditorActions.List_toggle_item_done">
        </action>

        <action class="com.vladsch.md.nav.actions.styling.InsertTableAction"
                id="MarkdownNavigator.InsertTable"
                text="Insert Table"
                description="Insert table on caret/selection"
                icon="MdIcons.EditorActions.Insert_table">
        </action>

        <action class="com.vladsch.md.nav.actions.styling.ReformatElementAction"
                id="MarkdownNavigator.ReformatElement"
                text="Format Element"
                description="Format current paragraph, table or table of contents"
                icon="MdIcons.EditorActions.Reformat_element">
        </action>

        <action class="com.vladsch.md.nav.actions.styling.ShowTextHexAction"
                id="MarkdownNavigator.ShowTextHex"
                text="Show Hex for Selection"
                description="Show hex character view of selected text"
                icon="MdIcons.EditorActions.Show_text_hex">
        </action>

        <action class="com.vladsch.md.nav.actions.styling.SizePreferencesDialogAction"
                id="MarkdownNavigator.SizePreferencesDialog"
                text="Size Preferences Dialog"
                description="Sets preferences dialog to the configured size."
                icon="MdIcons.EditorActions.Preferences_size">
        </action>

        <action class="com.vladsch.md.nav.actions.styling.DebugTextBoundsToggleStateAction"
                id="MarkdownNavigator.DebugTextBoundsToggleState"
                text="Show Text Bounds"
                description="Shows the text bounds for formatting at caret position."
                icon="MdIcons.EditorActions.Debug_text_bounds">

        </action>

        <action class="com.vladsch.md.nav.actions.styling.TranslateDocumentAction"
                id="MarkdownNavigator.TranslateDocument"
                text="Translate Document"
                description="Translate document powered by yandex.translate"
                icon="MdIcons.EditorActions.Yandex_document">
        </action>

        <action class="com.vladsch.md.nav.actions.editorLayout.CyclicSplitLayoutChangeAction"
                id="MarkdownNavigator.CyclicSplitLayoutChange"
                text="Cycle Split Layout"
                description="Toggle markdown editor layout through different values (editor only, preview only, wysiwyg split)"
                icon="MdIcons.Layout.Cycle_editor_preview">
        </action>

        <action class="com.vladsch.md.nav.actions.editorLayout.ToggleEditorLayoutChangeAction"
                text="Toggle Editor Layout"
                id="MarkdownNavigator.ToggleSplitLayoutChange"
                description="Toggle between editor only and editor with preview"
                icon="MdIcons.Layout.Toggle_editor_preview">
            <keyboard-shortcut keymap="$default" first-keystroke="ctrl p"/>
        </action>

        <action class="com.vladsch.md.nav.actions.editorLayout.EditorOnlyLayoutChangeAction"
                id="MarkdownNavigator.EditorOnlyLayoutChange"
                text="Show Editor Only"
                description="Sets markdown editor layout to show editor only"
                icon="MdIcons.Layout.Editor_only">
        </action>

        <action class="com.vladsch.md.nav.actions.editorLayout.PreviewOnlyLayoutChangeAction"
                id="MarkdownNavigator.PreviewOnlyLayoutChange"
                text="Show Preview Only"
                description="Sets markdown editor layout to show preview only"
                icon="MdIcons.Layout.Preview_only">
        </action>

        <action class="com.vladsch.md.nav.actions.editorLayout.EditorAndPreviewLayoutChangeAction"
                id="MarkdownNavigator.EditorAndPreviewLayoutChange"
                text="Show Editor and Preview"
                description="Sets markdown editor layout to show editor and preview in split"
                icon="MdIcons.Layout.Editor_preview">
        </action>

        <action class="com.vladsch.md.nav.actions.editorLayout.ToggleEditorSplitLayoutAction"
                id="MarkdownNavigator.ToggleEditorSplitLayout"
                text="Toggle Editor Split Orientation"
                description="Toggle editor split orientation"
                icon="MdIcons.Layout.Split_preview_horizontal">
        </action>

        <action class="com.vladsch.md.nav.actions.editorLayout.HtmlPreviewChangeAction"
                id="MarkdownNavigator.HtmlPreviewChange"
                text="Show HTML Preview"
                description="Sets preview pane to show rendered HTML"
                icon="MdIcons.Layout.Html_preview">
        </action>

        <action class="com.vladsch.md.nav.actions.editorLayout.ModifiedHtmlTextChangeAction"
                id="MarkdownNavigator.ModifiedHtmlTextChange"
                text="Show HTML Text Used for Browser"
                description="Sets preview pane to show HTML text as used in browser rendered preview"
                icon="MdIcons.Layout.Html_modified">
        </action>

        <action class="com.vladsch.md.nav.actions.editorLayout.UnmodifiedHtmlTextChangeAction"
                id="MarkdownNavigator.UnmodifiedHtmlTextChange"
                text="Show Plain HTML as Generated by Parser"
                description="Sets preview pane to show plain HTML text as generated by parser"
                icon="MdIcons.Layout.Html_unmodified">
        </action>

        <action class="com.vladsch.md.nav.actions.editorLayout.CyclicPreviewChangeAction"
                id="MarkdownNavigator.CyclicPreviewChange"
                text="Cycle Preview Content"
                description="Cycle markdown editor preview through different HTML previews (rendered, browser, plain)"
                icon="MdIcons.Layout.Cycle_html">
        </action>

        <action id="MarkdownNavigator.CopyUpsourceSelectionReference"
                class="com.vladsch.md.nav.actions.ide.CopyUpsourceSelectionReference"
                text="Copy Reference With Selection Line Numbers"
                icon="MdIcons.LinkTypes.Upsource">
            <add-to-group group-id="CutCopyPasteGroup" anchor="after" relative-to-action="CopyReference"/>
            <add-to-group group-id="EditorTabPopupMenu" anchor="after" relative-to-action="CopyReference"/>
            <add-to-group group-id="EditorPopupMenu" anchor="after" relative-to-action="CopyReference"/>
        </action>

        <action id="MarkdownNavigator.CopySelectionReference" class="com.vladsch.md.nav.actions.ide.CopySelectionReference" text="Copy Reference With Selection Line Numbers">
            <add-to-group group-id="CutCopyPasteGroup" anchor="after" relative-to-action="CopyReference"/>
            <add-to-group group-id="EditorTabPopupMenu" anchor="after" relative-to-action="CopyReference"/>
            <add-to-group group-id="EditorPopupMenu" anchor="after" relative-to-action="CopyReference"/>
        </action>
    </actions>

    <actions>
        <group id="MarkdownNavigator.Toolbar.Left" text="Markdown Navigator Editor Actions">
            <reference id="MarkdownNavigator.ToggleWrapOnTyping"/>
            <reference id="MarkdownNavigator.ToggleBold"/>
            <reference id="MarkdownNavigator.ToggleItalic"/>
            <reference id="MarkdownNavigator.ToggleStrikeThrough"/>
            <reference id="MarkdownNavigator.ToggleUnderline"/>
            <reference id="MarkdownNavigator.ToggleSuperscript"/>
            <reference id="MarkdownNavigator.ToggleSubscript"/>

            <separator/>

            <reference id="MarkdownNavigator.ToggleCodeSpan"/>
            <reference id="MarkdownNavigator.InsertLink"/>
            <reference id="MarkdownNavigator.BlockQuoteRemove"/>
            <reference id="MarkdownNavigator.BlockQuoteAdd"/>

            <separator/>

            <reference id="MarkdownNavigator.HeaderLevelUp"/>
            <reference id="MarkdownNavigator.HeaderLevelDown"/>
            <reference id="MarkdownNavigator.HeaderToggleType"/>

            <separator/>

            <reference id="MarkdownNavigator.ListUnIndent"/>
            <reference id="MarkdownNavigator.ListIndent"/>

            <group id="MarkdownNavigator.MarkdownListMenu"
                   text="Markdown List Actions"
                   popup="true"
                   icon="MdIcons.EditorActions.Menu_list">

                <reference id="MarkdownNavigator.ListTight"/>
                <reference id="MarkdownNavigator.ListLoose"/>
                <reference id="MarkdownNavigator.ListBulletItems"/>
                <reference id="MarkdownNavigator.ListOrderedItems"/>
                <reference id="MarkdownNavigator.ListTaskItems"/>
                <reference id="MarkdownNavigator.ListToggleTaskItemDone"/>
            </group>

            <separator/>

            <reference id="MarkdownNavigator.ReformatElement"/>

            <separator/>

            <group id="MarkdownNavigator.MarkdownMiscellaneousMenu"
                   text="Markdown Miscellaneous Actions"
                   popup="true"
                   icon="MdIcons.EditorActions.Menu_misc">

                <reference id="MarkdownNavigator.ShowTextHex"/>
                <reference id="MarkdownNavigator.SizePreferencesDialog"/>
                <reference id="MarkdownNavigator.DebugTextBoundsToggleState"/>
            </group>

            <group id="MarkdownNavigator.MarkdownCopyMenu"
                   text="Markdown Copy Actions"
                   popup="true"
                   icon="MdIcons.EditorActions.Menu_copy">

                <reference id="MarkdownNavigator.TranslateDocument"/>
            </group>

        </group>

        <group id="MarkdownNavigator.ToolsMenu" text="Markdown Navigator" popup="true" icon="MdIcons.Document.MARKDOWN_NAVIGATOR_LOGO">
            <add-to-group group-id="ToolsMenu" anchor="after" relative-to-action="ExternalToolsGroup"/>
            <group id="MarkdownNavigator.ExportMarkdownMenu" text="Export Markdown" popup="true">
                <reference id="MarkdownNavigator.TranslateDocument"/>
            </group>
        </group>

        <group id="MarkdownNavigator.FormatMarkdownMenu" text="Format Markdown" popup="true">
            <add-to-group group-id="MarkdownNavigator.ToolsMenu" anchor="after" relative-to-action="MarkdownNavigator.CopyMarkdownMenu"/>
            <reference id="MarkdownNavigator.ReformatElement"/>
        </group>

        <reference id="MarkdownNavigator.CyclicSplitLayoutChange"/>
        <reference id="MarkdownNavigator.ToggleSplitLayoutChange"/>

        <group id="MarkdownNavigator.Toolbar.Right" class="com.intellij.openapi.actionSystem.DefaultActionGroup"
               text="Markdown Navigator Editor Layout Actions">

            <reference id="MarkdownNavigator.EditorOnlyLayoutChange"/>
            <reference id="MarkdownNavigator.PreviewOnlyLayoutChange"/>
            <reference id="MarkdownNavigator.EditorAndPreviewLayoutChange"/>

            <separator/>

            <reference id="MarkdownNavigator.ToggleEditorSplitLayout"/>

            <separator/>

            <reference id="MarkdownNavigator.HtmlPreviewChange"/>
            <reference id="MarkdownNavigator.ModifiedHtmlTextChange"/>
            <reference id="MarkdownNavigator.UnmodifiedHtmlTextChange"/>
        </group>
    </actions>

    <extensions defaultExtensionNs="com.intellij">
        <intentionAction>
            <className>com.vladsch.md.nav.intentions.wiki.ChangeExplicitToWikiLinkIntention</className>
            <bundleName>com.vladsch.md.nav.localization.intentions</bundleName>
            <categoryKey>intention.category.links</categoryKey>
            <descriptionDirectoryName>basic/ChangeExplicitToWikiLinkIntention</descriptionDirectoryName>
        </intentionAction>

        <intentionAction>
            <className>com.vladsch.md.nav.intentions.wiki.ChangeWikiToExplicitLinkIntention</className>
            <bundleName>com.vladsch.md.nav.localization.intentions</bundleName>
            <categoryKey>intention.category.wiki</categoryKey>
            <descriptionDirectoryName>basic/ChangeWikiToExplicitLinkIntention</descriptionDirectoryName>
        </intentionAction>

        <intentionAction>
            <className>com.vladsch.md.nav.intentions.wiki.DeleteUnusedWikiLinkTextIntention</className>
            <bundleName>com.vladsch.md.nav.localization.intentions</bundleName>
            <categoryKey>intention.category.wiki</categoryKey>
            <descriptionDirectoryName>basic/DeleteUnusedWikiLinkTextIntention</descriptionDirectoryName>
        </intentionAction>

        <intentionAction>
            <className>com.vladsch.md.nav.intentions.wiki.DeleteResolvableWikiLinkTextIntention</className>
            <bundleName>com.vladsch.md.nav.localization.intentions</bundleName>
            <categoryKey>intention.category.wiki</categoryKey>
            <descriptionDirectoryName>basic/DeleteResolvableWikiLinkTextIntention</descriptionDirectoryName>
        </intentionAction>

        <intentionAction>
            <className>com.vladsch.md.nav.intentions.wiki.DeleteWikiLinkRefIntention</className>
            <bundleName>com.vladsch.md.nav.localization.intentions</bundleName>
            <categoryKey>intention.category.wiki</categoryKey>
            <descriptionDirectoryName>basic/DeleteWikiLinkRefIntention</descriptionDirectoryName>
        </intentionAction>

        <intentionAction>
            <className>com.vladsch.md.nav.intentions.wiki.SwapWikiLinkTextAndRefIntention</className>
            <bundleName>com.vladsch.md.nav.localization.intentions</bundleName>
            <categoryKey>intention.category.wiki</categoryKey>
            <descriptionDirectoryName>basic/SwapWikiLinkTextAndRefIntention</descriptionDirectoryName>
        </intentionAction>

        <intentionAction>
            <className>com.vladsch.md.nav.intentions.link.ChangeAutoToExplicitLinkIntention</className>
            <bundleName>com.vladsch.md.nav.localization.intentions</bundleName>
            <categoryKey>intention.category.links</categoryKey>
            <descriptionDirectoryName>basic/ChangeAutoToExplicitLinkIntention</descriptionDirectoryName>
        </intentionAction>
    </extensions>

    <extensions defaultExtensionNs="com.intellij">
        <intentionAction>
            <className>com.vladsch.md.nav.flex.intentions.ToggleFlexmarkExampleIgnoreIntention</className>
            <bundleName>com.vladsch.md.nav.flex.localization.intentions</bundleName>
            <categoryKey>intention.category.flexmark</categoryKey>
            <descriptionDirectoryName>flex/ToggleFlexmarkExampleIgnoreIntention</descriptionDirectoryName>
        </intentionAction>

        <intentionAction>
            <className>com.vladsch.md.nav.flex.intentions.EditFlexmarkExampleOptionsIntention</className>
            <bundleName>com.vladsch.md.nav.flex.localization.intentions</bundleName>
            <categoryKey>intention.category.flexmark</categoryKey>
            <descriptionDirectoryName>flex/EditFlexmarkExampleOptionsIntention</descriptionDirectoryName>
        </intentionAction>

        <intentionAction>
            <className>com.vladsch.md.nav.flex.intentions.AddCaretSelectionMarkupIntention</className>
            <bundleName>com.vladsch.md.nav.flex.localization.intentions</bundleName>
            <categoryKey>intention.category.flexmark</categoryKey>
            <descriptionDirectoryName>flex/AddCaretSelectionMarkupIntention</descriptionDirectoryName>
        </intentionAction>

        <intentionAction>
            <className>com.vladsch.md.nav.flex.intentions.AddTestSpecExampleSectionBreakIntention</className>
            <bundleName>com.vladsch.md.nav.flex.localization.intentions</bundleName>
            <categoryKey>intention.category.flexmark</categoryKey>
            <descriptionDirectoryName>flex/AddTestSpecExampleSectionBreakIntention</descriptionDirectoryName>
        </intentionAction>

        <intentionAction>
            <className>com.vladsch.md.nav.flex.intentions.AddTestSpecExampleIntention</className>
            <bundleName>com.vladsch.md.nav.flex.localization.intentions</bundleName>
            <categoryKey>intention.category.flexmark</categoryKey>
            <descriptionDirectoryName>flex/AddTestSpecExampleIntention</descriptionDirectoryName>
        </intentionAction>

        <intentionAction>
            <className>com.vladsch.md.nav.flex.intentions.AddVisibleSpecCRIntention</className>
            <bundleName>com.vladsch.md.nav.flex.localization.intentions</bundleName>
            <categoryKey>intention.category.flexmark</categoryKey>
            <descriptionDirectoryName>flex/AddVisibleSpecCRIntention</descriptionDirectoryName>
        </intentionAction>

        <intentionAction>
            <className>com.vladsch.md.nav.flex.intentions.AddVisibleSpecLSIntention</className>
            <bundleName>com.vladsch.md.nav.flex.localization.intentions</bundleName>
            <categoryKey>intention.category.flexmark</categoryKey>
            <descriptionDirectoryName>flex/AddVisibleSpecLSIntention</descriptionDirectoryName>
        </intentionAction>

        <intentionAction>
            <className>com.vladsch.md.nav.flex.intentions.AddVisibleSpecIntelliJDummyIdentifierIntention</className>
            <bundleName>com.vladsch.md.nav.flex.localization.intentions</bundleName>
            <categoryKey>intention.category.flexmark</categoryKey>
            <descriptionDirectoryName>flex/AddVisibleSpecIntelliJDummyIdentifierIntention</descriptionDirectoryName>
        </intentionAction>

        <intentionAction>
            <className>com.vladsch.md.nav.flex.intentions.AddVisibleSpecTabIntention</className>
            <bundleName>com.vladsch.md.nav.flex.localization.intentions</bundleName>
            <categoryKey>intention.category.flexmark</categoryKey>
            <descriptionDirectoryName>flex/AddVisibleSpecTabIntention</descriptionDirectoryName>
        </intentionAction>

        <intentionAction>
            <className>com.vladsch.md.nav.flex.intentions.AddCaretPositionMarkupIntention</className>
            <bundleName>com.vladsch.md.nav.flex.localization.intentions</bundleName>
            <categoryKey>intention.category.flexmark</categoryKey>
            <descriptionDirectoryName>flex/AddCaretPositionMarkupIntention</descriptionDirectoryName>
        </intentionAction>

        <intentionAction>
            <className>com.vladsch.md.nav.flex.intentions.RemoveCaretMarkupIntention</className>
            <bundleName>com.vladsch.md.nav.flex.localization.intentions</bundleName>
            <categoryKey>intention.category.flexmark</categoryKey>
            <descriptionDirectoryName>flex/RemoveCaretMarkupIntention</descriptionDirectoryName>
        </intentionAction>
    </extensions>

    <extensions defaultExtensionNs="com.intellij">
        <applicationConfigurable id="MarkdownNavigator.Settings.Application"
                                 bundle="com.vladsch.md.nav.localization.strings"
                                 groupId="language"
                                 key="language.name"
                                 instance="com.vladsch.md.nav.settings.MdApplicationConfigurable">
        </applicationConfigurable>

        <applicationConfigurable id="MarkdownNavigator.Settings.Editor"
                                 parentId="MarkdownNavigator.Settings.Application"
                                 groupWeight="0"
                                 bundle="com.vladsch.md.nav.localization.strings"
                                 key="settings.markdown.editor.name"
                                 instance="com.vladsch.md.nav.settings.MdEditorConfigurable"/>

        <projectConfigurable id="MarkdownNavigator.Settings.Preview"
                             parentId="MarkdownNavigator.Settings.Application"
                             groupWeight="-1"
                             bundle="com.vladsch.md.nav.localization.strings"
                             key="settings.markdown.preview.name"
                             nonDefaultProject="false"
                             instance="com.vladsch.md.nav.settings.MdPreviewConfigurable"/>

        <projectConfigurable id="MarkdownNavigator.Settings.Parser"
                             parentId="MarkdownNavigator.Settings.Application"
                             groupWeight="-2"
                             bundle="com.vladsch.md.nav.localization.strings"
                             key="settings.markdown.parser.name"
                             nonDefaultProject="false"
                             instance="com.vladsch.md.nav.settings.MdParserConfigurable"/>

        <projectConfigurable id="MarkdownNavigator.Settings.Css"
                             parentId="MarkdownNavigator.Settings.Application"
                             groupWeight="-3"
                             bundle="com.vladsch.md.nav.localization.strings"
                             key="settings.markdown.css.name"
                             nonDefaultProject="false"
                             instance="com.vladsch.md.nav.settings.MdCssConfigurable"/>

        <projectConfigurable id="MarkdownNavigator.Settings.Html"
                             parentId="MarkdownNavigator.Settings.Application"
                             groupWeight="-4"
                             bundle="com.vladsch.md.nav.localization.strings"
                             key="settings.markdown.html.name"
                             nonDefaultProject="false"
                             instance="com.vladsch.md.nav.settings.MdHtmlConfigurable"/>

        <projectConfigurable id="MarkdownNavigator.Settings.Html.FencedCode"
                             parentId="MarkdownNavigator.Settings.Html"
                             groupWeight="-4"
                             bundle="com.vladsch.md.nav.localization.strings"
                             key="settings.markdown.html.fenced-code.name"
                             nonDefaultProject="false"
                             instance="com.vladsch.md.nav.settings.MdFencedCodeConfigurable"/>

        <applicationConfigurable id="MarkdownNavigator.Settings.Notifications"
                                 parentId="MarkdownNavigator.Settings.Application"
                                 groupWeight="-10"
                                 bundle="com.vladsch.md.nav.localization.strings"
                                 key="settings.markdown.notification.name"
                                 instance="com.vladsch.md.nav.settings.MdNotificationConfigurable"/>

        <applicationConfigurable id="MarkdownNavigator.Settings.Debug"
                                 parentId="MarkdownNavigator.Settings.Application"
                                 groupWeight="-20"
                                 bundle="com.vladsch.md.nav.localization.strings"
                                 key="settings.markdown.debug.name"
                                 instance="com.vladsch.md.nav.settings.MdDebugConfigurable"/>

        <applicationConfigurable id="MarkdownNavigator.Settings.Notices"
                                 parentId="MarkdownNavigator.Settings.Application"
                                 groupWeight="-31"
                                 bundle="com.vladsch.md.nav.localization.strings"
                                 key="settings.markdown.notices.name"
                                 instance="com.vladsch.md.nav.settings.MdNoticesConfigurable"/>
    </extensions>

    <extensions defaultExtensionNs="com.intellij">
        <localInspection groupPath="Markdown" language="Markdown" shortName="GitHubTable" bundle="com.vladsch.md.nav.localization.inspections" key="inspection.github.tables"
                         id="markdown.github.tables"
                         enabledByDefault="true" level="WEAK WARNING" runForWholeFile="false"
                         groupKey="group.names.github"
                         implementationClass="com.vladsch.md.nav.inspections.table.GitHubTableInspection"/>

        <localInspection groupPath="Markdown" language="Markdown" shortName="InvalidEmojiShortcut" bundle="com.vladsch.md.nav.localization.inspections" key="inspection.emoji-shortcuts"
                         id="markdown.invalid-emoji-shortcut"
                         enabledByDefault="true" level="ERROR" runForWholeFile="false"
                         groupKey="group.names.reference-issues"
                         implementationClass="com.vladsch.md.nav.inspections.emoji.InvalidEmojiShortcutInspection"/>
    </extensions>
</idea-plugin>


text:
package org.apache.giraph.comm.requests;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.giraph.conf.ImmutableClassesGiraphConfigurable;
import org.apache.giraph.conf.ImmutableClassesGiraphConfiguration;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.io.WritableComparable;

/**
 * Interface for requests to implement
 *
 * @param <I> Vertex id
 * @param <V> Vertex data
 * @param <E> Edge data
 * @param <M> Message data
 */
public abstract class WritableRequest<I extends WritableComparable,
    V extends Writable, E extends Writable, M extends Writable>
    implements Writable,
    ImmutableClassesGiraphConfigurable<I, V, E, M> {
  /**
   * Value to use when size of the request in serialized form is not known
   * or too expensive to calculate
   */
  public static final int UNKNOWN_SIZE = -1;

  /** Configuration */
  private ImmutableClassesGiraphConfiguration<I, V, E, M> conf;
  /** Client id */
  private int clientId = -1;
  /** Request id */
  private long requestId = -1;

  public int getClientId() {
    return clientId;
  }

  public void setClientId(int clientId) {
    this.clientId = clientId;
  }

  public long getRequestId() {
    return requestId;
  }

  public void setRequestId(long requestId) {
    this.requestId = requestId;
  }

  /**
   * Get the size of the request in serialized form. The number returned by
   * this function can't be less than the actual size - if the size can't be
   * calculated correctly return WritableRequest.UNKNOWN_SIZE.
   *
   * @return The size (in bytes) of serialized request,
   * or WritableRequest.UNKNOWN_SIZE if the size is not known
   * or too expensive to calculate.
   */
  public int getSerializedSize() {
    // 4 for clientId, 8 for requestId
    return 4 + 8;
  }

  /**
   * Get the type of the request
   *
   * @return Request type
   */
  public abstract RequestType getType();

  /**
   * Serialize the request
   *
   * @param input Input to read fields from
   */
  abstract void readFieldsRequest(DataInput input) throws IOException;

  /**
   * Deserialize the request
   *
   * @param output Output to write the request to
   */
  abstract void writeRequest(DataOutput output) throws IOException;

  @Override
  public final ImmutableClassesGiraphConfiguration<I, V, E, M> getConf() {
    return conf;
  }

  @Override
  public final void setConf(ImmutableClassesGiraphConfiguration<I, V,
      E, M> conf) {
    this.conf = conf;
  }

  @Override
  public final void readFields(DataInput input) throws IOException {
    clientId = input.readInt();
    requestId = input.readLong();
    readFieldsRequest(input);
  }

  @Override
  public final void write(DataOutput output) throws IOException {
    output.writeInt(clientId);
    output.writeLong(requestId);
    writeRequest(output);
  }
}

redpajama_set_name: RedPajamaGithub


text:
"""Tests for partitioned_variables.py."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import numpy as np
from six.moves import xrange  # pylint: disable=redefined-builtin
import tensorflow as tf

class PartitionerCreatorsTest(tf.test.TestCase):

  def testFixedSizePartitioner(self):
    with self.test_session():
      partitioner = tf.fixed_size_partitioner(5, axis=0)
      with tf.variable_scope("root", partitioner=partitioner):
        v0 = tf.get_variable("v0", dtype=tf.float32, shape=(10, 10))
        v0_list = v0._get_variable_list()
        v0_part = v0._get_partitions()
        self.assertEqual(len(v0_list), 5)
        self.assertAllEqual(v0_part, (5, 1))

  def _testVariableAxisSizePartitioner(self, name, axis, max_shard_bytes,
                                       expected_axis_shards,
                                       expected_partitions,
                                       max_shards=None):
    partitioner = tf.variable_axis_size_partitioner(
        axis=axis, max_shard_bytes=max_shard_bytes, max_shards=max_shards)

    with tf.variable_scope("root", partitioner=partitioner):
      v0 = tf.get_variable(name, dtype=tf.float32, shape=(4, 8, 16, 32))
      v0_list = v0._get_variable_list()
      v0_part = v0._get_partitions()
      self.assertEqual(len(v0_list), expected_axis_shards)
      self.assertAllEqual(v0_part, expected_partitions)

  def testVariableAxisSizePartitioner(self):
    with self.test_session():
      # Create a partitioned variable of shape (4, 8, 16, 32) type float32
      # Bytes per slice along the given axes:

      # 8 * 16 * 32 * sizeof(float32) = 16384 / slice on axis 0
      # 4 * 16 * 32 * sizeof(float32) = 8192 / slice on axis 1
      # 4 * 8 * 32 * sizeof(float32) = 4096 / slice on axis 2
      # 4 * 8 * 16 * sizeof(float32) = 2048 / slice on axis 3

      # Now partition it in different ways...

      # No need to slice: bytes_per_slice * dim0 = 65536 < max_shard_bytes
      self._testVariableAxisSizePartitioner("v0", axis=0,
                                            max_shard_bytes=131072,
                                            expected_axis_shards=1,
                                            expected_partitions=(1, 1, 1, 1))

      # Slice exactly once: bytes_per_slice * dim1 = 65536 = max_shard_bytes
      self._testVariableAxisSizePartitioner("v1", axis=1,
                                            max_shard_bytes=65536,
                                            expected_axis_shards=1,
                                            expected_partitions=(1, 1, 1, 1))

      # Slice into 2 parts:
      # bytes_per_slice = 4096
      # slices_per_shard = 32768 / 4096 = 8
      # axis_shards = 16 / 8 = 2
      self._testVariableAxisSizePartitioner("v2", axis=2,
                                            max_shard_bytes=32768,
                                            expected_axis_shards=2,
                                            expected_partitions=(1, 1, 2, 1))

      # This partitioner makes sure we maximize the number of shards along
      # axis 3. Slice it into 32 parts:
      # bytes_per_slice = 2048
      # slices_per_shard = 2048 / 2048 = 1
      # axis_shards = 32 / 1 = 32
      self._testVariableAxisSizePartitioner("v3a", axis=3,
                                            max_shard_bytes=2048,
                                            expected_axis_shards=32,
                                            expected_partitions=(1, 1, 1, 32))

      # This partitioner makes sure we do not go past the bound of allowable
      # number of shards along axis 3.
      # Slice into 32 parts:
      # bytes_per_slice = 2048
      # slices_per_shard = max(1, 1024 / 2048) = 1
      # axis_shards = 32 / 1 = 32
      # Slice into max of 32 parts because: max_shard_bytes < bytes_per_slice
      self._testVariableAxisSizePartitioner("v3b", axis=3,
                                            max_shard_bytes=1024,
                                            expected_axis_shards=32,
                                            expected_partitions=(1, 1, 1, 32))

      # Specify max_shards so that it won't affect sharding.
      self._testVariableAxisSizePartitioner("v3c", axis=3,
                                            max_shard_bytes=1024,
                                            expected_axis_shards=32,
                                            expected_partitions=(1, 1, 1, 32),
                                            max_shards=33)

      # Specify max_shards so that it will affect sharding.
      self._testVariableAxisSizePartitioner("v3d", axis=3,
                                            max_shard_bytes=1024,
                                            expected_axis_shards=2,
                                            expected_partitions=(1, 1, 1, 2),
                                            max_shards=2)

      # Use the partitioner with strings
      partitioner_axis3_str = tf.variable_axis_size_partitioner(
          axis=3, max_shard_bytes=32768, bytes_per_string_element=8)

      with tf.variable_scope("root", partitioner=partitioner_axis3_str):
        v3str = tf.get_variable(
            "v3str",
            initializer=np.array([""] * 4 * 8 * 16 * 32).reshape(4, 8, 16, 32),
            dtype=tf.string,
            shape=(4, 8, 16, 32))
        v3str_list = v3str._get_variable_list()
        v3str_part = v3str._get_partitions()

        # Now the estimated bytes_per_slice = 4*8*16*bytes_per_string_element
        # which is equal to 4096.  Setting a max_shard_bytes of 32768
        # and we should get a split of 4.
        # Slice into 4 parts:
        # bytes_per_slice = 4096
        # slices_per_shard = 32768 / 4096 = 8
        # axis_shards = 32 / 8 = 4
        self.assertEqual(len(v3str_list), 4)
        self.assertAllEqual(v3str_part, (1, 1, 1, 4))

  def _testMinMaxVariablePartitioner(self, max_partitions, axis, min_slice_size,
                                     var_name, var_shape,
                                     expected_axis_shards, expected_partitions):
    partitioner = tf.min_max_variable_partitioner(max_partitions=max_partitions,
                                                  axis=axis,
                                                  min_slice_size=min_slice_size)
    with tf.variable_scope("root", partitioner=partitioner):
      v0 = tf.get_variable(var_name, dtype=tf.float32, shape=var_shape)
      v0_list = v0._get_variable_list()
      v0_part = v0._get_partitions()
      self.assertEqual(len(v0_list), expected_axis_shards)
      self.assertAllEqual(v0_part, expected_partitions)

  def testMinMaxVariablePartitioner(self):
    with self.test_session():
      # Partitioning a variable of shape=[2048] with a minimum of 2K per slice.
      self._testMinMaxVariablePartitioner(max_partitions=100, axis=0,
                                          min_slice_size=2 << 10,
                                          var_name="v0_0", var_shape=[2048],
                                          expected_axis_shards=4,
                                          expected_partitions=[4])

      # Partitioning a variable of shape=[2048, 1024] with a minimum of 256K per
      # slice.
      self._testMinMaxVariablePartitioner(max_partitions=100, axis=0,
                                          min_slice_size=256 << 10,
                                          var_name="v0", var_shape=[2048, 1024],
                                          expected_axis_shards=32,
                                          expected_partitions=[32, 1])

      # max_partitions restricts partitioning of the variable.
      self._testMinMaxVariablePartitioner(max_partitions=16, axis=0,
                                          min_slice_size=256 << 10,
                                          var_name="v1_max",
                                          var_shape=[2048, 1024],
                                          expected_axis_shards=16,
                                          expected_partitions=[16, 1])
      self._testMinMaxVariablePartitioner(max_partitions=1, axis=0,
                                          min_slice_size=256 << 10,
                                          var_name="v2_max",
                                          var_shape=[2048, 1024],
                                          expected_axis_shards=1,
                                          expected_partitions=[1, 1])

      # Reducing/Increasing min_slice_size proportionately increases/reduces the
      # number of partitions.
      self._testMinMaxVariablePartitioner(max_partitions=100, axis=0,
                                          min_slice_size=128 << 10,
                                          var_name="v3_slice",
                                          var_shape=[2048, 1024],
                                          expected_axis_shards=64,
                                          expected_partitions=[64, 1])
      self._testMinMaxVariablePartitioner(max_partitions=100, axis=0,
                                          min_slice_size=512 << 10,
                                          var_name="v4_slice",
                                          var_shape=[2048, 1024],
                                          expected_axis_shards=16,
                                          expected_partitions=[16, 1])

      # Partitioning the variable along a different axis.
      self._testMinMaxVariablePartitioner(max_partitions=100, axis=1,
                                          min_slice_size=256 << 10,
                                          var_name="v5_axis",
                                          var_shape=[64, 1024, 1, 3],
                                          expected_axis_shards=3,
                                          expected_partitions=[1, 3, 1, 1])
      self._testMinMaxVariablePartitioner(max_partitions=100, axis=3,
                                          min_slice_size=256 << 10,
                                          var_name="v6_axis",
                                          var_shape=[64, 1024, 1, 3],
                                          expected_axis_shards=3,
                                          expected_partitions=[1, 1, 1, 3])

      # Can not partition the variable more than what its shape allows.
      self._testMinMaxVariablePartitioner(max_partitions=100, axis=0,
                                          min_slice_size=256 << 10,
                                          var_name="v7_shape",
                                          var_shape=[16, 128, 1024],
                                          expected_axis_shards=16,
                                          expected_partitions=[16, 1, 1])
      self._testMinMaxVariablePartitioner(max_partitions=100, axis=0,
                                          min_slice_size=256 << 10,
                                          var_name="v8_shape",
                                          var_shape=[4, 512, 1024],
                                          expected_axis_shards=4,
                                          expected_partitions=[4, 1, 1])

def _IotaInitializer(shape, dtype=tf.float32, partition_info=None):
  assert dtype == tf.float32
  if len(shape) == 1:
    return range(shape[0])
  else:
    val = _IotaInitializer(shape[1:], dtype)
    return [[(10 ** i) * v for v in val] for i in range(shape[0])]

class PartitionedVariablesTestCase(tf.test.TestCase):

  def _TestSaveSpec(self, slices, expected_specs):
    self.assertEqual(len(expected_specs), len(slices))
    for i in xrange(len(expected_specs)):
      self.assertEquals(expected_specs[i], slices[i]._save_slice_info.spec)

  def testVecConstantInit(self):
    with self.test_session():
      rnd_par = tf.constant([1, 2, 3, 4])
      vs = tf.create_partitioned_variables([4], [4], rnd_par)
      tf.global_variables_initializer().run()
      val = tf.concat(0, vs).eval()
      rnd = rnd_par.eval()
      self.assertAllClose(rnd, val)
      self.assertEqual([tf.int32] * 4, [v.dtype.base_dtype for v in vs])
      self._TestSaveSpec(vs, ["4 0,1", "4 1,1", "4 2,1", "4 3,1"])

  def testConstantInit(self):
    with self.test_session():
      rnd_par = tf.constant([[1, 2, 3, 4], [5, 6, 7, 8]])
      vs = tf.create_partitioned_variables([2, 4], [1, 2], rnd_par)
      tf.global_variables_initializer().run()
      val = tf.concat(1, vs).eval()
      rnd = rnd_par.eval()
      self.assertAllClose(rnd, val)
      self.assertEqual([tf.int32] * 2, [v.dtype.base_dtype for v in vs])
      self._TestSaveSpec(vs, ["2 4 0,2:0,2", "2 4 0,2:2,2"])

  def testName(self):
    with self.test_session():
      rnd_par = tf.constant([[1, 2, 3, 4], [5, 6, 7, 8]])
      with tf.variable_scope("hi"):
        vs1 = tf.create_partitioned_variables([2, 4], [1, 2], rnd_par)
        vs2 = tf.create_partitioned_variables([2, 4], [1, 2], rnd_par)
      tf.global_variables_initializer().run()
      var1_name = vs1[0]._save_slice_info.full_name
      var2_name = vs2[0]._save_slice_info.full_name
      self.assertEqual("hi/PartitionedVariable", var1_name)
      self.assertEqual("hi/PartitionedVariable_1", var2_name)
      self.assertEqual(var1_name + "/part_0:0", vs1[0].name)
      self.assertEqual(var1_name + "/part_1:0", vs1[1].name)
      self.assertEqual(var2_name + "/part_0:0", vs2[0].name)
      self.assertEqual(var2_name + "/part_1:0", vs2[1].name)
    # Test same variable.
    with self.test_session():
      rnd_par = tf.constant([[1, 2, 3, 4], [5, 6, 7, 8]])
      with tf.variable_scope("hola") as vs:
        vs1 = tf.create_partitioned_variables(
            [2, 4], [1, 2], rnd_par, dtype=tf.int32)
      with tf.variable_scope(vs, reuse=True):
        vs2 = tf.create_partitioned_variables(
            [2, 4], [1, 2], rnd_par, dtype=tf.int32)
      tf.global_variables_initializer().run()
      var1_name = vs1[0]._save_slice_info.full_name
      var2_name = vs2[0]._save_slice_info.full_name
      self.assertEqual("hola/PartitionedVariable", var1_name)
      self.assertEqual("hola/PartitionedVariable", var2_name)
      self.assertEqual(var1_name + "/part_0:0", vs1[0].name)
      self.assertEqual(var1_name + "/part_1:0", vs1[1].name)
      self.assertEqual(var2_name + "/part_0:0", vs2[0].name)
      self.assertEqual(var2_name + "/part_1:0", vs2[1].name)
    # Test name_scope
    with self.test_session():
      rnd_par = tf.constant([[1, 2, 3, 4], [5, 6, 7, 8]])
      with tf.name_scope("ola"):
        vs1 = tf.create_partitioned_variables([2, 4], [1, 2], rnd_par)
        vs2 = tf.create_partitioned_variables([2, 4], [1, 2], rnd_par)
      tf.global_variables_initializer().run()
      var1_name = vs1[0]._save_slice_info.full_name
      var2_name = vs2[0]._save_slice_info.full_name
      # Currently, the name scope 'ola' has no effect.
      self.assertEqual("PartitionedVariable", var1_name)
      self.assertEqual("PartitionedVariable_1", var2_name)
      self.assertEqual(var1_name + "/part_0:0", vs1[0].name)
      self.assertEqual(var1_name + "/part_1:0", vs1[1].name)
      self.assertEqual(var2_name + "/part_0:0", vs2[0].name)
      self.assertEqual(var2_name + "/part_1:0", vs2[1].name)

  def testRandomInitValue(self):
    with self.test_session():
      rnd = tf.Variable(tf.random_uniform([200, 40]))
      vs = tf.create_partitioned_variables(
          rnd.get_shape(), [1, 10], rnd.initialized_value())
      tf.global_variables_initializer().run()
      val = tf.concat(1, vs).eval()
      rnd = rnd.eval()
      self.assertAllClose(rnd, val)
      self.assertEqual([tf.float32] * 10, [v.dtype.base_dtype for v in vs])
      self._TestSaveSpec(vs, ["200 40 0,200:0,4",
                              "200 40 0,200:4,4",
                              "200 40 0,200:8,4",
                              "200 40 0,200:12,4",
                              "200 40 0,200:16,4",
                              "200 40 0,200:20,4",
                              "200 40 0,200:24,4",
                              "200 40 0,200:28,4",
                              "200 40 0,200:32,4",
                              "200 40 0,200:36,4"])

  def testRandomInitUnevenPartitions(self):
    with self.test_session():
      rnd = tf.Variable(
          tf.random_uniform([20, 43], dtype=tf.float64))
      var_lists = [
          tf.create_partitioned_variables(
              rnd.get_shape(), [1, i],
              rnd.initialized_value())
          for i in xrange(1, 10)]
      tf.global_variables_initializer().run()
      rnd_val = rnd.eval()
      # Only check the slice save specs for the first 5 tf.
      save_specs = [
          # One slice
          ["20 43 0,20:0,43"],
          # Two slices
          ["20 43 0,20:0,22",
           "20 43 0,20:22,21"],
          # Three slices
          ["20 43 0,20:0,15",
           "20 43 0,20:15,14",
           "20 43 0,20:29,14"],
          # Four slices
          ["20 43 0,20:0,11",
           "20 43 0,20:11,11",
           "20 43 0,20:22,11",
           "20 43 0,20:33,10"],
          # Five slices
          ["20 43 0,20:0,9",
           "20 43 0,20:9,9",
           "20 43 0,20:18,9",
           "20 43 0,20:27,8",
           "20 43 0,20:35,8"]]
      for i, vs in enumerate(var_lists):
        var_val = tf.concat(1, vs).eval()
        self.assertAllClose(rnd_val, var_val)
        self.assertEqual(
            [tf.float64] * len(vs), [v.dtype.base_dtype for v in vs])
        if i < len(save_specs):
          self._TestSaveSpec(vs, save_specs[i])

  def testDegenerate(self):
    with self.test_session():
      rnd = tf.Variable(tf.random_uniform([10, 43]))
      vs = tf.create_partitioned_variables(
          rnd.get_shape(), [1, 1], rnd.initialized_value())
      tf.global_variables_initializer().run()
      val = tf.concat(0, vs).eval()
      rnd = rnd.eval()
      self.assertAllClose(rnd, val)
      self._TestSaveSpec(vs, ["10 43 0,10:0,43"])

  def testSliceSizeOne(self):
    with self.test_session():
      rnd = tf.Variable(tf.random_uniform([10, 43]))
      vs = tf.create_partitioned_variables(
          rnd.get_shape(), [10, 1], rnd.initialized_value())
      tf.global_variables_initializer().run()
      val = tf.concat(0, vs).eval()
      rnd = rnd.eval()
      self.assertAllClose(rnd, val)
      self._TestSaveSpec(vs, ["10 43 0,1:0,43",
                              "10 43 1,1:0,43",
                              "10 43 2,1:0,43",
                              "10 43 3,1:0,43",
                              "10 43 4,1:0,43",
                              "10 43 5,1:0,43",
                              "10 43 6,1:0,43",
                              "10 43 7,1:0,43",
                              "10 43 8,1:0,43",
                              "10 43 9,1:0,43"])

  def testIotaInitializer(self):
    self.assertAllClose([0., 1., 2., 3.], _IotaInitializer([4]))
    self.assertAllClose([[0., 1.], [0., 10.], [0., 100.], [0., 1000.]],
                        _IotaInitializer([4, 2]))
    with self.test_session():
      vs = tf.create_partitioned_variables([13, 5], [3, 1], _IotaInitializer)
      tf.global_variables_initializer().run()
      slice0 = _IotaInitializer([5, 5])
      slice1 = _IotaInitializer([4, 5])
      slice2 = _IotaInitializer([4, 5])
      val = tf.concat(0, vs).eval()
      self.assertAllClose(slice0 + slice1 + slice2, val)
      self._TestSaveSpec(vs, ["13 5 0,5:0,5",
                              "13 5 5,4:0,5",
                              "13 5 9,4:0,5"])

  def testRandomInitializer(self):
    # Sanity check that the slices uses a different seed when using a random
    # initializer function.
    with self.test_session():
      var0, var1 = tf.create_partitioned_variables(
          [20, 12], [1, 2], tf.random_uniform_initializer())
      tf.global_variables_initializer().run()
      val0, val1 = var0.eval().flatten(), var1.eval().flatten()
      self.assertTrue(np.linalg.norm(val0 - val1) > 1e-6)
    # Negative test that proves that slices have the same values if
    # the random initializer uses a seed.
    with self.test_session():
      var0, var1 = tf.create_partitioned_variables(
          [20, 12], [1, 2], tf.random_uniform_initializer(seed=201))
      tf.global_variables_initializer().run()
      val0, val1 = var0.eval().flatten(), var1.eval().flatten()
      self.assertAllClose(val0, val1)

  def testSomeErrors(self):
    with self.test_session():
      rnd = tf.Variable(tf.random_uniform([10, 43]))
      with self.assertRaises(ValueError):
        tf.create_partitioned_variables([10], [1, 1], rnd.initialized_value())
      with self.assertRaises(ValueError):
        tf.create_partitioned_variables([10, 20], [1], rnd.initialized_value())
      with self.assertRaises(ValueError):
        tf.create_partitioned_variables([10, 43], [1], rnd.initialized_value())
      with self.assertRaises(ValueError):
        tf.create_partitioned_variables(
            [10, 43], [1, 2, 3], rnd.initialized_value())
      with self.assertRaises(ValueError):
        tf.create_partitioned_variables(
            [10, 43], [11, 1], rnd.initialized_value())
      with self.assertRaises(ValueError):
        tf.create_partitioned_variables(
            [10, 43], [20, 1], rnd.initialized_value())
      with self.assertRaises(ValueError):
        tf.create_partitioned_variables(
            [10, 43], [1, 50], rnd.initialized_value())

  def testControlDepsNone(self):
    with self.test_session() as session:
      c = tf.constant(1.0)
      with tf.control_dependencies([c]):
        # d get the control dependency.
        d = tf.constant(2.0)
        # Partitioned variables do not.
        var_x = tf.get_variable(
            "x",
            initializer=tf.ones_initializer([2]),
            partitioner=tf.variable_axis_size_partitioner(4))

        ops_before_read = session.graph.get_operations()
        var_x.as_tensor()  # Caches the ops for subsequent reads.
        reading_ops = [op for op in session.graph.get_operations()
                       if op not in ops_before_read]

      self.assertEqual([c.op], d.op.control_inputs)
      # Tests that no control dependencies are added to reading a partitioned
      # variable which is similar to reading a variable.
      for op in reading_ops:
        self.assertEqual([], op.control_inputs)

  def testConcat(self):
    with self.test_session() as session:
      var_x = tf.get_variable(
          "x",
          initializer=tf.constant([1., 2.]),
          partitioner=tf.variable_axis_size_partitioner(4))

      c = tf.constant(1.0)
      with tf.control_dependencies([c]):
        ops_before_concat = session.graph.get_operations()
        value = var_x._concat()  # pylint: disable=protected-access
        concat_ops = [op for op in session.graph.get_operations()
                      if op not in ops_before_concat]

      concat_control_inputs = [ci for op in concat_ops
                               for ci in op.control_inputs]
      self.assertTrue(
          c.op in concat_control_inputs,
          "var_x._concat() should get control dependencies from its scope.")
      tf.global_variables_initializer().run()
      self.assertAllClose(value.eval(), var_x.as_tensor().eval())

if __name__ == "__main__":
  tf.test.main()