Instruction:
作为 Java 安全专家，检测此代码中的安全漏洞：
## 内容1
### 文件路径：
xwiki-platform-core/xwiki-platform-attachment/xwiki-platform-attachment-ui/src/main/resources/XWiki/AttachmentSelector.xml
### 代码内容：
<?xml version="1.1" encoding="UTF-8"?>

<xwikidoc version="1.5" reference="XWiki.AttachmentSelector" locale="">
  <web>XWiki</web>
  <name>AttachmentSelector</name>
  <language/>
  <defaultLanguage/>
  <translation>0</translation>
  <creator>xwiki:XWiki.Admin</creator>
  <parent>Main.WebHome</parent>
  <author>xwiki:XWiki.Admin</author>
  <contentAuthor>xwiki:XWiki.Admin</contentAuthor>
  <version>1.1</version>
  <title>#if ($request.docname)$xwiki.getDocument($request.docname).plainTitle ($request.docname): #end$services.localization.render('xe.attachmentSelector.gallery.title')</title>
  <comment/>
  <minorEdit>false</minorEdit>
  <syntaxId>xwiki/2.1</syntaxId>
  <hidden>true</hidden>
  <content>{{velocity output="false"}}
#set ($translationPrefix = 'xe.attachmentSelector')

#if ($request.xaction == 'postUpload')
  #set ($targetDocument = $xwiki.getDocument($request.get('docname')))
  #set ($targetAttachDocument = $xwiki.getDocument($request.get('targetdocname')))

  #set ($fieldname = $request.get('fieldname'))
  #set ($comment = $services.localization.render("${translationPrefix}.postUpload.comment", [$fieldname]))
  #set ($docAction = $request.get('docAction'))
  #set ($attachmentList = $targetAttachDocument.getAttachmentList())
  #if ($attachmentList && $attachmentList.size() > 0)
    #set ($sortedAttachments = $collectiontool.sort($attachmentList, 'date:desc'))
    #set ($lastAttachment = $sortedAttachments.get(0))
  #end
  $response.sendRedirect($targetDocument.getURL($docAction, $escapetool.url({
    $fieldname: $lastAttachment.filename,
    'comment': $comment,
    'form_token': $request.form_token
  })))
  #stop
#end
{{/velocity}}

{{velocity output="false"}}
##
## Macros
##
#set ($attachmentPickerDocName = 'XWiki.AttachmentSelector')

$xwiki.ssx.use($attachmentPickerDocName)
$xwiki.jsx.use($attachmentPickerDocName)

#**
 * Displays the attachment gallery as a list of attachment boxes, starting with special boxes for uploading a new attachment and for setting a default value.
 *
 * @param $targetDocument the document to recieve the field value being modified
 * @param $targetAttachDocument the document to list/save attachments to
 * @param $options generic picker options
 *#
#macro (attachmentPicker_displayAttachmentGallery $targetDocument, $targetAttachDocument, $options)
  #set ($currentValue = $targetDocument.getValue($options.property))
  #if ("$!{targetAttachDocument.getAttachment($currentValue)}" == '')
    #set ($currentValue = "$!{options.defaultValue}")
  #end
  (% class="gallery" %)(((
  ## Only display the upload form if they have edit permission on targetAttachDocument
  #attachmentPicker_displayUploadForm($targetDocument, $targetAttachDocument, $options)
  #attachmentPicker_displayAttachmentGalleryEmptyValue($targetDocument, $targetAttachDocument, $options, $currentValue)
  #if ("$!services.temporaryAttachments" != '')
    #set ($unsortedAttachments = $services.temporaryAttachments.listAllAttachments($targetAttachDocument))
    #set ($sortedAttachments = $collectiontool.sort($unsortedAttachments, "${options.sortAttachmentsBy}"))
  #else
    #set ($sortedAttachments = $collectiontool.sort($targetAttachDocument.getAttachmentList(), "${options.sortAttachmentsBy}") )
  #end
  #foreach ($attachment in $sortedAttachments)
    #set ($extension = $attachment.getFilename())
    #set ($extension = $extension.substring($mathtool.add($extension.lastIndexOf('.'), 1)).toLowerCase())
    #if ($options.filter.size() == 0 || $options.filter.contains($extension))
      #attachmentPicker_displayAttachmentBox($attachment $targetDocument $targetAttachDocument, $options $currentValue)
    #end
  #end
  )))
#end

#**
 * Displays an attachment box.
 *
 * @param $attachment the target attachment to display
 * @param $targetDocument the document being modified
 * @param $options generic picker options
 * @param $currentValue the currently selected file, used for determining if the box should be highlighted as the current value
 *#
#macro (attachmentPicker_displayAttachmentBox $attachment $targetDocument $targetAttachDocument, $options $currentValue)
  #set ($hasTemporaryAttachment = "$!services.temporaryAttachments" != '')
  #set ($canEdit = $xwiki.hasAccessLevel('edit', $xcontext.user, ${targetAttachDocument.fullName}))
  #set ($isTemporaryAttachment = false)
  #if(!$hasTemporaryAttachment)
    #set ($canDeleteAttachment = $canEdit)
  #else
    #set ($isTemporaryAttachment = $services.temporaryAttachments.temporaryAttachmentExists($attachment))
    ## TODO: Update once it is made possible to delete temporary attachments (see XWIKI-20225).
    #set ($canDeleteAttachment = !$isTemporaryAttachment && $canEdit)
  #end
  #set ($cssClasses = [])
  #if ($options.displayImage && $attachment.isImage())
    #set ($discard = $cssClasses.add('gallery_image'))
  #end
  #if ($isTemporaryAttachment)
    #set ($discard = $cssClasses.add('temporary_attachment'))
  #end
  #attachmentPicker_displayStartFrame({'value' : $attachment.filename, 'text' : $attachment.filename, 'cssClass' : "${stringtool.join($cssClasses, ' ')}"} $currentValue)
  #attachmentPicker_displayAttachmentDetails($attachment $options)
  #set ($returnURL = $escapetool.url($doc.getURL('view', $request.queryString)))
  #set ($deleteURL = $targetAttachDocument.getAttachmentURL($attachment.filename, 'delattachment', "xredirect=${returnURL}&form_token=$!{services.csrf.getToken()}") )
  #set ($viewURL = $targetAttachDocument.getAttachmentURL($attachment.filename) )##{'name' : 'download', 'url' : $viewURL, 'rel' : '__blank'}
  #set ($selectURL = $targetDocument.getURL(${options.get('docAction')}, $escapetool.url({
    "${options.get('classname')}_${options.get('object')}_${options.get('property')}": ${attachment.filename},
    'form_token': $!{services.csrf.getToken()}
  })))
  ## Delete action is only proposed for users with the edit right on the document.
  ## If the temporary attachment is available, the delete action is only allowed for non-temporary attachments.
  #set ($attachmentActions = [{'name' : 'select', 'url' : $selectURL}])
  #if($canDeleteAttachment)
    #set ($discard = $attachmentActions.add({'name' : 'delete', 'url' : $deleteURL}))
  #end
  #define($additionalContent)
    #if ($isTemporaryAttachment)
      #set ($titleMessage = $services.localization.render('attachment.attachmentSelector.attachmentBox.temporaryAttachmentTitle'))
      #set ($titleMessage = $services.rendering.escape($titleMessage, 'xwiki/2.1'))
      (% title="$titleMessage" %)$services.icon.render('clock')(%%)
    #end
  #end
  #attachmentPicker_displayEndFrame ($attachmentActions $additionalContent)
#end

#**
 * Writes the wiki code used at the start of an attachment box. Outputs the attachment title bar, and opens the inner frame div.
 *
 * @param $boxOptions a map of parameters/options for the current attachment, holding, for example, the attachment name (boxOptions.value),
 *        the title to display (boxOptions.text), optional extra CSS classnames to put on the box (boxOptions.cssClass)
 * @param $currentValue the currently selected file, used for determining if this attachment should be highlighted as the current value
 *#
#macro (attachmentPicker_displayStartFrame $boxOptions $currentValue)
  (% class="gallery_attachmentbox $!{boxOptions.cssClass} #if ("$!{boxOptions.value}" == $currentValue) current#{end}" %)(((
    (% class="gallery_attachmenttitle" title="$services.rendering.escape($!{boxOptions.value}, 'xwiki/2.1')" %)(((
      $services.rendering.escape($boxOptions.text, 'xwiki/2.1')
    )))
    (% class="gallery_attachmentframe" %)(((
#end

#**
 * Displays details about an attachment inside the attachment box. If the attachment is an image and the "displayImage" option is on,
 * then the image is displayed. Otherwise, some basic information is displayed: the version, the size, the date and the author.
 *
 * @param $attachment the target attachment to display
 * @param $options generic picker options
 *#
#macro (attachmentPicker_displayAttachmentDetails $attachment $options)
  #if ($attachment)
    ## Compute the attachment reference because there's no getter.
    #set ($attachmentReference = $services.model.createAttachmentReference($attachment.document.documentReference,
      $attachment.filename))
    #set ($attachmentStringReference = $services.rendering.escape($services.model.serialize($attachmentReference, 'default'), 'xwiki/2.1'))
    #if ($attachment.isImage() && $options.displayImage)
      ## We add the version to the query string in order to invalidate the cache when an image attachment is replaced.
      #set ($queryString = $escapetool.url({'version': $attachment.version}))
      [[[[image:${attachmentStringReference}||width=180 queryString="$queryString"]]>>attach:$attachmentStringReference]]
    #else
      * (% class="mime" %){{html wiki=false clean=false}}#mimetypeimg($attachment.getMimeType().toLowerCase() $attachment.getFilename().toLowerCase()){{/html}}(%%) (% class="filename" %)$services.rendering.escape($attachment.getFilename(), 'xwiki/2.1')(% %)
      * v$attachment.getVersion() (#dynamicsize($attachment.longSize))
      * $services.localization.render('core.viewers.attachments.author', [$!{xwiki.getUserName($attachment.author, false)}]) $services.localization.render('core.viewers.attachments.date', [$!{xwiki.formatDate($attachment.date, 'dd/MM/yyyy hh:mm')}])
      * (% class="buttonwrapper" %)[[${services.localization.render("${translationPrefix}.actions.download")}>>attach:${attachmentStringReference}||title="$services.localization.render("${translationPrefix}.actions.download")" rel="__blank" class="button"]](%%)
    #end
  #end
#end

#**
 * Writes the wiki code used at the end of an attachment box. Closes the inner frame div, and outputs the attachment actions.
 *
 * @param $actions a list of maps defining action buttons, where each entry contains a subset of the following:
 *

 *
name

 *
identifies the action; the name is used as a CSS classname, and in the translation key for the display text, as "xe.attachmentSelector.actions.<name>"

 *
url

 *
the destination of the button

 *
rel

 *
an optional parameter to be used in the "rel" HTML attribute; for example "__blank" can be used to open the link in a new tab/window

 *

 * @param $additionalContent optional additional content that does not follow the structure of the actions
 *#
#macro (attachmentPicker_displayEndFrame $actions $additionalContent)
    )))## attachmentframe
    (% class="gallery_actions" %)(((
      #foreach ($action in $actions)
        #set( $actionname = $services.localization.render("${translationPrefix}.actions.${action.name}") )
        [[${actionname}>>path:${action.url}||class="tool ${action.name}" title="${actionname}" #if($action.rel) rel="${action.rel}"#end]]##
      #end
      $!additionalContent
    )))## actions
  )))## attachmentbox
#end

#**
 * Displays the upload box used for adding and selecting a new attachment.
 *
 * @param $targetDocument the document with the property being modified
 * @param $targetAttachDocument the document to upload the attachment to
 * @param $options generic picker options
 *#
#macro (attachmentPicker_displayUploadForm $targetDocument, $targetAttachDocument, $options)
#attachmentPicker_displayStartFrame({
   'value' : $services.localization.render("${translationPrefix}.upload.title"),
   'text' : $services.localization.render("${translationPrefix}.upload.title"),
   'cssClass' : 'gallery_upload'
  } $NULL)
{{html clean="false"}}
<form action="$targetAttachDocument.getURL('upload')" enctype="multipart/form-data" method="post" id="uploadAttachment" class="uploadAttachment xform">

    #if (${options.rawfilter} != '')
      $escapetool.xml($services.localization.render("${translationPrefix}.upload.hint", [${options.rawfilter}]))
    #end
    <input type="file" name="filepath" id="attachfile" class="noitems" title="$!{escapetool.xml($options.rawfilter)}"/>
    <input type="hidden" name="xredirect" value="$xwiki.getDocument($attachmentPickerDocName).getURL('get', "xaction=postUpload&amp;docAction=$!{escapetool.url($options.get('docAction'))}&amp;targetdocname=$!{escapetool.url($targetAttachDocument.fullName)}&amp;docname=$!{escapetool.url($targetDocument.fullName)}&amp;fieldname=$!{escapetool.url($options.get('classname'))}_$!{escapetool.url($options.get('object'))}_$!{escapetool.url($options.get('property'))}&amp;form_token=$!{services.csrf.getToken()}")" />
    <input type="hidden" name="docname" value="$!{escapetool.xml($targetDocument.fullName)}" />
    <input type="hidden" name="classname" value="$!{escapetool.xml($options.get('classname'))}" />
    <input type="hidden" name="object" value="$!{escapetool.xml($options.get('object'))}" />
    <input type="hidden" name="property" value="$!{escapetool.xml($options.get('property'))}" />
    <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" />

  #if ("$!currentValue" != '' && $currentValue != $options.defaultValue)

        <input type="checkbox" name="filename" value="$!escapetool.xml($currentValue)"
          />$services.localization.render('attachmentSelector.replace',
          ["$!escapetool.xml($currentValue)"])

      $escapetool.xml($services.localization.render('attachmentSelector.replace.hint'))

  #end
  #if ($xwiki.hasEditComment() && $options.versionSummary)

    #if ($xwiki.isEditCommentFieldHidden())
      <input type="hidden" name="comment" value="$!escapetool.xml($request.comment)" />
    #else
      $services.localization.render('core.comment')
      <input type="text" name="comment" id="commentinput" value="$!escapetool.xml($request.comment)"
        title="$services.localization.render('core.comment.tooltip')" />
    #end

  #end

    <input type="submit" name="action_upload" class="button " value='$services.localization.render("${translationPrefix}.upload.submit")'  title='$services.localization.render("${translationPrefix}.upload.submit")'/>

</form>
{{/html}}
#attachmentPicker_displayEndFrame ([])
#end

#**
 * Displays the "empty value" box, used for unsetting the field value.
 *
 * @param $targetDocument the document being modified
 * @param $targetAttachDocument the document that the attachments will the loaded from/saved to
 * @param $options generic picker options
 * @param $currentValue the currently selected file, used for determining if the empty box should be highlighted as the current value
 *#
#macro (attachmentPicker_displayAttachmentGalleryEmptyValue $targetDocument, $targetAttachDocument, $options, $currentValue)
  #if ("$!{options.get('defaultValue')}" != '')
    #set ($reference = ${options.get('defaultValue')})
    #set ($docNameLimit = $reference.indexOf('@'))
    #if ($docNameLimit > 0)
      #set ($docName = $reference.substring(0, $docNameLimit))
    #else
      #set ($docName = $targetAttachDocument.fullName)
    #end
    #set ($attachmentName = $reference.substring($mathtool.add($docNameLimit, 1)))
    #set ($defaultAttachment = $xwiki.getDocument($docName).getAttachment($attachmentName))
    #if ($defaultAttachment.isImage())
      #set($dcssClass = 'gallery_image')
    #end
  #end
  #attachmentPicker_displayStartFrame({'cssClass' : "gallery_emptyChoice $!{dcssClass}", 'text' : $services.localization.render("${translationPrefix}.default"), 'value' : "${options.defaultValue}"} $currentValue)
  #attachmentPicker_displayAttachmentDetails($defaultAttachment $options)
  #set ($returnURL = $escapetool.url($doc.getURL('view', $request.queryString)))
  #set ($selectURL = $targetDocument.getURL(${options.get('docAction')}, "${options.get('classname')}_${options.get('object')}_${options.get('property')}=&form_token=$!{services.csrf.getToken()}"))
  #attachmentPicker_displayEndFrame ([{'name' : 'select', 'url' : $selectURL}])
#end
{{/velocity}}

{{velocity}}
#if ($request.docname)
  #set ($targetDocument = $xwiki.getDocument($request.docname))
  #if ($request.targetdocname)
    ## Use the target document if it exists.
    #set ($targetAttachDocument = $xwiki.getDocument($request.targetdocname))
  #else
    ## Otherwise, just use the current document as the target to save/load attachments
    #set ($targetAttachDocument = $targetDocument)
  #end
  #if ("$!{request.savemode}" == 'direct')
    #set($docAction = 'save')
  #else
    #set($docAction = $targetAttachDocument.getDefaultEditMode())
  #end
  #set ($filter = [])
  #set ($rawfilter = '')
  #if ("$!{request.filter}" != '')
    #foreach ($value in $request.filter.trim().split('\s*+[,|; ]\s*+'))
      #if ("$!value" != '')
        #set ($discard = $filter.add($value.toLowerCase()))
        #set ($rawfilter = "${rawfilter}, ${value}")
      #end
    #end
    #if ($rawfilter != '')
      #set ($rawfilter = $rawfilter.substring(2))
    #end
  #end
  #if ("$!{request.displayImage}" == 'true')
    #set ($displayImage = true)
  #else
    #set ($displayImage = false)
  #end
  ### Determine attachment sorting
  #set($sortAttachmentsBy = "$!{request.sortAttachmentsBy}")
  #set ($validAttachmentProperties = ['filename', 'date', 'filesize', 'author', 'version', 'mimeType'])
  #if($sortAttachmentsBy == '' || $validAttachmentProperties.indexOf($sortAttachmentsBy) == -1)
    ### Default to sorting by filename, sort not requested.
    #set($sortAttachmentsBy = "filename")
  #end
  ### Set attachment sorting direction
  #if($sortAttachmentsBy == 'date')
    ### Sort the date descending
    #set($sortAttachmentsBy = "date:desc")
  #else
    ### Sort everything else ascending
    #set($sortAttachmentsBy = "${sortAttachmentsBy}:asc")
  #end
  #set ($options = {
    'classname' : ${request.get('classname')},
    'object' : $!{numbertool.toNumber($request.object).intValue()},
    'property' : ${request.property},
    'displayImage' : ${displayImage},
    'docAction' : ${docAction},
    'defaultValue' : "$!{request.defaultValue}",
    'rawfilter': "$!{rawfilter}",
    'filter': ${filter},
    'sortAttachmentsBy': ${sortAttachmentsBy},
    'versionSummary': $request.versionSummary.equals('true')
  })
  $!targetDocument.use($targetDocument.getObject($options.classname, $options.object))##
  #attachmentPicker_displayAttachmentGallery($targetDocument, $targetAttachDocument, $options)

  #set ($cancelLinkName = $services.rendering.escape($services.rendering.escape($services.localization.render("${translationPrefix}.cancel"), 'xwiki/2.1'), 'xwiki/2.1'))
  #set ($cancelLinkTarget = $services.rendering.escape($services.model.serialize($targetDocument), 'xwiki/2.1'))
  (% class="gallery_buttons buttons" %)(((
  (% class="buttonwrapper secondary" %)[[$cancelLinkName>>$cancelLinkTarget||class="button secondary" id="attachment-picker-close"]]
  )))
#end
{{/velocity}}</content>
  <object>
    <name>XWiki.AttachmentSelector</name>
    <number>0</number>
    <className>XWiki.JavaScriptExtension</className>
    <guid>caa5337b-fad4-4c21-8ef4-9e7e1c44dbfe</guid>
    <class>
      <name>XWiki.JavaScriptExtension</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <cache>
        <cache>0</cache>
        <defaultValue>long</defaultValue>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>cache</name>
        <number>5</number>
        <prettyName>Caching policy</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators>|, </separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values>long|short|default|forbid</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </cache>

        <contenttype>PureText</contenttype>
        <disabled>0</disabled>
        <editor>PureText</editor>
        <name>code</name>
        <number>2</number>
        <prettyName>Code</prettyName>
        <rows>20</rows>
        <size>50</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>

      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <parse>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>parse</name>
        <number>4</number>
        <prettyName>Parse content</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </parse>
      <use>
        <cache>0</cache>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>use</name>
        <number>3</number>
        <prettyName>Use this extension</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators>|, </separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values>currentPage|onDemand|always</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </use>
    </class>
    <property>
      <cache>long</cache>
    </property>
    <property>
      var XWiki = (function(XWiki) {
  function uploadTemporaryAttachment() {
    // Require jquery locally until we are able to fully migrate this code away from prototype.
    const form = this.property.up('form');
    require(['jquery'], function ($) {
      const data = new FormData();
      const uploadedFile = $('#attachfile')[0].files[0];
      const filenameCheckbox = $("#uploadAttachment input[name='filename']");

      // TODO: Fix replace currently selected checkbox (see XWIKI-20181).
      data.append('upload', uploadedFile);
      const notification = new XWiki.widgets.Notification(
        "$services.localization.render('xe.attachmentSelector.upload.inProgress')", 'inprogress');
      const params = {
        'form_token': $(form).find('[name="form_token"]').val(),
        'sheet': 'CKEditor.FileUploader',
        'outputSyntax': 'plain'
      };

      // Update the name of the file with the name of the currently selected attachment if required.
      if (filenameCheckbox.prop('checked')) {
        params['filename'] = filenameCheckbox.val()
      }

      $.ajax({
        'url': XWiki.currentDocument.getURL('get', new URLSearchParams(params).toString()),
        method: 'POST',
        data: data,
        processData: false,
        contentType: false, // Sets the 'multipart/form-data' automatically
        headers: {
          'X-XWiki-Temporary-Attachment-Support': true
        }
      }).done(function (response) {
        #set ($successMessage = $escapetool.javascript($services.localization.render('attachment.attachmentSelector.temporaryUpload.success')))
        notification.replace(new XWiki.widgets.Notification("$successMessage", 'done'));
        // Add a field with the name of the uploaded file so that it is moved from the temporary
        // attachments to the persisded ones on save.
        $(form).append($('<input/>')
          .prop('type', 'hidden')
          .prop('name', 'uploadedFiles')
          .prop('value', response.fileName))
        $(form).find('input[type="hidden"].property-reference').prop('value', response.fileName);
        this.updateAttachment(response.fileName, response.url);
        this.dialog.closeDialog();
      }.bind(this)).fail(function  () {
        #set ($errorMessage = $escapetool.javascript($services.localization.render('attachment.attachmentSelector.temporaryUpload.failure')))notification.replace(new XWiki.widgets.Notification("$errorMessage", 'error'));
      });
    }.bind(this));
  }

  function directUploadAttachment(uploadForm) {
    // FIXME This fails in HTML5, will deal with it later:
    // this.property.down('input').value = uploadForm.down('input[type="file"]').value;
    // uploadForm.xredirect.value = window.location.pathname;
    document.observe('xwiki:document:saved', function () {
      new XWiki.widgets.Notification("$services.localization.render('xe.attachmentSelector.upload.inProgress')",
        'inprogress');
      uploadForm.submit();
    })
    document.fire('xwiki:actions:save', {'continue': true, form: this.property.up('form')});
  }

  /** Handles the gallery buttons directly in the current page without reloading the window. */
  XWiki.AttachmentPicker = Class.create({
    /**
     * Constructor.
     *
     * @param property the property being edited, as the containing div with class="attachment-picker"
     * @param dialog the modal dialog where the gallery was loaded
     */
    initialize : function(property, dialog) {
      this.property = property;
      this.dialog = dialog;
      this.gallery = dialog.dialogBox;
      if (!this.property.down('input')) {
        this.directSave = true;
      }
      this.defaultValue = '';
      var defaultValueElement = this.gallery.down('.gallery_emptyChoice .gallery_attachmenttitle');
      if (defaultValueElement) {
        this.defaultValue = defaultValueElement.title;
      }
      this.defaultImageSource = '';
      var defaultImage = this.gallery.down('.gallery_emptyChoice.gallery_image img');
      if (defaultImage) {
        this.defaultImageSource = defaultImage.src.replace(/\?.*$/, '');
      }
      this.filterFormUpload();
      this.addDeleteListeners();
      this.addSelectListeners();
      this.updateCurrentSelection();
      this.addCloseListener();
      var img = this.property.down('img');
      if (img) {
        img.observe('load', function() {img.up('div').removeClassName('hidden');});
        img.observe('error', function() {img.up('div').addClassName('hidden');});
      }
    },
    /**
     * Catches the upload form submission and stops it if the selected file is not of the accepted types (or not selected at all),
     * and saves the underlying form (if any) so that any unsaved changes won't be lost.
     */
    filterFormUpload : function() {
      this.gallery.select('.uploadAttachment input[type="file"]').each(function(fileInput) {
        fileInput.__allowedExtensions = fileInput.title.toLowerCase().replace(/\s*[,|; ]\s*/g, " ").strip();
        if (fileInput.__allowedExtensions != '') {
          fileInput.__allowedExtensions = fileInput.__allowedExtensions.split(" ");
        } else {
          fileInput.__allowedExtensions = false;
        }
      });
      this.gallery.select(".uploadAttachment").invoke('observe', 'submit', function(event) {
        event.stop();
        var uploadForm = event.element();
        var hasErrors = false;
        uploadForm.select('input[type="file"]').each(function(fileInput) {
          if (fileInput.value == '') {
            new XWiki.widgets.Notification("$services.localization.render('xe.attachmentSelector.upload.error.noFile')", 'error');
            hasErrors = true;
          } else if (fileInput.__allowedExtensions && fileInput.__allowedExtensions.indexOf(this.getFileExtension(fileInput.value)) == -1) {
            new XWiki.widgets.Notification("$services.localization.render('xe.attachmentSelector.upload.error.badExtension')", 'error');
            hasErrors = true;
          }
          const beforeUploadEvent = Event.fire(document, 'xwiki:actions:beforeUpload', {
            file: fileInput
          });

          if (beforeUploadEvent.defaultPrevented) {
            hasErrors = true;
          }
        }.bind(this));
        if (!hasErrors) {
          if (this.directSave) {
            uploadForm.submit();
          } else {
            if ("$!services.temporaryAttachments" != '') {
              uploadTemporaryAttachment.call(this);
            } else {
              directUploadAttachment.call(this, uploadForm);
            }
          }
        }
      }.bindAsEventListener(this));
    },
    getFileExtension : function(filename) {
      var fpath = filename.replace('\\', '/');
      var pieces = fpath.split('/');
      if (pieces.length == 0) {
        return null;
      }
      var basename = pieces[pieces.length-1];
      pieces = basename.split('.');
      return pieces[pieces.length-1].toLowerCase();
    },

    /** Catch attachment delete requests. */
    addDeleteListeners : function() {
      this.gallery.select('.gallery_actions .tool.delete').invoke('observe', 'click', this.onDelete.bindAsEventListener(this));
    },

    /** Catch attachment selection requests. */
    addSelectListeners : function() {
      this.gallery.select('.gallery_actions .tool.select').invoke('observe', 'click', this.onSelect.bindAsEventListener(this));
    },

    /** AJAX deletion of attachments. */
    onDelete : function(event) {
      event.stop();
      deleteTool = event.element();
      if (!deleteTool.disabled) {
        new XWiki.widgets.ConfirmedAjaxRequest(
          deleteTool.readAttribute('href'),
          {
            onCreate : function() { deleteTool.disabled = true },
            onSuccess : function() {
              var attachmentBox = deleteTool.up('.gallery_attachmentbox');
              if (attachmentBox) {
                if (attachmentBox.hasClassName('current')) {
                   this.updateAttachment(this.defaultValue, this.defaultImageSource);
                   if (this.gallery.down('.gallery_emptyChoice')) {
                     this.gallery.down('.gallery_emptyChoice').addClassName('current');
                   }
                   // Disable the replace feature because there's no selection.
                   var fileNameInput = this.gallery.down('input[type="checkbox"][name="filename"]');
                   fileNameInput.disabled = true;
                   // Empty the displayed selected file name.
                   fileNameInput.up('label').down('strong').update('');
                   if (!this.directSave) {
                     this.property.down('input').value = this.defaultValue;
                   }
                }
                attachmentBox.remove();
              }
            }.bind(this),
            onComplete : function() {
              deleteTool.disabled = false;
            }
          },
          {
            confirmationText: "$services.localization.render('core.viewers.attachments.delete.confirm')",
            progressMessageText : "$services.localization.render('core.viewers.attachments.delete.inProgress')",
            successMessageText : "$services.localization.render('core.viewers.attachments.delete.done')",
            failureMessageText : "$services.localization.render('core.viewers.attachments.delete.failed')"
          }
        );
      }
    },

    /** Update the property with the selected value without reloading the page. */
    onSelect : function(event) {
      event.stop();
      var targetElement = event.element();
      var attachmentName = targetElement.up('.gallery_attachmentbox').down('.gallery_attachmenttitle').title;
      var imageSource = targetElement.up('.gallery_attachmentbox.gallery_image');
      if (imageSource) {
        imageSource = imageSource.down('.gallery_attachmentframe img');
        if (imageSource) {
          imageSource = imageSource.src.replace(/\?.*$/, '');
        }
      }
      if (!imageSource) {
        imageSource = '';
      }
      if (this.directSave) {
        // save via ajax
        if (!targetElement.disabled) {
          new Ajax.Request(event.element().href, {
            onCreate : function() {
              targetElement.disabled = true;
              targetElement._x_notif = new XWiki.widgets.Notification("$services.localization.render('core.widgets.confirmationBox.notification.inProgress')", 'inprogress');
            },
            onSuccess : function () {
              targetElement._x_notif.hide();
              // on success, update image
              this.updateAttachment(attachmentName, imageSource);
              this.dialog.closeDialog();
            }.bindAsEventListener(this),
            onFailure : function(response) {
              var failureReason = response.statusText || 'Server not responding';
              if (targetElement._x_notif) {
                targetElement._x_notif.replace(new XWiki.widgets.Notification("$services.localization.render('core.widgets.confirmationBox.notification.failed')" + failureReason, "error"));
              } else {
                new XWiki.widgets.Notification(this.interactionParameters.failureMessageText + failureReason, "error");
              }
            },
            on0 : function(response) {
              response.request.options.onFailure(response);
            },
            onComplete : function() {
              targetElement.disabled = false;
            }
          });
        }
      } else {
        this.updateAttachment(attachmentName, imageSource);
        this.property.down('input').value = attachmentName;
        this.dialog.closeDialog();
      }
    },

    /** Update the property display. */
    updateAttachment : function(attachmentName, imageSource) {
      var img = this.property.down('img');
      if (img) {
        img.src = img.src.replace(/^[^\?]+($|\?)/, imageSource + "$1");
        var link = img.up('a');
        if (link) {
          link.href = link.href.replace(/^[^\?]+($|\?)/, imageSource + "$1");
        }
      } else {
        var displayed = this.property.down('.displayed');
        if (displayed) {
          displayed.update(attachmentName);
          var link = displayed.up('a');
          if (link) {
            link.href = link.href.replace(/^[^\?]+($|\?)/, attachmentName + "$1");
          }
        }
      }
    },

    /** Update the gallery to reflect the currently selected value. */
    updateCurrentSelection : function() {
      if (!this.directSave) {
        var selectedName =  this.property.down('input').value;
        var selectedElement = this.gallery.down('.gallery_attachmenttitle[title="' + selectedName.replace('"', '\\22 ') + '"]');
        if (selectedElement) {
          selectedElement = selectedElement.up('.gallery_attachmentbox');
        } else {
          selectedElement = this.gallery.down('.gallery_emptyChoice');
        }
        if (!selectedElement.hasClassName('current')) {
          this.gallery.select('.gallery_attachmentbox.current .tool.select').invoke('removeClassName', 'hidden');
          this.gallery.select('.gallery_attachmentbox.current').invoke('removeClassName', 'current');
          selectedElement.addClassName('current');
        }
        selectedElement.down('.tool.select').addClassName('hidden');
      } else {
        this.gallery.down('.current .tool.select').addClassName('hidden');
      }
    },
    addCloseListener : function () {
      var closeButton = $('attachment-picker-close');
      if (closeButton) {
        closeButton.observe('click', function(event) {
          event.stop();
          this.dialog.closeDialog();
        }.bindAsEventListener(this));
      }
    }
  });

  var loading = new Element('div', {'class' : 'imgcenter'}).update("");
  var dialog;

  /* Hook onto the picker buttons so that the gallery is loaded via AJAX in a modal dialog. */
  document.observe('xwiki:dom:loaded', function() {
    $$('.attachment-picker-start').invoke('observe', 'click', function(event) {
      event.stop();
      var targetElement = event.element();
      var url = targetElement.href;
      if (url.indexOf('?') < 0) {
        url += '?';
      }
      url += "&xpage=plain";
      dialog = new XWiki.widgets.ModalPopup(
        loading, {}, {
          'verticalPosition' : 'top',
          'removeOnClose' : true,
          'title' : "$services.localization.render('xe.attachmentSelector.gallery.title')"
        }
      );
      dialog.shortcuts.close.keys = [];
      dialog.showDialog();
      dialog.dialog.down().setStyle({position: "fixed"});
      dialog.dialog.setStyle({top: document.viewport.getScrollOffsets().top + "px", position: "absolute"});
      dialog.dialogBox.setStyle({overflow: "hidden", width: "80%", margin: "0 10%"});
      new Ajax.Updater(loading.up(), url, {
        onComplete : function() {
          // Play nice with the Lightbox widget
          if (window.gallery_lb) {
            window.gallery_lb.updateImageList();
          }
          // Manually convert the special rel values into target attributes for the newly inserted content (rel="_something" => target="something")
          if (typeof (XWiki.fixLinksTargetAttribute) == 'function') {
            // Trick the function into updating link targets in edit mode; normally the conversion only takes place in view mode
            var __tmp = XWiki.contextaction;
            XWiki.contextaction = 'view';
            XWiki.fixLinksTargetAttribute(dialog.dialog);
            XWiki.contextaction = __tmp;
          }
          new XWiki.AttachmentPicker(targetElement.up('.attachment-picker'), dialog);
        }
      });
    });
  });
  return XWiki;
}(XWiki || {}));
    </property>
    <property>
      <name>Loads the image picker in a modal dialog</name>
    </property>
    <property>
      <parse>1</parse>
    </property>
    <property>
      <use>currentPage</use>
    </property>
  </object>
  <object>
    <name>XWiki.AttachmentSelector</name>
    <number>1</number>
    <className>XWiki.JavaScriptExtension</className>
    <guid>2aa565e6-b9bd-4095-a7a9-bbf47d75d079</guid>
    <class>
      <name>XWiki.JavaScriptExtension</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <cache>
        <cache>0</cache>
        <defaultValue>long</defaultValue>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>cache</name>
        <number>5</number>
        <prettyName>Caching policy</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators>|, </separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values>long|short|default|forbid</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </cache>

        <contenttype>PureText</contenttype>
        <disabled>0</disabled>
        <editor>PureText</editor>
        <name>code</name>
        <number>2</number>
        <prettyName>Code</prettyName>
        <rows>20</rows>
        <size>50</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>

      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <parse>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>parse</name>
        <number>4</number>
        <prettyName>Parse content</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </parse>
      <use>
        <cache>0</cache>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>use</name>
        <number>3</number>
        <prettyName>Use this extension</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators>|, </separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values>currentPage|onDemand|always</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </use>
    </class>
    <property>
      <cache>long</cache>
    </property>
    <property>
      XWiki.widgets.ModalPopup.prototype.showDialog = function(event) {
  if (event) {
    Event.stop(event);
  }
  // Only do this if the dialog is not already active.
  if (!this.active) {
    this.active = true;
    if (!this.dialog) {
      // The dialog wasn't loaded, create it.
      this.createDialog();
    }
    // Start listening to keyboard events
    this.attachKeyListeners();
    // Display the dialog
    this.dialog.show();
  }
};
XWiki.widgets.ModalPopup.prototype.closeDialog = function(event) {
  if (event) {
    Event.stop(event);
  }
  // Call optional callback
  this.options.onClose.call(this);
  // Hide the dialog, without removing it from the DOM.
  this.dialog.hide();
  if (this.options.removeOnClose) {
    this.dialog.remove();
  }
  // Stop the UI shortcuts (except the initial Show Dialog one).
  this.detachKeyListeners();
  // Re-enable the 'show' behavior.
  this.active = false;
}

    </property>
    <property>
      <name>Patch for modalPopup.js, allowing to display several widgets on the same screen and removing position:fixed in IE</name>
    </property>
    <property>
      <parse>0</parse>
    </property>
    <property>
      <use>currentPage</use>
    </property>
  </object>
  <object>
    <name>XWiki.AttachmentSelector</name>
    <number>0</number>
    <className>XWiki.StyleSheetExtension</className>
    <guid>2a28ce9c-ab00-4847-936d-53e4f2acbfe0</guid>
    <class>
      <name>XWiki.StyleSheetExtension</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <cache>
        <cache>0</cache>
        <defaultValue>long</defaultValue>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>cache</name>
        <number>5</number>
        <prettyName>Caching policy</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators>|, </separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values>long|short|default|forbid</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </cache>

        <contenttype>PureText</contenttype>
        <disabled>0</disabled>
        <editor>PureText</editor>
        <name>code</name>
        <number>2</number>
        <prettyName>Code</prettyName>
        <rows>20</rows>
        <size>50</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>

      <contentType>
        <cache>0</cache>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>contentType</name>
        <number>6</number>
        <prettyName>Content Type</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators>|, </separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values>CSS|LESS</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </contentType>
      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <parse>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>parse</name>
        <number>4</number>
        <prettyName>Parse content</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </parse>
      <use>
        <cache>0</cache>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>use</name>
        <number>3</number>
        <prettyName>Use this extension</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators>|, </separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values>currentPage|onDemand|always</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </use>
    </class>
    <property>
      <cache>long</cache>
    </property>
    <property>
      #template("colorThemeInit.vm")
#set ($boxSize = 170)
#set ($boxPadding = 5)
#set ($boxMargin = 5)
## Make the upload box two times as wide, so that the input fits nicely.
## |                                                     |
## |                         |  |                        |
## | 1 width + 1 border + 2 margins + 1 border + 1 width |
#set ($uploadBoxSize = $mathtool.add(2, $mathtool.add($mathtool.mul($boxSize, 2), $mathtool.mul($boxMargin, 2))))
#set ($imgSize = $mathtool.sub($boxSize, $mathtool.mul($boxPadding, 2)))
#set ($actionsHeight = 20)
#set ($actionsWidth = 16)
/*--------------------------------------------------------*/
/* Attachment picker layout fixes                              */
.attachment-picker p {
  margin: 0;
  padding : 0;
}
.attachment-picker picture {
  max-width: 100%;
}
/*--------------------------------------------------------*/
/* Gallery attachmentboxes                                     */
.gallery p {
  margin: 0;
}
.gallery_attachmentbox {
  background: $theme.pageContentBackgroundColor;
  border: 1px solid $theme.borderColor;
  border-radius: 5px;
  float: left;
  margin: ${boxMargin}px;
  overflow: hidden;
  position: relative;
  width: ${boxSize}px;
}
.gallery .current {
  background-color: $theme.highlightColor;
  border-width: 3px;
  margin: 3px;
}
.gallery .current .gallery_attachmenttitle {
  font-weight: bold;
}
.gallery_attachmentbox:hover {
  background-color: $theme.highlightColor;
}

.gallery_attachmenttitle {
  background: $theme.backgroundSecondaryColor;
  border-bottom: 1px dotted $theme.borderColor;
  border-radius: 5px 5px 0px 0px;
  font-size: 85%;
  padding: 3px ${boxPadding}px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.gallery_attachmenttitle p {
  text-align: center;
  overflow: hidden;
}

.gallery_attachmentframe {
  padding: ${boxPadding}px;
  height: ${imgSize}px;
  overflow: hidden;
  position: relative;
}

.gallery_attachmentframe a {
  display: block;
  text-align: center;
}

.gallery_attachmentbox img {
  max-height: ${imgSize}px;
  max-width: ${imgSize}px;
  width: auto;
}
.gallery_attachmentframe ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
}
.gallery_attachmentframe li {
  margin: 0.5em 0 0.5em 20px;
  font-size: 0.8em;
}
.gallery_attachmentframe .mime {
  margin: 0 2px 0 -20px;
}
.gallery_attachmentframe .mime img {
  vertical-align: top;
}
.gallery_attachmentframe li .filename {
  display: inline-block;
  font-weight: bold;
  width: $mathtool.sub($imgSize, 22)px;
  word-wrap: break-word;
}

/* Actions */
.gallery_actions {
  width: auto;
  position: absolute;
  bottom: 0px;
  right: ${boxPadding}px;
}
.gallery_actions .tool {
  background: none no-repeat 50% transparent;
  cursor: pointer;
  display: block;
  float: left;
  height: ${actionsHeight}px;
  padding: 0 !important;
  overflow: hidden;
  text-indent: -1000em;
  opacity: 0.6;
  width: ${actionsWidth}px;
}
.gallery_actions .tool:hover {
  opacity: 1;
}
.gallery_actions .select {
  background-image: url("$xwiki.getSkinFile('icons/silk/tick.png')");
}
.gallery_actions .delete {
  background-image: url("$xwiki.getSkinFile('icons/silk/cross.png')");
}
.gallery_actions .view {
  background-image: url("$xwiki.getSkinFile('icons/silk/link.png')");
}
.gallery_actions .download {
  background-image: url("$xwiki.getSkinFile('icons/silk/arrow_down.png')");
}
/*--------------------------------------------------*/
/* Upload form                                      */
.gallery_upload {
  ## Make this box twice as large as the others
  width: ${uploadBoxSize}px;
}
.gallery_upload, .gallery_upload:hover {
  background-color: $theme.backgroundSecondaryColor;
}

.gallery_upload .gallery_attachmenttitle {
  background-position: 1px center;
  background-image: url("$xwiki.getSkinFile('icons/silk/bullet_add.png')");
  background-repeat: no-repeat;
  padding-left: 16px;
}
.gallery_upload .gallery_attachmentframe {
  height: auto;
}
.gallery_upload_input {
  margin-bottom: 10px;
}
.gallery_upload input[type="file"] {
  font-size: 86%;
  width: ${mathtool.sub($uploadBoxSize, $mathtool.mul($boxPadding, 2))}px;
}
.gallery_upload .buttonwrapper {
  margin: 0;
}
.gallery_upload .button,
.gallery_upload label {
  font-size: 86%;
}
.gallery_upload input[type="checkbox"] {
  vertical-align: text-bottom;
}
.gallery_upload label[for="commentinput"] {
  margin-top: 10px;
}

/* ------------------------------------ */
/* Buttons on top:                      */
.gallery_actions {
  top: 1px;
  right: 3px;
}
.gallery_attachmenttitle p {
  text-align: left;
  margin-right: ${mathtool.add($mathtool.mul(2, $actionsWidth), $boxPadding)}px;
}
/* ------------------------------------ */
/* Cancel button                        */
.gallery_buttons {
  clear: both;
  margin: ${boxMargin}px;
}
    </property>
    <property>
      <contentType/>
    </property>
    <property>
      <name>Attachment galery styling</name>
    </property>
    <property>
      <parse>1</parse>
    </property>
    <property>
      <use>onDemand</use>
    </property>
  </object>
  <object>
    <name>XWiki.AttachmentSelector</name>
    <number>0</number>
    <className>XWiki.WikiMacroClass</className>
    <guid>7f67fdfc-a67a-4166-b7c1-6d572ee54719</guid>
    <class>
      <name>XWiki.WikiMacroClass</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <async_cached>
        <defaultValue>0</defaultValue>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType/>
        <name>async_cached</name>
        <number>13</number>
        <prettyName>Cached</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </async_cached>
      <async_context>
        <cache>0</cache>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>1</multiSelect>
        <name>async_context</name>
        <number>14</number>
        <prettyName>Context elements</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator>, </separator>
        <separators>|, </separators>
        <size>5</size>
        <unmodifiable>0</unmodifiable>
        <values>action=Action|doc.reference=Document|icon.theme=Icon theme|locale=Language|rendering.defaultsyntax=Default syntax|rendering.restricted=Restricted|rendering.targetsyntax=Target syntax|request.base=Request base URL|request.cookies|request.parameters=Request parameters|request.url=Request URL|request.wiki=Request wiki|user=User|wiki=Wiki</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </async_context>
      <async_enabled>
        <defaultValue>0</defaultValue>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType/>
        <name>async_enabled</name>
        <number>12</number>
        <prettyName>Asynchronous rendering</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </async_enabled>

        <disabled>0</disabled>
        <editor>Text</editor>
        <name>code</name>
        <number>10</number>
        <prettyName>Macro code</prettyName>
        <rows>20</rows>
        <size>40</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>

      <contentDescription>
        <contenttype>PureText</contenttype>
        <disabled>0</disabled>
        <editor>PureText</editor>
        <name>contentDescription</name>
        <number>9</number>
        <prettyName>Content description (Not applicable for "No content" type)</prettyName>
        <rows>5</rows>
        <size>40</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
      </contentDescription>
      <contentJavaType>
        <cache>0</cache>
        <defaultValue>Unknown</defaultValue>
        <disabled>0</disabled>
        <displayType>input</displayType>
        <freeText>allowed</freeText>
        <largeStorage>1</largeStorage>
        <multiSelect>0</multiSelect>
        <name>contentJavaType</name>
        <number>8</number>
        <picker>1</picker>
        <prettyName>Macro content type</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator>|</separator>
        <separators>|</separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values>Unknown|Wiki</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </contentJavaType>
      <contentType>
        <cache>0</cache>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>contentType</name>
        <number>7</number>
        <prettyName>Macro content availability</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator>|</separator>
        <separators>|</separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values>Optional|Mandatory|No content</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </contentType>
      <defaultCategories>
        <cache>0</cache>
        <disabled>0</disabled>
        <displayType>input</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>1</multiSelect>
        <name>defaultCategories</name>
        <number>4</number>
        <prettyName>Default categories</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators>|, </separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values/>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </defaultCategories>
      <description>
        <contenttype>PureText</contenttype>
        <disabled>0</disabled>
        <editor>PureText</editor>
        <name>description</name>
        <number>3</number>
        <prettyName>Macro description</prettyName>
        <rows>5</rows>
        <size>40</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
      </description>
      <id>
        <disabled>0</disabled>
        <name>id</name>
        <number>1</number>
        <prettyName>Macro id</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </id>
      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>2</number>
        <prettyName>Macro name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <priority>
        <disabled>0</disabled>
        <name>priority</name>
        <number>11</number>
        <numberType>integer</numberType>
        <prettyName>Priority</prettyName>
        <size>10</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.NumberClass</classType>
      </priority>
      <supportsInlineMode>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>supportsInlineMode</name>
        <number>5</number>
        <prettyName>Supports inline mode</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </supportsInlineMode>
      <visibility>
        <cache>0</cache>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>visibility</name>
        <number>6</number>
        <prettyName>Macro visibility</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator>|</separator>
        <separators>|</separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values>Current User|Current Wiki|Global</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </visibility>
    </class>
    <property>
      <async_cached>0</async_cached>
    </property>
    <property>
      <async_context/>
    </property>
    <property>
      <async_enabled>0</async_enabled>
    </property>
    <property>
      {{velocity output="false"}}
$xwiki.jsfx.use('js/xwiki/widgets/modalPopup.js', true)##
$xwiki.ssfx.use('js/xwiki/widgets/modalPopup.css', true)##
$xwiki.jsx.use($xcontext.macro.doc.fullName)##
$xwiki.ssx.use($xcontext.macro.doc.fullName)##
## Integrates the optional Lightbox widget (from http://extensions.xwiki.org/xwiki/bin/view/Extension/Lightbox+Application )
#if ($xwiki.exists('XWiki.Lightbox'))
  $xwiki.jsx.use('XWiki.Lightbox')
  $xwiki.ssx.use('XWiki.Lightbox')
#end

##
## Prepare parameters
##
## Keep track for when we have a target document
#set ($hasTargetDoc = false)
#set ($targetdoc = "$!{xcontext.macro.params.targetdocname}")
###
## Set the targetdoc we want to save to (default to current doc if not set)
#if ("$!{targetdoc}" != '')
  ## Check access on targetdocname
  #set ($targetPermView = $xwiki.hasAccessLevel('view',$xcontext.user,${targetdoc}))
  #set ($targetPermEdit = $xwiki.hasAccessLevel('edit',$xcontext.user,${targetdoc}))
  #set ($targetdoc = $xwiki.getDocument($targetdoc) )
  #set ($hasTargetDoc = true)
#else
  ## The user should have edit and view permissions for the current doc
  #set ($targetPermView = true)
  #set ($targetPermEdit = true)
  #set($targetdoc = $doc)
#end
#set ($classname = "$!{xcontext.macro.params.classname}")
#set ($property = "$!{xcontext.macro.params.property}")
#set ($object = $numbertool.toNumber("$!{xcontext.macro.params.object}").intValue())
#if ("$!{object}" != $!{xcontext.macro.params.object})
  #set ($object = ${doc.getObject($classname).number})
  #if ("$!{object}" == '')
    #set ($object = 0)
  #end
#end

#if ("$!{xcontext.macro.params.displayImage}" == 'true' && $targetPermView)
  #set ($displayImage = true)
#else
  #set ($displayImage = false)
#end
#if ($displayImage)
  #set ($alt = '')
  #set ($width = '')
  #set ($height = '')
  #if ($xcontext.macro.params.alternateText)
    #set ($alt = "$services.rendering.escape($!{xcontext.macro.params.alternateText}, 'xwiki/2.1')")
  #end
  #if ($xcontext.macro.params.width)
    #set ($width = "$services.rendering.escape($!{xcontext.macro.params.width}, 'xwiki/2.1')")
  #end
  #if ($xcontext.macro.params.height)
    #set ($height = "$services.rendering.escape($!{xcontext.macro.params.height}, 'xwiki/2.1')")
  #end
  #set ($imageParams = '')
  #if ("${width}" != '')
    #set($imageParams = "$!{imageParams} width=${width}")
  #end
  #if ("${height}" != '')
    #set ($imageParams = "$!{imageParams} height=${height}")
  #end
  #set ($imageParams = "$!{imageParams} alt='${alt}'")
  #if ("$!{imageParams}" != '')
    #set ($imageParams = "||${imageParams.trim()}")
  #end
#end
#if ("$!{xcontext.macro.params.link}" == 'true')
  #set ($link = true)
#else
  #set ($link = false)
#end

#set ($cssClass = "displayed x-attachment $!{xcontext.macro.params.cssClass}")
#set ($defaultValue = "$!{xcontext.macro.params.defaultValue}")
#if ($defaultValue != '')
  #set ($defaultReference = $services.model.resolveAttachment($defaultValue))
#else
  #set ($defaultReference = false)
#end
#set ($filter = ${xcontext.macro.params.filter})

#set ($buttontext = "$!{xcontext.macro.params.buttontext}")
#if ($buttontext == '')
  #set ($buttontext = $services.localization.render('xe.attachmentSelector.selectFile'))
#end

#set ($savemode = "$!{xcontext.macro.params.savemode}")
#if ($savemode != 'direct')
  #set ($savemode = 'form')
#end

#set ($propValue = "$!{doc.getObject($classname, $object).getProperty($property).value}")
##

#macro (attachmentPicker_displayAttachment $name $displayImage $withLink $forceElement)
  #set ($attachment = $targetdoc.getAttachment("$!{name}"))
  #if ("$!{name}" != '' && "$!{attachment}" != '')
    #set ($attachmentRef = $services.model.createAttachmentReference(${targetdoc.documentReference}, ${name}))
    #set ($attachmentName = $name)
  #else
    #set ($attachmentRef = $defaultReference)
    #if ($attachmentRef)
      #set ($docReference = $attachmentRef.documentReference)
    #else
      #set ($docReference = $targetdoc.documentReference)
    #end
    #set ($attachmentName = $attachmentRef.name)
    #set ($attachment = $xwiki.getDocument($docReference).getAttachment($attachmentName))
    #if (!$attachment)
      #set ($withLink = false)
    #end
  #end
  #if ($attachmentRef)
    #set ($attachmentResource = $services.model.serialize($attachmentRef, 'local'))
  #else
    #set ($attachmentResource = '')
  #end
  #if ($displayImage)
    (% class="$!{cssClass}#if (!$attachment) hidden#end" %)(((#if ("$!{attachmentResource}" != '' || $forceElement)#if($withLink)[[#end[[image:$services.rendering.escape(${attachmentResource}, 'xwiki/2.1')$!{imageParams}]]#if($withLink)>>attach:$services.rendering.escape(${attachmentResource},'xwiki/2.1')||rel=lightbox]]#{end}#end)))##
  #else
    (% class="$!{cssClass}" %)#if ("$!{attachmentResource}" != '' || $forceElement)#if ($withLink)[[attach:${attachmentResource}||rel=__blank]]#{else}(% class="displayed" %)#if($targetPermView)$services.rendering.escape($!{attachmentName}, 'xwiki/2.1')#{else}Access Denied#{end}(% %)#{end}#end(%%)##
  #end
#end

## Display the "Choose an attachment" button if they can:
##  1. Edit the current page
##  2. View the target attachment page. (can be the same page)
#macro (attachmentPicker_displayButton)
  #if ($targetPermView)
    #set ($queryString = {
      'docname': $doc.fullName,
      'classname': $classname,
      'property': $property,
      'object': $object,
      'savemode': $savemode,
      'defaultValue': $defaultValue,
      'filter': $filter,
      'displayImage': $displayImage,
      'versionSummary': $xcontext.macro.params.versionSummary.equals('true')
    })
    #if ($hasTargetDoc)
      #set ($queryString.targetdocname = $targetdoc.fullName)
    #end
    #set ($linkLabel = $services.rendering.escape($services.rendering.escape($buttontext, 'xwiki/2.1'), 'xwiki/2.1'))
    (% class="buttonwrapper" %)[[$linkLabel>>${xcontext.macro.doc.fullName}||queryString="$escapetool.url($queryString)"
      class="attachment-picker-start button" title="$services.rendering.escape($buttontext, 'xwiki/2.1')"]](%%)##
  #end
#end
{{/velocity}}

{{velocity}}
#if ("${savemode}" == 'direct')
  (% class="attachment-picker" %)(((#attachmentPicker_displayAttachment($propValue $displayImage $link true) #attachmentPicker_displayButton())))
#elseif ($xcontext.action == 'inline' || $xcontext.action == 'edit')
  (% class="attachment-picker" %)(((##
    #attachmentPicker_displayAttachment($propValue $displayImage false true) #attachmentPicker_displayButton()##
    {{html}}<input type="hidden" name="${classname}_${object}_${property}" value="${propValue}" class="property-reference"/>{{/html}}##
  )))
#else
  #attachmentPicker_displayAttachment($propValue $displayImage $link false)
#end
{{/velocity}}
    </property>
    <property>
      <contentDescription/>
    </property>
    <property>
      <contentJavaType/>
    </property>
    <property>
      <contentType>No content</contentType>
    </property>
    <property>
      <defaultCategories>
        <value>Development</value>
      </defaultCategories>
    </property>
    <property>
      <description>A control to be used for object properties of the current document that are supposed to contain the name of an attachment from the current (or target) document. Allows uploading new attachments, and deleting attachments from the target document.  If no target document is specified, the current document will be used. Object properties are only saved to the current document.</description>
    </property>
    <property>
      <id>attachmentSelector</id>
    </property>
    <property>
      <name>Attachment Selector</name>
    </property>
    <property>
      <priority/>
    </property>
    <property>
      <supportsInlineMode>1</supportsInlineMode>
    </property>
    <property>
      <visibility>Current Wiki</visibility>
    </property>
  </object>
  <object>
    <name>XWiki.AttachmentSelector</name>
    <number>0</number>
    <className>XWiki.WikiMacroParameterClass</className>
    <guid>bb1b9208-3b4a-43e4-8a69-603281ca1412</guid>
    <class>
      <name>XWiki.WikiMacroParameterClass</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <defaultValue>
        <disabled>0</disabled>
        <name>defaultValue</name>
        <number>4</number>
        <prettyName>Parameter default value</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </defaultValue>
      <description>
        <disabled>0</disabled>
        <name>description</name>
        <number>2</number>
        <prettyName>Parameter description</prettyName>
        <rows>5</rows>
        <size>40</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
      </description>
      <mandatory>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>mandatory</name>
        <number>3</number>
        <prettyName>Parameter mandatory</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </mandatory>
      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Parameter name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <type>
        <disabled>0</disabled>
        <name>type</name>
        <number>5</number>
        <prettyName>Parameter type</prettyName>
        <size>60</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </type>
    </class>
    <property>
      <defaultValue/>
    </property>
    <property>
      <description>The full name of the document holding the XClass that contains the property associated with this picker. </description>
    </property>
    <property>
      <mandatory>1</mandatory>
    </property>
    <property>
      <name>classname</name>
    </property>
    <property>
      <type>org.xwiki.model.reference.DocumentReference</type>
    </property>
  </object>
  <object>
    <name>XWiki.AttachmentSelector</name>
    <number>1</number>
    <className>XWiki.WikiMacroParameterClass</className>
    <guid>c51517fc-93e9-4594-8b10-b014a8907452</guid>
    <class>
      <name>XWiki.WikiMacroParameterClass</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <defaultValue>
        <disabled>0</disabled>
        <name>defaultValue</name>
        <number>4</number>
        <prettyName>Parameter default value</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </defaultValue>
      <description>
        <disabled>0</disabled>
        <name>description</name>
        <number>2</number>
        <prettyName>Parameter description</prettyName>
        <rows>5</rows>
        <size>40</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
      </description>
      <mandatory>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>mandatory</name>
        <number>3</number>
        <prettyName>Parameter mandatory</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </mandatory>
      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Parameter name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <type>
        <disabled>0</disabled>
        <name>type</name>
        <number>5</number>
        <prettyName>Parameter type</prettyName>
        <size>60</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </type>
    </class>
    <property>
      <defaultValue/>
    </property>
    <property>
      <description>The name of the property associated with the picker.</description>
    </property>
    <property>
      <mandatory>1</mandatory>
    </property>
    <property>
      <name>property</name>
    </property>
    <property>
      <type/>
    </property>
  </object>
  <object>
    <name>XWiki.AttachmentSelector</name>
    <number>2</number>
    <className>XWiki.WikiMacroParameterClass</className>
    <guid>b43c2df7-9941-4941-834b-0236424cfaa9</guid>
    <class>
      <name>XWiki.WikiMacroParameterClass</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <defaultValue>
        <disabled>0</disabled>
        <name>defaultValue</name>
        <number>4</number>
        <prettyName>Parameter default value</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </defaultValue>
      <description>
        <disabled>0</disabled>
        <name>description</name>
        <number>2</number>
        <prettyName>Parameter description</prettyName>
        <rows>5</rows>
        <size>40</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
      </description>
      <mandatory>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>mandatory</name>
        <number>3</number>
        <prettyName>Parameter mandatory</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </mandatory>
      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Parameter name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <type>
        <disabled>0</disabled>
        <name>type</name>
        <number>5</number>
        <prettyName>Parameter type</prettyName>
        <size>60</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </type>
    </class>
    <property>
      <defaultValue/>
    </property>
    <property>
      <description>The identifier (number) of the object for which the property is displayed by this picker. If missing, the first instance of the class given by the parameter classname found in the document will be considered.</description>
    </property>
    <property>
      <mandatory>0</mandatory>
    </property>
    <property>
      <name>object</name>
    </property>
    <property>
      <type/>
    </property>
  </object>
  <object>
    <name>XWiki.AttachmentSelector</name>
    <number>5</number>
    <className>XWiki.WikiMacroParameterClass</className>
    <guid>a35e6fcc-b5e9-4c49-a601-cead93cba813</guid>
    <class>
      <name>XWiki.WikiMacroParameterClass</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <defaultValue>
        <disabled>0</disabled>
        <name>defaultValue</name>
        <number>4</number>
        <prettyName>Parameter default value</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </defaultValue>
      <description>
        <disabled>0</disabled>
        <name>description</name>
        <number>2</number>
        <prettyName>Parameter description</prettyName>
        <rows>5</rows>
        <size>40</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
      </description>
      <mandatory>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>mandatory</name>
        <number>3</number>
        <prettyName>Parameter mandatory</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </mandatory>
      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Parameter name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <type>
        <disabled>0</disabled>
        <name>type</name>
        <number>5</number>
        <prettyName>Parameter type</prettyName>
        <size>60</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </type>
    </class>
    <property>
      <defaultValue/>
    </property>
    <property>
      <description>A CSS class for the element surrounding the property value.</description>
    </property>
    <property>
      <mandatory>0</mandatory>
    </property>
    <property>
      <name>cssClass</name>
    </property>
    <property>
      <type/>
    </property>
  </object>
  <object>
    <name>XWiki.AttachmentSelector</name>
    <number>6</number>
    <className>XWiki.WikiMacroParameterClass</className>
    <guid>2dcec651-66b9-4d7c-9ac6-2578a426a5f4</guid>
    <class>
      <name>XWiki.WikiMacroParameterClass</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <defaultValue>
        <disabled>0</disabled>
        <name>defaultValue</name>
        <number>4</number>
        <prettyName>Parameter default value</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </defaultValue>
      <description>
        <disabled>0</disabled>
        <name>description</name>
        <number>2</number>
        <prettyName>Parameter description</prettyName>
        <rows>5</rows>
        <size>40</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
      </description>
      <mandatory>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>mandatory</name>
        <number>3</number>
        <prettyName>Parameter mandatory</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </mandatory>
      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Parameter name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <type>
        <disabled>0</disabled>
        <name>type</name>
        <number>5</number>
        <prettyName>Parameter type</prettyName>
        <size>60</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </type>
    </class>
    <property>
      <defaultValue>form</defaultValue>
    </property>
    <property>
      <description>States how the property is updated. Accepted values: "form" (default)  meaning that the selected value is stored in an input that will be saved via an external form; "direct" meas that the picker is responsible with updating the property value.</description>
    </property>
    <property>
      <mandatory>0</mandatory>
    </property>
    <property>
      <name>savemode</name>
    </property>
    <property>
      <type/>
    </property>
  </object>
  <object>
    <name>XWiki.AttachmentSelector</name>
    <number>7</number>
    <className>XWiki.WikiMacroParameterClass</className>
    <guid>a932ece6-3c6d-48c7-a717-536317705f71</guid>
    <class>
      <name>XWiki.WikiMacroParameterClass</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <defaultValue>
        <disabled>0</disabled>
        <name>defaultValue</name>
        <number>4</number>
        <prettyName>Parameter default value</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </defaultValue>
      <description>
        <disabled>0</disabled>
        <name>description</name>
        <number>2</number>
        <prettyName>Parameter description</prettyName>
        <rows>5</rows>
        <size>40</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
      </description>
      <mandatory>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>mandatory</name>
        <number>3</number>
        <prettyName>Parameter mandatory</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </mandatory>
      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Parameter name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <type>
        <disabled>0</disabled>
        <name>type</name>
        <number>5</number>
        <prettyName>Parameter type</prettyName>
        <size>60</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </type>
    </class>
    <property>
      <defaultValue/>
    </property>
    <property>
      <description>Text of the button that triggers the picker. Defaults to $services.localization.render('xe.attachmentSelector.selectFile').</description>
    </property>
    <property>
      <mandatory>0</mandatory>
    </property>
    <property>
      <name>buttontext</name>
    </property>
    <property>
      <type/>
    </property>
  </object>
  <object>
    <name>XWiki.AttachmentSelector</name>
    <number>10</number>
    <className>XWiki.WikiMacroParameterClass</className>
    <guid>5c3f5b0d-1d0d-4820-8985-13d779972acb</guid>
    <class>
      <name>XWiki.WikiMacroParameterClass</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <defaultValue>
        <disabled>0</disabled>
        <name>defaultValue</name>
        <number>4</number>
        <prettyName>Parameter default value</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </defaultValue>
      <description>
        <disabled>0</disabled>
        <name>description</name>
        <number>2</number>
        <prettyName>Parameter description</prettyName>
        <rows>5</rows>
        <size>40</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
      </description>
      <mandatory>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>mandatory</name>
        <number>3</number>
        <prettyName>Parameter mandatory</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </mandatory>
      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Parameter name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <type>
        <disabled>0</disabled>
        <name>type</name>
        <number>5</number>
        <prettyName>Parameter type</prettyName>
        <size>60</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </type>
    </class>
    <property>
      <defaultValue/>
    </property>
    <property>
      <description>What attachment is displayed in view mode if the property is empty. Should either be empty or in the form of a wiki attachment reference (e.g. "attachment.txt", "Another.Document@attachment.txt").</description>
    </property>
    <property>
      <mandatory>0</mandatory>
    </property>
    <property>
      <name>defaultValue</name>
    </property>
    <property>
      <type>org.xwiki.model.reference.AttachmentReference</type>
    </property>
  </object>
  <object>
    <name>XWiki.AttachmentSelector</name>
    <number>12</number>
    <className>XWiki.WikiMacroParameterClass</className>
    <guid>aa252c40-59a0-4e82-a94b-e133862fe082</guid>
    <class>
      <name>XWiki.WikiMacroParameterClass</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <defaultValue>
        <disabled>0</disabled>
        <name>defaultValue</name>
        <number>4</number>
        <prettyName>Parameter default value</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </defaultValue>
      <description>
        <disabled>0</disabled>
        <name>description</name>
        <number>2</number>
        <prettyName>Parameter description</prettyName>
        <rows>5</rows>
        <size>40</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
      </description>
      <mandatory>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>mandatory</name>
        <number>3</number>
        <prettyName>Parameter mandatory</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </mandatory>
      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Parameter name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <type>
        <disabled>0</disabled>
        <name>type</name>
        <number>5</number>
        <prettyName>Parameter type</prettyName>
        <size>60</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </type>
    </class>
    <property>
      <defaultValue/>
    </property>
    <property>
      <description>Comma separated list of file extensions accepted by the property (to become a comma separated list of mimetypes when XWiki will use HTML5). All files are accepted if this parameter is empty.</description>
    </property>
    <property>
      <mandatory>0</mandatory>
    </property>
    <property>
      <name>filter</name>
    </property>
    <property>
      <type/>
    </property>
  </object>
  <object>
    <name>XWiki.AttachmentSelector</name>
    <number>13</number>
    <className>XWiki.WikiMacroParameterClass</className>
    <guid>e31c42de-47d7-4a73-a236-b99c2231dca7</guid>
    <class>
      <name>XWiki.WikiMacroParameterClass</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <defaultValue>
        <disabled>0</disabled>
        <name>defaultValue</name>
        <number>4</number>
        <prettyName>Parameter default value</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </defaultValue>
      <description>
        <disabled>0</disabled>
        <name>description</name>
        <number>2</number>
        <prettyName>Parameter description</prettyName>
        <rows>5</rows>
        <size>40</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
      </description>
      <mandatory>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>mandatory</name>
        <number>3</number>
        <prettyName>Parameter mandatory</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </mandatory>
      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Parameter name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <type>
        <disabled>0</disabled>
        <name>type</name>
        <number>5</number>
        <prettyName>Parameter type</prettyName>
        <size>60</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </type>
    </class>
    <property>
      <defaultValue>false</defaultValue>
    </property>
    <property>
      <description>States whether images are displayed or just their name is printed like for other attachments. Possible values: true, false (default).</description>
    </property>
    <property>
      <mandatory>0</mandatory>
    </property>
    <property>
      <name>displayImage</name>
    </property>
    <property>
      <type/>
    </property>
  </object>
  <object>
    <name>XWiki.AttachmentSelector</name>
    <number>14</number>
    <className>XWiki.WikiMacroParameterClass</className>
    <guid>0b2cea67-1942-4ce2-9f5e-90907033c92c</guid>
    <class>
      <name>XWiki.WikiMacroParameterClass</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <defaultValue>
        <disabled>0</disabled>
        <name>defaultValue</name>
        <number>4</number>
        <prettyName>Parameter default value</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </defaultValue>
      <description>
        <disabled>0</disabled>
        <name>description</name>
        <number>2</number>
        <prettyName>Parameter description</prettyName>
        <rows>5</rows>
        <size>40</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
      </description>
      <mandatory>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>mandatory</name>
        <number>3</number>
        <prettyName>Parameter mandatory</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </mandatory>
      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Parameter name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <type>
        <disabled>0</disabled>
        <name>type</name>
        <number>5</number>
        <prettyName>Parameter type</prettyName>
        <size>60</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </type>
    </class>
    <property>
      <defaultValue/>
    </property>
    <property>
      <description>The width of the displayed image, only taken into account if displayImage=true.</description>
    </property>
    <property>
      <mandatory>0</mandatory>
    </property>
    <property>
      <name>width</name>
    </property>
    <property>
      <type/>
    </property>
  </object>
  <object>
    <name>XWiki.AttachmentSelector</name>
    <number>15</number>
    <className>XWiki.WikiMacroParameterClass</className>
    <guid>003ab606-5c72-465d-bfd6-bd21262be502</guid>
    <class>
      <name>XWiki.WikiMacroParameterClass</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <defaultValue>
        <disabled>0</disabled>
        <name>defaultValue</name>
        <number>4</number>
        <prettyName>Parameter default value</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </defaultValue>
      <description>
        <disabled>0</disabled>
        <name>description</name>
        <number>2</number>
        <prettyName>Parameter description</prettyName>
        <rows>5</rows>
        <size>40</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
      </description>
      <mandatory>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>mandatory</name>
        <number>3</number>
        <prettyName>Parameter mandatory</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </mandatory>
      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Parameter name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <type>
        <disabled>0</disabled>
        <name>type</name>
        <number>5</number>
        <prettyName>Parameter type</prettyName>
        <size>60</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </type>
    </class>
    <property>
      <defaultValue/>
    </property>
    <property>
      <description>The height of the displayed image, only taken into account if displayImage=true</description>
    </property>
    <property>
      <mandatory>0</mandatory>
    </property>
    <property>
      <name>height</name>
    </property>
    <property>
      <type/>
    </property>
  </object>
  <object>
    <name>XWiki.AttachmentSelector</name>
    <number>16</number>
    <className>XWiki.WikiMacroParameterClass</className>
    <guid>9ca8402c-6df8-4068-b00f-1f9bb18f38a9</guid>
    <class>
      <name>XWiki.WikiMacroParameterClass</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <defaultValue>
        <disabled>0</disabled>
        <name>defaultValue</name>
        <number>4</number>
        <prettyName>Parameter default value</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </defaultValue>
      <description>
        <disabled>0</disabled>
        <name>description</name>
        <number>2</number>
        <prettyName>Parameter description</prettyName>
        <rows>5</rows>
        <size>40</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
      </description>
      <mandatory>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>mandatory</name>
        <number>3</number>
        <prettyName>Parameter mandatory</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </mandatory>
      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Parameter name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <type>
        <disabled>0</disabled>
        <name>type</name>
        <number>5</number>
        <prettyName>Parameter type</prettyName>
        <size>60</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </type>
    </class>
    <property>
      <defaultValue/>
    </property>
    <property>
      <description>The alternate text of the displayed image, only taken into account if displayImage=true</description>
    </property>
    <property>
      <mandatory>0</mandatory>
    </property>
    <property>
      <name>alternateText</name>
    </property>
    <property>
      <type/>
    </property>
  </object>
  <object>
    <name>XWiki.AttachmentSelector</name>
    <number>17</number>
    <className>XWiki.WikiMacroParameterClass</className>
    <guid>54e733cd-f755-4dee-8629-b713f685790a</guid>
    <class>
      <name>XWiki.WikiMacroParameterClass</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <defaultValue>
        <disabled>0</disabled>
        <name>defaultValue</name>
        <number>4</number>
        <prettyName>Parameter default value</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </defaultValue>
      <description>
        <disabled>0</disabled>
        <name>description</name>
        <number>2</number>
        <prettyName>Parameter description</prettyName>
        <rows>5</rows>
        <size>40</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
      </description>
      <mandatory>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>mandatory</name>
        <number>3</number>
        <prettyName>Parameter mandatory</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </mandatory>
      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Parameter name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <type>
        <disabled>0</disabled>
        <name>type</name>
        <number>5</number>
        <prettyName>Parameter type</prettyName>
        <size>60</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </type>
    </class>
    <property>
      <defaultValue>false</defaultValue>
    </property>
    <property>
      <description>States whether a link to the attachment is associated in view mode with the displayed attachment name/image. Possible values: true, false (default).</description>
    </property>
    <property>
      <mandatory>0</mandatory>
    </property>
    <property>
      <name>link</name>
    </property>
    <property>
      <type/>
    </property>
  </object>
  <object>
    <name>XWiki.AttachmentSelector</name>
    <number>18</number>
    <className>XWiki.WikiMacroParameterClass</className>
    <guid>99b73453-120c-481a-8889-1a7efc7b73f2</guid>
    <class>
      <name>XWiki.WikiMacroParameterClass</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <defaultValue>
        <disabled>0</disabled>
        <name>defaultValue</name>
        <number>4</number>
        <prettyName>Parameter default value</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </defaultValue>
      <description>
        <disabled>0</disabled>
        <name>description</name>
        <number>2</number>
        <prettyName>Parameter description</prettyName>
        <rows>5</rows>
        <size>40</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
      </description>
      <mandatory>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>mandatory</name>
        <number>3</number>
        <prettyName>Parameter mandatory</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </mandatory>
      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Parameter name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <type>
        <disabled>0</disabled>
        <name>type</name>
        <number>5</number>
        <prettyName>Parameter type</prettyName>
        <size>60</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </type>
    </class>
    <property>
      <defaultValue/>
    </property>
    <property>
      <description>The target document name to save/list attachments from</description>
    </property>
    <property>
      <mandatory>0</mandatory>
    </property>
    <property>
      <name>targetdocname</name>
    </property>
    <property>
      <type>org.xwiki.model.reference.DocumentReference</type>
    </property>
  </object>
  <object>
    <name>XWiki.AttachmentSelector</name>
    <number>19</number>
    <className>XWiki.WikiMacroParameterClass</className>
    <guid>8f5e90e1-5171-4519-b6e9-e11cc36529f1</guid>
    <class>
      <name>XWiki.WikiMacroParameterClass</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <defaultValue>
        <disabled>0</disabled>
        <name>defaultValue</name>
        <number>4</number>
        <prettyName>Parameter default value</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </defaultValue>
      <description>
        <disabled>0</disabled>
        <name>description</name>
        <number>2</number>
        <prettyName>Parameter description</prettyName>
        <rows>5</rows>
        <size>40</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
      </description>
      <mandatory>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>mandatory</name>
        <number>3</number>
        <prettyName>Parameter mandatory</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </mandatory>
      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Parameter name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <type>
        <disabled>0</disabled>
        <name>type</name>
        <number>5</number>
        <prettyName>Parameter type</prettyName>
        <size>60</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </type>
    </class>
    <property>
      <defaultValue>false</defaultValue>
    </property>
    <property>
      <description>Whether to allow the user to enter a version summary that will be recorded in the history. An automatic message is used when no version summary is provided or if the version summary input is not displayed.</description>
    </property>
    <property>
      <mandatory>0</mandatory>
    </property>
    <property>
      <name>versionSummary</name>
    </property>
    <property>
      <type/>
    </property>
  </object>
</xwikidoc>

Output:
【漏洞类型】XSS（跨站脚本攻击）
【严重性】Medium
【漏洞摘要】这是一个XSS漏洞。在原始代码中，`$fieldname` 和 `$comment` 变量在 `$response.sendRedirect` 方法中被直接插入到URL中，而没有进行适当的转义。这使得攻击者可以通过在输入中注入恶意脚本，从而在用户浏览器中执行任意代码。问题行在原始代码中是 `#set ($fieldname = $request.get('fieldname'))` 和 `#set ($comment = $services.localization.render("${translationPrefix}.postUpload.comment", [$fieldname]))`，以及在 `sendRedirect` 方法中使用这些变量。

【关键代码模式】与此漏洞相关的关键代码模式是直接使用用户输入（如 `$request.get('fieldname')`）在生成HTML或URL时，而没有进行适当的转义。关键词包括 `$request.get`、`$response.sendRedirect` 和 `$services.localization.render`。

【修复方法说明】修复方法通过使用 `$escapetool.xml` 对 `$fieldname` 和 `$comment` 进行转义，从而防止恶意输入被解释为HTML或JavaScript。