text:
..
  Normally, there are no heading levels assigned to certain characters as the structure is
  determined from the succession of headings. However, this convention is used in Python's
  Style Guide for documenting which you may follow:

  # with overline, for parts
  * for chapters
  = for sections
  - for subsections
  ^ for subsubsections
  " for paragraphs

##########
Backing up
##########

Now we're ready to backup some data. The contents of a directory at a
specific point in time is called a "snapshot" in restic. Run the
following command and enter the repository password you chose above
again:

.. code-block:: console

    $ restic -r /srv/restic-repo --verbose backup ~/work
    open repository
    enter password for repository:
    password is correct
    lock repository
    load index files
    start scan
    start backup
    scan finished in 1.837s
    processed 1.720 GiB in 0:12
    Files:        5307 new,     0 changed,     0 unmodified
    Dirs:         1867 new,     0 changed,     0 unmodified
    Added:      1.200 GiB
    snapshot 40dc1520 saved

As you can see, restic created a backup of the directory and was pretty
fast! The specific snapshot just created is identified by a sequence of
hexadecimal characters, ``40dc1520`` in this case.

You can see that restic tells us it processed 1.720 GiB of data, this is the
size of the files and directories in ``~/work`` on the local file system. It
also tells us that only 1.200 GiB was added to the repository. This means that
some of the data was duplicate and restic was able to efficiently reduce it.

If you don't pass the ``--verbose`` option, restic will print less data. You'll
still get a nice live status display. Be aware that the live status shows the
processed files and not the transferred data. Transferred volume might be lower
(due to de-duplication) or higher.

On Windows, the ``--use-fs-snapshot`` option will use Windows' Volume Shadow Copy
Service (VSS) when creating backups. Restic will transparently create a VSS
snapshot for each volume that contains files to backup. Files are read from the
VSS snapshot instead of the regular filesystem. This allows to backup files that are
exclusively locked by another process during the backup.

By default VSS ignores Outlook OST files. This is not a restriction of restic
but the default Windows VSS configuration. The files not to snapshot are
configured in the Windows registry under the following key:

.. code-block:: console

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\BackupRestore\FilesNotToSnapshot

For more details refer the official Windows documentation e.g. the article
``Registry Keys and Values for Backup and Restore``.

If you run the backup command again, restic will create another snapshot of
your data, but this time it's even faster and no new data was added to the
repository (since all data is already there). This is de-duplication at work!

.. code-block:: console

    $ restic -r /srv/restic-repo --verbose backup ~/work
    open repository
    enter password for repository:
    password is correct
    lock repository
    load index files
    using parent snapshot d875ae93
    start scan
    start backup
    scan finished in 1.881s
    processed 1.720 GiB in 0:03
    Files:           0 new,     0 changed,  5307 unmodified
    Dirs:            0 new,     0 changed,  1867 unmodified
    Added:      0 B
    snapshot 79766175 saved

You can even backup individual files in the same repository (not passing
``--verbose`` means less output):

.. code-block:: console

    $ restic -r /srv/restic-repo backup ~/work.txt
    enter password for repository:
    password is correct
    snapshot 249d0210 saved

If you're interested in what restic does, pass ``--verbose`` twice (or
``--verbose=2``) to display detailed information about each file and directory
restic encounters:

.. code-block:: console

    $ echo 'more data foo bar' >> ~/work.txt

    $ restic -r /srv/restic-repo --verbose --verbose backup ~/work.txt
    open repository
    enter password for repository:
    password is correct
    lock repository
    load index files
    using parent snapshot f3f8d56b
    start scan
    start backup
    scan finished in 2.115s
    modified  /home/user/work.txt, saved in 0.007s (22 B added)
    modified  /home/user/, saved in 0.008s (0 B added, 378 B metadata)
    modified  /home/, saved in 0.009s (0 B added, 375 B metadata)
    processed 22 B in 0:02
    Files:           0 new,     1 changed,     0 unmodified
    Dirs:            0 new,     2 changed,     0 unmodified
    Data Blobs:      1 new
    Tree Blobs:      3 new
    Added:      1.116 KiB
    snapshot 8dc503fc saved

In fact several hosts may use the same repository to backup directories
and files leading to a greater de-duplication.

Now is a good time to run ``restic check`` to verify that all data
is properly stored in the repository. You should run this command regularly
to make sure the internal structure of the repository is free of errors.

File change detection
*********************

When restic encounters a file that has already been backed up, whether in the
current backup or a previous one, it makes sure the file's contents are only
stored once in the repository. To do so, it normally has to scan the entire
contents of every file. Because this can be very expensive, restic also uses a
change detection rule based on file metadata to determine whether a file is
likely unchanged since a previous backup. If it is, the file is not scanned
again.

Change detection is only performed for regular files (not special files,
symlinks or directories) that have the exact same path as they did in a
previous backup of the same location.  If a file or one of its containing
directories was renamed, it is considered a different file and its entire
contents will be scanned again.

Metadata changes (permissions, ownership, etc.) are always included in the
backup, even if file contents are considered unchanged.

On **Unix** (including Linux and Mac), given that a file lives at the same
location as a file in a previous backup, the following file metadata
attributes have to match for its contents to be presumed unchanged:

 * Modification timestamp (mtime).
 * Metadata change timestamp (ctime).
 * File size.
 * Inode number (internal number used to reference a file in a filesystem).

The reason for requiring both mtime and ctime to match is that Unix programs
can freely change mtime (and some do). In such cases, a ctime change may be
the only hint that a file did change.

The following ``restic backup`` command line flags modify the change detection
rules:

 * ``--force``: turn off change detection and rescan all files.
 * ``--ignore-ctime``: require mtime to match, but allow ctime to differ.
 * ``--ignore-inode``: require mtime to match, but allow inode number
   and ctime to differ.

The option ``--ignore-inode`` exists to support FUSE-based filesystems and
pCloud, which do not assign stable inodes to files.

Note that the device id of the containing mount point is never taken into
account. Device numbers are not stable for removable devices and ZFS snapshots.
If you want to force a re-scan in such a case, you can change the mountpoint.

On **Windows**, a file is considered unchanged when its path, size
and modification time match, and only ``--force`` has any effect.
The other options are recognized but ignored.

Dry Runs
********

You can perform a backup in dry run mode to see what would happen without
modifying the repository.

-  ``--dry-run``/``-n`` Report what would be done, without writing to the repository

Combined with ``--verbose``, you can see a list of changes:

.. code-block:: console

    $ restic -r /srv/restic-repo backup ~/work --dry-run -vv | grep "added"
    modified  /plan.txt, saved in 0.000s (9.110 KiB added)
    modified  /archive.tar.gz, saved in 0.140s (25.542 MiB added)
    Would be added to the repository: 25.551 MiB

.. _backup-excluding-files:
Excluding Files
***************

You can exclude folders and files by specifying exclude patterns, currently
the exclude options are:

-  ``--exclude`` Specified one or more times to exclude one or more items
-  ``--iexclude`` Same as ``--exclude`` but ignores the case of paths
-  ``--exclude-caches`` Specified once to exclude folders containing `this special file <https://bford.info/cachedir/>`__
-  ``--exclude-file`` Specified one or more times to exclude items listed in a given file
-  ``--iexclude-file`` Same as ``exclude-file`` but ignores cases like in ``--iexclude``
-  ``--exclude-if-present foo`` Specified one or more times to exclude a folder's content if it contains a file called ``foo`` (optionally having a given header, no wildcards for the file name supported)
-  ``--exclude-larger-than size`` Specified once to excludes files larger than the given size

Please see ``restic help backup`` for more specific information about each exclude option.

Let's say we have a file called ``excludes.txt`` with the following content:

::

    # exclude go-files
    *.go
    # exclude foo/x/y/z/bar foo/x/bar foo/bar
    foo/**/bar

It can be used like this:

.. code-block:: console

    $ restic -r /srv/restic-repo backup ~/work --exclude="*.c" --exclude-file=excludes.txt

This instructs restic to exclude files matching the following criteria:

 * All files matching ``*.c`` (parameter ``--exclude``)
 * All files matching ``*.go`` (second line in ``excludes.txt``)
 * All files and sub-directories named ``bar`` which reside somewhere below a directory called ``foo`` (fourth line in ``excludes.txt``)

Patterns use `filepath.Glob <https://golang.org/pkg/path/filepath/#Glob>`__ internally,
see `filepath.Match <https://golang.org/pkg/path/filepath/#Match>`__ for
syntax. Patterns are tested against the full path of a file/dir to be saved,
even if restic is passed a relative path to save. Empty lines and lines
starting with a ``#`` are ignored.

Environment variables in exclude files are expanded with `os.ExpandEnv
<https://golang.org/pkg/os/#ExpandEnv>`__, so ``/home/$USER/foo`` will be
expanded to ``/home/bob/foo`` for the user ``bob``. To get a literal dollar
sign, write ``$$`` to the file - this has to be done even when there's no
matching environment variable for the word following a single ``$``. Note
that tilde (``~``) is not expanded, instead use the ``$HOME`` or equivalent
environment variable (depending on your operating system).

Patterns need to match on complete path components. For example, the pattern ``foo``:

 * matches ``/dir1/foo/dir2/file`` and ``/dir/foo``
 * does not match ``/dir/foobar`` or ``barfoo``

A trailing ``/`` is ignored, a leading ``/`` anchors the pattern at the root directory.
This means, ``/bin`` matches ``/bin/bash`` but does not match ``/usr/bin/restic``.

Regular wildcards cannot be used to match over the directory separator ``/``,
e.g. ``b*ash`` matches ``/bin/bash`` but does not match ``/bin/ash``. For this,
the special wildcard ``**`` can be used to match arbitrary sub-directories: The
pattern ``foo/**/bar`` matches:

 * ``/dir1/foo/dir2/bar/file``
 * ``/foo/bar/file``
 * ``/tmp/foo/bar``

Spaces in patterns listed in an exclude file can be specified verbatim. That is,
in order to exclude a file named ``foo bar star.txt``, put that just as it reads
on one line in the exclude file. Please note that beginning and trailing spaces
are trimmed - in order to match these, use e.g. a ``*`` at the beginning or end
of the filename.

Spaces in patterns listed in the other exclude options (e.g. ``--exclude`` on the
command line) are specified in different ways depending on the operating system
and/or shell. Restic itself does not need any escaping, but your shell may need
some escaping in order to pass the name/pattern as a single argument to restic.

On most Unixy shells, you can either quote or use backslashes. For example:

 * ``--exclude='foo bar star/foo.txt'``
 * ``--exclude="foo bar star/foo.txt"``
 * ``--exclude=foo\ bar\ star/foo.txt``

If a pattern starts with exclamation mark and matches a file that
was previously matched by a regular pattern, the match is cancelled.
It works similarly to ``gitignore``, with the same limitation: once a
directory is excluded, it is not possible to include files inside the
directory. Here is a complete example to backup a selection of
directories inside the home directory. It works by excluding any
directory, then selectively add back some of them.

::

    $HOME/*
    !$HOME/Documents
    !$HOME/code
    !$HOME/.emacs.d
    !$HOME/games
    # [...]
    node_modules
    *~
    *.o
    *.lo
    *.pyc

By specifying the option ``--one-file-system`` you can instruct restic
to only backup files from the file systems the initially specified files
or directories reside on. In other words, it will prevent restic from crossing
filesystem boundaries and subvolumes when performing a backup.

For example, if you backup ``/`` with this option and you have external
media mounted under ``/media/usb`` then restic will not back up ``/media/usb``
at all because this is a different filesystem than ``/``. Virtual filesystems
such as ``/proc`` are also considered different and thereby excluded when
using ``--one-file-system``:

.. code-block:: console

    $ restic -r /srv/restic-repo backup --one-file-system /

Please note that this does not prevent you from specifying multiple filesystems
on the command line, e.g:

.. code-block:: console

    $ restic -r /srv/restic-repo backup --one-file-system / /media/usb

will back up both the ``/`` and ``/media/usb`` filesystems, but will not
include other filesystems like ``/sys`` and ``/proc``.

.. note:: ``--one-file-system`` is currently unsupported on Windows, and will
    cause the backup to immediately fail with an error.

Files larger than a given size can be excluded using the `--exclude-larger-than`
option:

.. code-block:: console

    $ restic -r /srv/restic-repo backup ~/work --exclude-larger-than 1M

This excludes files in ``~/work`` which are larger than 1 MiB from the backup.

The default unit for the size value is bytes, so e.g. ``--exclude-larger-than 2048``
would exclude files larger than 2048 bytes (2 KiB). To specify other units,
suffix the size value with one of ``k``/``K`` for KiB (1024 bytes), ``m``/``M`` for MiB (1024^2 bytes),
``g``/``G`` for GiB (1024^3 bytes) and ``t``/``T`` for TiB (1024^4 bytes), e.g. ``1k``, ``10K``, ``20m``,
``20M``,  ``30g``, ``30G``, ``2t`` or ``2T``).

Including Files
***************

The options ``--files-from``, ``--files-from-verbatim`` and ``--files-from-raw``
allow you to give restic a file containing lists of file patterns or paths to
be backed up. This is useful e.g. when you want to back up files from many
different locations, or when you use some other software to generate the list
of files to back up.

The argument passed to ``--files-from`` must be the name of a text file that
contains one *pattern* per line. The file must be encoded as UTF-8, or UTF-16
with a byte-order mark. Leading and trailing whitespace is removed from the
patterns. Empty lines and lines starting with a ``#`` are ignored and each
pattern is expanded when read, such that special characters in it are expanded
using the Go function `filepath.Glob <https://golang.org/pkg/path/filepath/#Glob>`__
- please see its documentation for the syntax you can use in the patterns.

The argument passed to ``--files-from-verbatim`` must be the name of a text file
that contains one *path* per line, e.g. as generated by GNU ``find`` with the
``-print`` flag. Unlike ``--files-from``, ``--files-from-verbatim`` does not
expand any special characters in the list of paths, does not strip off any
whitespace and does not ignore lines starting with a ``#``. This option simply
reads and uses each line as-is, although empty lines are still ignored. Use this
option when you want to backup a list of filenames containing the special
characters that would otherwise be expanded when using ``--files-from``.

The ``--files-from-raw`` option is a variant of ``--files-from-verbatim`` that
requires each line in the file to be terminated by an ASCII NUL character (the
``\0`` zero byte) instead of a newline, so that it can even handle file paths
containing newlines in their name or are not encoded as UTF-8 (except on
Windows, where the listed filenames must still be encoded in UTF-8. This option
is the safest choice when generating the list of filenames from a script (e.g.
GNU ``find`` with the ``-print0`` flag).

All three options interpret the argument ``-`` as standard input and will read
the list of files/patterns from there instead of a text file.

In all cases, paths may be absolute or relative to ``restic backup``'s working
directory.

For example, maybe you want to backup files which have a name that matches a
certain regular expression pattern (uses GNU ``find``):

.. code-block:: console

    $ find /tmp/some_folder -regex PATTERN -print0 > /tmp/files_to_backup

You can then use restic to backup the filtered files:

.. code-block:: console

    $ restic -r /srv/restic-repo backup --files-from-raw /tmp/files_to_backup

You can combine all three options with each other and with the normal file arguments:

.. code-block:: console

    $ restic backup --files-from /tmp/files_to_backup /tmp/some_additional_file
    $ restic backup --files-from /tmp/glob-pattern --files-from-raw /tmp/generated-list /tmp/some_additional_file

Comparing Snapshots
*******************

Restic has a `diff` command which shows the difference between two snapshots
and displays a small statistic, just pass the command two snapshot IDs:

.. code-block:: console

    $ restic -r /srv/restic-repo diff 5845b002 2ab627a6
    password is correct
    comparing snapshot ea657ce5 to 2ab627a6:

     C   /restic/cmd_diff.go
    +    /restic/foo
     C   /restic/restic

    Files:           0 new,     0 removed,     2 changed
    Dirs:            1 new,     0 removed
    Others:          0 new,     0 removed
    Data Blobs:     14 new,    15 removed
    Tree Blobs:      2 new,     1 removed
      Added:   16.403 MiB
      Removed: 16.402 MiB

Backing up special items and metadata
*************************************

**Symlinks** are archived as symlinks, ``restic`` does not follow them.
When you restore, you get the same symlink again, with the same link target
and the same timestamps.

If there is a **bind-mount** below a directory that is to be saved, restic descends into it.

**Device files** are saved and restored as device files. This means that e.g. ``/dev/sda`` is
archived as a block device file and restored as such. This also means that the content of the
corresponding disk is not read, at least not from the device file.

By default, restic does not save the access time (atime) for any files or other
items, since it is not possible to reliably disable updating the access time by
restic itself. This means that for each new backup a lot of metadata is
written, and the next backup needs to write new metadata again. If you really
want to save the access time for files and directories, you can pass the
``--with-atime`` option to the ``backup`` command.

Note that ``restic`` does not back up some metadata associated with files. Of
particular note are::

  - file creation date on Unix platforms
  - inode flags on Unix platforms
  - file ownership and ACLs on Windows
  - the "hidden" flag on Windows

Reading data from stdin
***********************

Sometimes it can be nice to directly save the output of a program, e.g.
``mysqldump`` so that the SQL can later be restored. Restic supports
this mode of operation, just supply the option ``--stdin`` to the
``backup`` command like this:

.. code-block:: console

    $ set -o pipefail
    $ mysqldump [...] | restic -r /srv/restic-repo backup --stdin

This creates a new snapshot of the output of ``mysqldump``. You can then
use e.g. the fuse mounting option (see below) to mount the repository
and read the file.

By default, the file name ``stdin`` is used, a different name can be
specified with ``--stdin-filename``, e.g. like this:

.. code-block:: console

    $ mysqldump [...] | restic -r /srv/restic-repo backup --stdin --stdin-filename production.sql

The option ``pipefail`` is highly recommended so that a non-zero exit code from
one of the programs in the pipe (e.g. ``mysqldump`` here) makes the whole chain
return a non-zero exit code. Refer to the `Use the Unofficial Bash Strict Mode
<http://redsymbol.net/articles/unofficial-bash-strict-mode/>`__ for more
details on this.

Tags for backup
***************

Snapshots can have one or more tags, short strings which add identifying
information. Just specify the tags for a snapshot one by one with ``--tag``:

.. code-block:: console

    $ restic -r /srv/restic-repo backup --tag projectX --tag foo --tag bar ~/work
    [...]

The tags can later be used to keep (or forget) snapshots with the ``forget``
command. The command ``tag`` can be used to modify tags on an existing
snapshot.

Scheduling backups
******************

Restic does not have a built-in way of scheduling backups, as it's a tool
that runs when executed rather than a daemon. There are plenty of different
ways to schedule backup runs on various different platforms, e.g. systemd
and cron on Linux/BSD and Task Scheduler in Windows, depending on one's
needs and requirements. When scheduling restic to run recurringly, please
make sure to detect already running instances before starting the backup.

Space requirements
******************

Restic currently assumes that your backup repository has sufficient space
for the backup operation you are about to perform. This is a realistic
assumption for many cloud providers, but may not be true when backing up
to local disks.

Should you run out of space during the middle of a backup, there will be
some additional data in the repository, but the snapshot will never be
created as it would only be written at the very (successful) end of
the backup operation.  Previous snapshots will still be there and will still
work.

Environment Variables
*********************

In addition to command-line options, restic supports passing various options in
environment variables. The following lists these environment variables:

.. code-block:: console

    RESTIC_REPOSITORY_FILE              Name of file containing the repository location (replaces --repository-file)
    RESTIC_REPOSITORY                   Location of repository (replaces -r)
    RESTIC_PASSWORD_FILE                Location of password file (replaces --password-file)
    RESTIC_PASSWORD                     The actual password for the repository
    RESTIC_PASSWORD_COMMAND             Command printing the password for the repository to stdout
    RESTIC_KEY_HINT                     ID of key to try decrypting first, before other keys
    RESTIC_CACHE_DIR                    Location of the cache directory
    RESTIC_COMPRESSION                  Compression mode (only available for repository format version 2)
    RESTIC_PROGRESS_FPS                 Frames per second by which the progress bar is updated
    RESTIC_PACK_SIZE                    Target size for pack files
    RESTIC_READ_CONCURRENCY             Concurrency for file reads

    TMPDIR                              Location for temporary files

    AWS_ACCESS_KEY_ID                   Amazon S3 access key ID
    AWS_SECRET_ACCESS_KEY               Amazon S3 secret access key
    AWS_SESSION_TOKEN                   Amazon S3 temporary session token
    AWS_DEFAULT_REGION                  Amazon S3 default region
    AWS_PROFILE                         Amazon credentials profile (alternative to specifying key and region)
    AWS_SHARED_CREDENTIALS_FILE         Location of the AWS CLI shared credentials file (default: ~/.aws/credentials)

    ST_AUTH                             Auth URL for keystone v1 authentication
    ST_USER                             Username for keystone v1 authentication
    ST_KEY                              Password for keystone v1 authentication

    OS_AUTH_URL                         Auth URL for keystone authentication
    OS_REGION_NAME                      Region name for keystone authentication
    OS_USERNAME                         Username for keystone authentication
    OS_USER_ID                          User ID for keystone v3 authentication
    OS_PASSWORD                         Password for keystone authentication
    OS_TENANT_ID                        Tenant ID for keystone v2 authentication
    OS_TENANT_NAME                      Tenant name for keystone v2 authentication

    OS_USER_DOMAIN_NAME                 User domain name for keystone authentication
    OS_USER_DOMAIN_ID                   User domain ID for keystone v3 authentication
    OS_PROJECT_NAME                     Project name for keystone authentication
    OS_PROJECT_DOMAIN_NAME              Project domain name for keystone authentication
    OS_PROJECT_DOMAIN_ID                Project domain ID for keystone v3 authentication
    OS_TRUST_ID                         Trust ID for keystone v3 authentication

    OS_APPLICATION_CREDENTIAL_ID        Application Credential ID (keystone v3)
    OS_APPLICATION_CREDENTIAL_NAME      Application Credential Name (keystone v3)
    OS_APPLICATION_CREDENTIAL_SECRET    Application Credential Secret (keystone v3)

    OS_STORAGE_URL                      Storage URL for token authentication
    OS_AUTH_TOKEN                       Auth token for token authentication

    B2_ACCOUNT_ID                       Account ID or applicationKeyId for Backblaze B2
    B2_ACCOUNT_KEY                      Account Key or applicationKey for Backblaze B2

    AZURE_ACCOUNT_NAME                  Account name for Azure
    AZURE_ACCOUNT_KEY                   Account key for Azure
    AZURE_ACCOUNT_SAS                   Shared access signatures (SAS) for Azure

    GOOGLE_PROJECT_ID                   Project ID for Google Cloud Storage
    GOOGLE_APPLICATION_CREDENTIALS      Application Credentials for Google Cloud Storage (e.g. $HOME/.config/gs-secret-restic-key.json)

    RCLONE_BWLIMIT                      rclone bandwidth limit

See :ref:`caching` for the rules concerning cache locations when
``RESTIC_CACHE_DIR`` is not set.

The external programs that restic may execute include ``rclone`` (for rclone
backends) and ``ssh`` (for the SFTP backend). These may respond to further
environment variables and configuration files; see their respective manuals.

Exit status codes
*****************

Restic returns one of the following exit status codes after the backup command is run:

 * 0 when the backup was successful (snapshot with all source files created)
 * 1 when there was a fatal error (no snapshot created)
 * 3 when some source files could not be read (incomplete snapshot with remaining files created)

Fatal errors occur for example when restic is unable to write to the backup destination, when
there are network connectivity issues preventing successful communication, or when an invalid
password or command line argument is provided. When restic returns this exit status code, one
should not expect a snapshot to have been created.

Source file read errors occur when restic fails to read one or more files or directories that
it was asked to back up, e.g. due to permission problems. Restic displays the number of source
file read errors that occurred while running the backup. If there are errors of this type,
restic will still try to complete the backup run with all the other files, and create a
snapshot that then contains all but the unreadable files.

One can use these exit status codes in scripts and other automation tools, to make them aware of
the outcome of the backup run. To manually inspect the exit code in e.g. Linux, run ``echo $?``.


text:
using MonoMac.Foundation;
using System.CodeDom.Compiler;

namespace Radish
{
	[Register ("MainWindowController")]
	partial class MainWindowController
	{
		[Outlet]
        MonoMac.AppKit.NSProgressIndicator busyIndicator { get; set; }

		[Outlet]
        MonoMac.AppKit.NSProgressIndicator busyProgressControl { get; set; }

		[Outlet]
		Radish.KTBorderlessWindow busyWindow { get; set; }

		[Outlet]
        MonoMac.Foundation.NSObject fileInformationController { get; set; }

		[Outlet]
        MonoMac.AppKit.NSImageView imageView { get; set; }

		[Outlet]
        MonoMac.AppKit.NSPanel informationPanel { get; set; }

		[Outlet]
        MonoMac.AppKit.NSImageView notificationImage { get; set; }

		[Outlet]
        MonoMac.Foundation.NSObject notificationWindow { get; set; }

		[Outlet]
        MonoMac.AppKit.NSScrollView scrollView { get; set; }

		[Outlet]
        MonoMac.Foundation.NSObject searchController { get; set; }

		[Outlet]
        MonoMac.AppKit.NSWindow searchWindow { get; set; }

		[Outlet]
        MonoMac.AppKit.NSTextField statusFilename { get; set; }

		[Outlet]
        MonoMac.AppKit.NSTextField statusGps { get; set; }

		[Outlet]
        MonoMac.AppKit.NSTextField statusIndex { get; set; }

		[Outlet]
        MonoMac.AppKit.NSTextField statusKeywords { get; set; }

		[Outlet]
        MonoMac.AppKit.NSTextField statusTimestamp { get; set; }

		[Outlet]
        MonoMac.AppKit.NSView statusView { get; set; }

		[Outlet]
        MonoMac.Foundation.NSObject thumbController { get; set; }

		[Outlet]
        MonoMac.AppKit.NSWindow thumbnailWindow { get; set; }

		void ReleaseDesignerOutlets ()
		{
			if (busyIndicator != null) {
				busyIndicator.Dispose ();
				busyIndicator = null;
			}

			if (busyWindow != null) {
				busyWindow.Dispose ();
				busyWindow = null;
			}

			if (fileInformationController != null) {
				fileInformationController.Dispose ();
				fileInformationController = null;
			}

			if (imageView != null) {
				imageView.Dispose ();
				imageView = null;
			}

			if (informationPanel != null) {
				informationPanel.Dispose ();
				informationPanel = null;
			}

			if (notificationImage != null) {
				notificationImage.Dispose ();
				notificationImage = null;
			}

			if (notificationWindow != null) {
				notificationWindow.Dispose ();
				notificationWindow = null;
			}

			if (scrollView != null) {
				scrollView.Dispose ();
				scrollView = null;
			}

			if (searchController != null) {
				searchController.Dispose ();
				searchController = null;
			}

			if (searchWindow != null) {
				searchWindow.Dispose ();
				searchWindow = null;
			}

			if (statusFilename != null) {
				statusFilename.Dispose ();
				statusFilename = null;
			}

			if (statusGps != null) {
				statusGps.Dispose ();
				statusGps = null;
			}

			if (statusIndex != null) {
				statusIndex.Dispose ();
				statusIndex = null;
			}

			if (statusKeywords != null) {
				statusKeywords.Dispose ();
				statusKeywords = null;
			}

			if (statusTimestamp != null) {
				statusTimestamp.Dispose ();
				statusTimestamp = null;
			}

			if (statusView != null) {
				statusView.Dispose ();
				statusView = null;
			}

			if (thumbController != null) {
				thumbController.Dispose ();
				thumbController = null;
			}

			if (thumbnailWindow != null) {
				thumbnailWindow.Dispose ();
				thumbnailWindow = null;
			}

			if (busyProgressControl != null) {
				busyProgressControl.Dispose ();
				busyProgressControl = null;
			}
		}
	}

	[Register ("MainWindow")]
	partial class MainWindow
	{

		void ReleaseDesignerOutlets ()
		{
		}
	}
}

redpajama_set_name: RedPajamaGithub


text:
<?php

/**
 * @ignore
 */
if (!defined('IN_PHPBB'))
{
	exit;
}

if (empty($lang) || !is_array($lang))
{
	$lang = array();
}

// DEVELOPERS PLEASE NOTE
//
// All language files should use UTF-8 as their encoding and the files must not contain a BOM.
//
// Placeholders can now contain order information, e.g. instead of
// 'Page %s of %s' you can (and should) write 'Page %1$s of %2$s', this allows
// translators to re-order the output of data while ensuring it remains correct
//
// You do not need this where single placeholders are used, e.g. 'Message %d' is fine
// equally where a string contains only two placeholders which are used to wrap text
// in a url you again do not need to specify an order e.g., 'Click %sHERE%s' is fine
//
// Some characters you may want to copy&paste:
// ' » " " …
//

$lang = array_merge($lang, array(
	'ACTION'						=> 'Akcija',
	'ADVANCED'						=> 'Napredno',
	'AUTH_CACHE_PURGE'				=> 'Brisanje autorizacijske privremene memorije',

	'CACHE_PURGE'					=> 'Brisanje privremene memorije foruma',
	'CONFIGURE'						=> 'Postavi',
	'CONFIG_ADD'					=> 'Dodavanje nove konfiguracijske varijable: %s',
	'CONFIG_ALREADY_EXISTS'			=> 'GREŠKA: Konfiguracijska varijabla %s već postoji.',
	'CONFIG_NOT_EXIST'				=> 'GREŠKA: Konfiguracijska varijabla %s ne postoji.',
	'CONFIG_REMOVE'					=> 'Uklanjanje konfiguracijske varijable: %s',
	'CONFIG_UPDATE'					=> 'Ažuriranje konfiguracijske varijable: %s',

	'DISPLAY_RESULTS'				=> 'Prikaži potpune rezultate',
	'DISPLAY_RESULTS_EXPLAIN'		=> 'Odaberi Da za prikaz svih radnji i rezultata tijekom provođenja zahtijevane radnje.',

	'ERROR_NOTICE'					=> 'Dogodila se jedna ili više grešaka prilikom provođenja zahtijevane radnje.  Molimo da se skine ova datoteka sa popisom greški i zatim kontaktira autor moda za pomoć.

Ukoliko imaš problema sa skidanjem datoteke, možeš joj direktno pristupiti pomoću FTP pristupa na slijedećoj lokaciji: %2$s',
	'ERROR_NOTICE_NO_FILE'			=> 'Dogodila se jedna ili više grešaka prilikom provođenja zahtijevane radnje.  Molimo da napravite potpuni zapis svake greške i zatim kontaktira autora moda za pomoć.',

	'FAIL'							=> 'Neuspjeh',
	'FILE_COULD_NOT_READ'			=> 'GREŠKA: Nije moguće otvoriti datoteku %s za čitanje.',
	'FOUNDERS_ONLY'					=> 'Moraš biti osnivač/ica foruma kako bi mogao/la pristupiti ovoj stranici.',

	'GROUP_NOT_EXIST'				=> 'Grupa ne postoji',

	'IGNORE'						=> 'Ignoriraj',
	'IMAGESET_CACHE_PURGE'			=> 'Osvježavanje %s seta slika',
	'INSTALL'						=> 'Instaliraj',
	'INSTALL_MOD'					=> 'Instaliraj %s',
	'INSTALL_MOD_CONFIRM'			=> 'Jesi li spreman/na na instalaciju %s?',

	'MODULE_ADD'					=> 'Dodavanje %1$s modula: %2$s',
	'MODULE_ALREADY_EXIST'			=> 'GREŠKA: Modul već postoji.',
	'MODULE_NOT_EXIST'				=> 'GREŠKA: Modul ne postoji.',
	'MODULE_REMOVE'					=> 'Uklanjanje %1$s modula: %2$s',

	'NONE'							=> 'Ništa',
	'NO_TABLE_DATA'					=> 'GREŠKA: Podaci iz tablice nisu specificirani',

	'PARENT_NOT_EXIST'				=> 'GREŠKA: Osnovna kategorija specificirana za ovaj modul ne postoji.',
	'PERMISSIONS_WARNING'			=> 'Postavke novih dopuštenja su dodane.  Molimo da se provjere postavke dopuštenja kako bi se osiguralo da su postavljene na željeni način.',
	'PERMISSION_ADD'				=> 'Dodavanje opcije za novo dopuštenje: %s',
	'PERMISSION_ALREADY_EXISTS'		=> 'GREŠKA: Opcija dopuštenja %s već postoji.',
	'PERMISSION_NOT_EXIST'			=> 'GREŠKA: Opcija dopuštenja %s ne postoji.',
	'PERMISSION_REMOVE'				=> 'Uklanjanje opcije dopuštenja: %s',
	'PERMISSION_ROLE_ADD'			=> 'Dodavanje nove uloge dopuštenja: %s',
	'PERMISSION_ROLE_UPDATE'		=> 'Ažuriranje uloge dopuštenja: %s',
	'PERMISSION_ROLE_REMOVE'		=> 'Uklanjanje uloge dopuštenja: %s',
	'PERMISSION_SET_GROUP'			=> 'Postavljanje dopuštenja za %s grupu.',
	'PERMISSION_SET_ROLE'			=> 'Postavljanje dopuštenja za %s ulogu.',
	'PERMISSION_UNSET_GROUP'		=> 'Uklanjanje postavki dopuštenja za %s grupu.',
	'PERMISSION_UNSET_ROLE'			=> 'Uklanjanje dopuštenja za %s ulogu.',

	'ROLE_ALREADY_EXISTS'			=> 'Uloga dopuštenja već postoji.',
	'ROLE_NOT_EXIST'				=> 'Uloga dopuštenja ne postoji',

	'SUCCESS'						=> 'Uspjeh',

	'TABLE_ADD'						=> 'Dodavanje nove tablice unutar baze podataka: %s',
	'TABLE_ALREADY_EXISTS'			=> 'GREŠKA: Tablica baze podataka %s već postoji.',
	'TABLE_COLUMN_ADD'				=> 'Dodavanje novog stupca pod nazivom %2$s u tablicu %1$s',
	'TABLE_COLUMN_ALREADY_EXISTS'	=> 'GREŠKA: Stupac %2$s već postoji unutar tablice %1$s.',
	'TABLE_COLUMN_NOT_EXIST'		=> 'GREŠKA: Stupac %2$s ne postoji unutar tablice %1$s.',
	'TABLE_COLUMN_REMOVE'			=> 'Uklanjanje stupca pod nazivom %2$s iz tablice %1$s',
	'TABLE_COLUMN_UPDATE'			=> 'Ažuriranje stupca pod nazivom %2$s iz tablice %1$s',
	'TABLE_KEY_ADD'					=> 'Dodavanje ključa pod nazivom %2$s unutar tablice %1$s',
	'TABLE_KEY_ALREADY_EXIST'		=> 'GREŠKA: Indeks %2$s već postoji unutar tablice %1$s.',
	'TABLE_KEY_NOT_EXIST'			=> 'GREŠKA: Indeks %2$s ne postoji unutar tablice %1$s.',
	'TABLE_KEY_REMOVE'				=> 'Uklanjanje ključa pod nazivom %2$s iz tablice %1$s',
	'TABLE_NOT_EXIST'				=> 'GREŠKA: Tablica baze podataka %s ne postoji.',
	'TABLE_REMOVE'					=> 'Uklanjanje tablice baze podataka: %s',
	'TABLE_ROW_INSERT_DATA'			=> 'Umetanje podataka u %s tablicu baze podataka.',
	'TABLE_ROW_REMOVE_DATA'			=> 'Uklanjanje reda iz %s tablice baze podataka',
	'TABLE_ROW_UPDATE_DATA'			=> 'Ažuriranje reda u %s tablici baze podataka.',
	'TEMPLATE_CACHE_PURGE'			=> 'Osvježavanje %s predloška',
	'THEME_CACHE_PURGE'				=> 'Osvježavanje %s teme',

	'UNINSTALL'						=> 'Deinstaliraj',
	'UNINSTALL_MOD'					=> 'Deinstaliraj %s',
	'UNINSTALL_MOD_CONFIRM'			=> 'Jesi li spreman/na deinstalirati %s?  Sve postavke i podaci pohranjeni od strane ovog moda će biti uklonjeni!',
	'UNKNOWN'						=> 'Nepoznato',
	'UPDATE_MOD'					=> 'Ažuriraj %s',
	'UPDATE_MOD_CONFIRM'			=> 'Jesi li spreman/na ažurirati %s?',
	'UPDATE_UMIL'					=> 'Ova verzija UMIL-a je zastarjela.

Molimo da skineš posljednju verziju UMIL-a (Unified MOD Install Library) sa: %1$s',

	'VERSIONS'						=> 'Verzija MOD-a: %1$s
Trenutno instalirana: %2$s',
	'VERSION_SELECT'				=> 'Odabir verzije',
	'VERSION_SELECT_EXPLAIN'		=> 'Ne mijenjaj iz "Ignoriraj" ukoliko ne znaš točno što radiš ili ti je rečeno da to učiniš.',
));

?>


text:
package net.liftweb.example.comet

import _root_.scala.actors._
import _root_.scala.actors.Actor._
import _root_.net.liftweb.http._
import _root_.net.liftweb.util.Helpers._
import _root_.scala.collection.immutable.TreeMap
import _root_.scala.xml._
import S._
import SHtml._
import _root_.net.liftweb.util._
import _root_.net.liftweb.http.js._
import _root_.net.liftweb.http.js.jquery._
import JsCmds._
import JE._
import JqJsCmds._

class Chat extends CometActor {
  private var userName = ""
  private var currentData: List[ChatLine] = Nil
  override def defaultPrefix = Full("chat")

  private lazy val infoId = uniqueId + "_info"

  private lazy val server = {
    val ret = ChatServer
    ret ! ChatServerAdd(this)
    ret
  }

  override def lowPriority = {
    case ChatServerUpdate(value) =>
      (value -- currentData) match {
        case Nil =>
        case diff => partialUpdate(diff.reverse.foldLeft(Noop)((a,b) => a &
                                                               AppendHtml(infoId, line(b))))
      }

      currentData = value
  }

  override lazy val fixedRender: Box[NodeSeq] = {
    val n = Helpers.nextFuncName

    ajaxForm(After(100, SetValueAndFocus(n, "")),
             (text("", sendMessage _) %
              ("id" -> n)) ++ <input type="submit" value="Chat"/> )
  }

  def line(cl: ChatLine) = (
{hourFormat(cl.when)} {cl.user}: {cl.msg}
)

  override def render = (Hello "{userName}"

{currentData.reverse.flatMap(line)}

                         )

  override def localSetup {
    askForName
    super.localSetup
  }

  override def localShutdown() {
    ChatServer ! ChatServerRemove(this)
    super.localShutdown()
  }

  private def askForName {
    if (userName.length == 0) {
      ask(new AskName, "what's your username") {
        case s: String if (s.trim.length > 2) =>
          userName = s.trim
          reRender(true)

        case s =>
          askForName
          reRender(false)
      }
    }
  }

  def sendMessage(msg: String) = server ! ChatServerMsg(userName, msg.trim)
}


text:
"""

File: tertian_chord.py

Purpose: Defines a class to represent a tertian chord

"""
from harmonicmodel.chord import Chord
from tonalmodel.interval import Interval
from tonalmodel.diatonic_pitch import DiatonicPitch

class TertianChord(Chord):
    """
    Class that defines a tertian chord
    This class create it tones based on differing specifications found in TertianChordTemplate:
    1) If root is given by a diatonic tone (and chord type), the diatonic tonality is not used,
       and strict interval specs decide the other notes.
    2) If root is given by diatonic tonality and scale reference,
       a) If the chord type is given, the tones are built as in 1) but with the root determined by
          scale degree on tonality.
       b) If the chord type is note given, the tones are built on the tonality itself.  The chord type determined by
          the tones.

    Inversion results in a re-ordering of the tone, making the inversion tone the first tone.

    The result self.tones is a list of duplets (diatonic_tone, interval)
    """

    def __init__(self, tertian_chord_template, diatonic_tonality=None):
        """
        Constructor.
        Args:
          tertian_chord_template: TertianChordTemplate
          diatonic_tonality: DiatonicTonality (used in scale degree chord formation)
        """
        Chord.__init__(self, tertian_chord_template, diatonic_tonality)

        self.__tones = []
        self.__chord_type = self.chord_template.chord_type

        self.__root_tone = self.chord_template.diatonic_basis

        if self.chord_template.diatonic_basis:
            if self.chord_type:
                self.__create_chord_on_diatonic(self.root_tone)
            else:
                self.__create_chord_on_diatonic_without_type(self.root_tone)
        else:
            if not self.diatonic_tonality:
                raise Exception(
                    'Diatonic tonality must be specified for chords based on scale degree: {0}'.
                    format(str(self.chord_template)))
            if self.chord_type:
                self.__create_chord_on_scale_degree_with_chord_type()
            else:
                self.__create_chord_on_scale_degree()

    def __create_chord_on_diatonic(self, diatonic_tone):
        self.chord_basis = []
        for interval in self.chord_template.base_intervals:
            tone = interval.get_end_tone(diatonic_tone)
            self.__tones.append((tone, interval))
            self.chord_basis.append(interval)

        for interval in self.chord_template.tension_intervals:
            tone = interval.get_end_tone(diatonic_tone)
            self.__tones.append((tone, interval))

        self.__set_inversion()

    def __create_chord_on_diatonic_without_type(self, diatonic_tone):
        from tonalmodel.tonality import Tonality
        from tonalmodel.modality import ModalityType
        from harmonicmodel.tertian_chord_template import TertianChordTemplate
        diatonic_tonality = Tonality.create(ModalityType.Major, diatonic_tone)
        tone_scale = diatonic_tonality.annotation

        self.chord_basis = []
        base_tone = None
        for i in range(0, 3):
            tone = tone_scale[(2 * i) % (len(tone_scale) - 1)]
            if i == 0:
                base_tone = tone

            pitch_a = DiatonicPitch(1, diatonic_tone)
            b_octave = 2 if base_tone.diatonic_index > tone.diatonic_index else 1
            pitch_b = DiatonicPitch(b_octave, tone.diatonic_symbol)
            interval = Interval.create_interval(pitch_a, pitch_b)
            self.chord_basis.append(interval)

            self.__tones.append((tone, interval))
        self.__set_inversion()

        self.__chord_type = TertianChordTemplate.get_chord_type(self.chord_basis)

    def __create_chord_on_scale_degree(self):
        from harmonicmodel.tertian_chord_template import TertianChordTemplate
        root_index = self.chord_template.scale_degree - 1
        tone_scale = self.diatonic_tonality.annotation

        self.chord_basis = []
        base_tone = None
        for i in range(0, 3):
            tone = tone_scale[(root_index + 2 * i) % (len(tone_scale) - 1)]
            if i == 0:
                base_tone = tone

            pitch_a = DiatonicPitch(1, tone_scale[root_index].diatonic_symbol)
            b_octave = 2 if base_tone.diatonic_index > tone.diatonic_index else 1
            pitch_b = DiatonicPitch(b_octave, tone.diatonic_symbol)
            interval = Interval.create_interval(pitch_a, pitch_b)
            self.chord_basis.append(interval)

            self.__tones.append((tone, interval))
        self.__set_inversion()

        self.__chord_type = TertianChordTemplate.get_chord_type(self.chord_basis)

    def __create_chord_on_scale_degree_with_chord_type(self):
        root_index = self.chord_template.scale_degree - 1
        tone_scale = self.diatonic_tonality.annotation
        self.__root_tone = tone_scale[root_index]

        self.__create_chord_on_diatonic(self.__root_tone)

    def __set_inversion(self):
        invert_id = -1
        if self.chord_template.inversion:
            if self.chord_template.inversion == 1:
                return
            invert_id = self.chord_template.inversion
        elif self.chord_template.inversion_interval:
            # find the interval

            for i in range(0, len(self.chord_basis)):
                if self.chord_basis[i].is_same(self.chord_template.inversion_interval):
                    invert_id = i + 1
                    break
            if invert_id == -1 and self.chord_template.tension_intervals:
                for i in range(0, len(self.chord_template.tension_intervals)):
                    if self.chord_template.tension_intervals[i] == self.chord_template.inversion_interval:
                        invert_id = i + 1 + len(self.chord_basis)
                        break
            if invert_id == -1:
                raise Exception(
                    "Could not find interval {0} for chord off template {1}".
                    format(self.chord_template.inversion_interval, self.chord_template))
            # remove the cited index
        item = self.__tones[invert_id - 1]
        self.__tones.remove(item)
        self.__tones.insert(0, item)

    @property
    def tones(self):
        new_list = []
        new_list.extend(self.__tones)
        return new_list

    @property
    def chord_type(self):
        return self.__chord_type

    @property
    def root_tone(self):
        return self.__root_tone

    def sorted_tones(self):
        return sorted(self.tones, key=lambda tone: tone[1].semitones())

    def __str__(self):
        return '{0} [{1}]'.format(str(self.chord_template),
                                  ', '.join(str(tone[0].diatonic_symbol) for tone in self.tones))


text:
package org.apache.cassandra.io.sstable;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

import org.apache.cassandra.io.sstable.format.SSTableFormat;
import org.apache.commons.lang3.StringUtils;
import org.junit.Assert;
import org.junit.Test;

import org.apache.cassandra.db.Directories;
import org.apache.cassandra.utils.ByteBufferUtil;
import org.apache.cassandra.utils.Pair;

import static org.junit.Assert.*;

public class DescriptorTest
{
    private final String ksname = "ks";
    private final String cfname = "cf";
    private final String cfId = ByteBufferUtil.bytesToHex(ByteBufferUtil.bytes(UUID.randomUUID()));
    private final File tempDataDir;

    public DescriptorTest() throws IOException
    {
        // create CF directories, one without CFID and one with it
        tempDataDir = File.createTempFile("DescriptorTest", null).getParentFile();
    }

    @Test
    public void testFromFilename() throws Exception
    {
        File cfIdDir = new File(tempDataDir.getAbsolutePath() + File.separator + ksname + File.separator + cfname + '-' + cfId);
        testFromFilenameFor(cfIdDir);
    }

    @Test
    public void testFromFilenameInBackup() throws Exception
    {
        File backupDir = new File(StringUtils.join(new String[]{tempDataDir.getAbsolutePath(), ksname, cfname + '-' + cfId, Directories.BACKUPS_SUBDIR}, File.separator));
        testFromFilenameFor(backupDir);
    }

    @Test
    public void testFromFilenameInSnapshot() throws Exception
    {
        File snapshotDir = new File(StringUtils.join(new String[]{tempDataDir.getAbsolutePath(), ksname, cfname + '-' + cfId, Directories.SNAPSHOT_SUBDIR, "snapshot_name"}, File.separator));
        testFromFilenameFor(snapshotDir);
    }

    @Test
    public void testFromFilenameInLegacyDirectory() throws Exception
    {
        File cfDir = new File(tempDataDir.getAbsolutePath() + File.separator + ksname + File.separator + cfname);
        testFromFilenameFor(cfDir);
    }

    private void testFromFilenameFor(File dir)
    {
        // normal
        checkFromFilename(new Descriptor(dir, ksname, cfname, 1, Descriptor.Type.FINAL), false);
        // skip component (for streaming lock file)
        checkFromFilename(new Descriptor(dir, ksname, cfname, 2, Descriptor.Type.FINAL), true);
        // tmp
        checkFromFilename(new Descriptor(dir, ksname, cfname, 3, Descriptor.Type.TEMP), false);
        // secondary index
        String idxName = "myidx";
        File idxDir = new File(dir.getAbsolutePath() + File.separator + Directories.SECONDARY_INDEX_NAME_SEPARATOR + idxName);
        checkFromFilename(new Descriptor(idxDir, ksname, cfname + Directories.SECONDARY_INDEX_NAME_SEPARATOR + idxName, 4, Descriptor.Type.FINAL), false);
        // secondary index tmp
        checkFromFilename(new Descriptor(idxDir, ksname, cfname + Directories.SECONDARY_INDEX_NAME_SEPARATOR + idxName, 5, Descriptor.Type.TEMP), false);

        // legacy version
        checkFromFilename(new Descriptor("ja", dir, ksname, cfname, 1, Descriptor.Type.FINAL, SSTableFormat.Type.LEGACY), false);
        // legacy tmp
        checkFromFilename(new Descriptor("ja", dir, ksname, cfname, 2, Descriptor.Type.TEMP, SSTableFormat.Type.LEGACY), false);
        // legacy secondary index
        checkFromFilename(new Descriptor("ja", dir, ksname, cfname + Directories.SECONDARY_INDEX_NAME_SEPARATOR + idxName, 3, Descriptor.Type.FINAL, SSTableFormat.Type.LEGACY), false);
    }

    private void checkFromFilename(Descriptor original, boolean skipComponent)
    {
        File file = new File(skipComponent ? original.baseFilename() : original.filenameFor(Component.DATA));

        Pair<Descriptor, String> pair = Descriptor.fromFilename(file.getParentFile(), file.getName(), skipComponent);
        Descriptor desc = pair.left;

        assertEquals(original.directory, desc.directory);
        assertEquals(original.ksname, desc.ksname);
        assertEquals(original.cfname, desc.cfname);
        assertEquals(original.version, desc.version);
        assertEquals(original.generation, desc.generation);
        assertEquals(original.type, desc.type);

        if (skipComponent)
        {
            assertNull(pair.right);
        }
        else
        {
            assertEquals(Component.DATA.name(), pair.right);
        }
    }

    @Test
    public void validateNames()
    {

        String names[] = {
            /*"system-schema_keyspaces-ka-1-CompressionInfo.db",  "system-schema_keyspaces-ka-1-Summary.db",
            "system-schema_keyspaces-ka-1-Data.db",             "system-schema_keyspaces-ka-1-TOC.txt",
            "system-schema_keyspaces-ka-1-Digest.sha1",         "system-schema_keyspaces-ka-2-CompressionInfo.db",
            "system-schema_keyspaces-ka-1-Filter.db",           "system-schema_keyspaces-ka-2-Data.db",
            "system-schema_keyspaces-ka-1-Index.db",            "system-schema_keyspaces-ka-2-Digest.sha1",
            "system-schema_keyspaces-ka-1-Statistics.db",
            "system-schema_keyspacest-tmp-ka-1-Data.db",*/
            "system-schema_keyspace-ka-1-"+ SSTableFormat.Type.BIG.name+"-Data.db"
        };

        for (String name : names)
        {
            Descriptor d = Descriptor.fromFilename(name);
        }
    }

    @Test
    public void badNames()
    {
        String names[] = {
                "system-schema_keyspaces-k234a-1-CompressionInfo.db",  "system-schema_keyspaces-ka-aa-Summary.db",
                "system-schema_keyspaces-XXX-ka-1-Data.db",             "system-schema_keyspaces-k",
                "system-schema_keyspace-ka-1-AAA-Data.db",  "system-schema-keyspace-ka-1-AAA-Data.db"
        };

        for (String name : names)
        {
            try
            {
                Descriptor d = Descriptor.fromFilename(name);
                Assert.fail(name);
            } catch (Throwable e) {
                //good
            }
        }
    }

}


text:
/**
 * This class is experimental, and as such has not been tested.
 * Please help make it more robust by contributing fixes if you find issues
 **/

#import <Foundation/Foundation.h>
#import "AJNBusAttachment.h"
#import "AJNTranslator.h"
#import "AJTMTimeServiceServerClock.h"
#import "AJTMTimeServiceServerAuthorityClock.h"
#import "AJTMTimeServiceServerAlarm.h"
#import "AJTMTimeServiceAlarmBusObj.h"
#import "AJTMTimeServiceTimerBusObj.h"
#import "AJTMTimeServiceConstants.h"
#import "alljoyn/time/TimeServiceConstants.h"
#import "AJTMTimeServiceServerClockBase.h"
#import "AJTMTimeServiceServerAlarmBase.h"
#import "AJTMTimeServiceServerTimerBase.h"
#import "AJTMTimeServiceServerAlarmFactoryBase.h"
#import "AJTMTimeServiceServerTimerFactoryBase.h"

//class TimeServiceServer : public SessionListener, public SessionPortListener {
/**
 * The main class to initialize the Time Service in the server mode.
 * Initialize the class by calling the TimeServiceServer->init() method
 */
@interface AJTMTimeServiceServer : NSObject

/**
 * Get Instance of AJTMTimeServiceServer - singleton implementation
 * @return instance
 */
+ (id)sharedInstance;

/**
 * Initialize the TimeServiceServer
 *
 * @param BusAttachment to be used by the TimeServiceServer
 */
-(QStatus)initWithBus:(AJNBusAttachment*) busAttachment;

/**
 * Stop the TimeServiceServer
 */
-(void)shutdown;

/**
 * Returns BusAttachment that is used by the TimeServiceServer.
 *
 * @return AJNBusAttachment or NULL if the BusAttachment is not initialized.
 */
-(AJNBusAttachment*)busAttachment;

/**
 * TimeServiceServer is started if the method TimeServiceServer->init(BusAttachment)
 * has been invoked
 * @return TRUE if the TimeServiceServer has been started
 */
-(bool)isStarted;

/**
 * Create Clock.
 * @param clock Methods of this Clock are invoked as a response to calls of the remote TimeServiceClient(s)
 * @return status of creating the Clock
 */
-(QStatus)createClock:(AJTMTimeServiceServerClockBase*) clock;

/**
 * Create Time Authority Clock.
 * The clock allows to send TimeServiceServerAuthorityClock.timeSync() signal to suggest synchronizing
 * time with it.
 *
 * @param clock Methods of this Clock are invoked as a response to calls of the remote TimeServiceClient(s)
 * @param type Options where this Time AuthorityClock synchronizes its time
 * @return status of creating the TimeAuthority clock
 */
-(QStatus)createTimeAuthorityClock:(AJTMTimeServiceServerAuthorityClock*) clock authorityType:(AJTMClockAuthorityType) authorityType;

/**
 * Create Alarm.
 *
 * @param alarm Methods of this Alarm are invoked
 * as a response to calls of the remote TimeServiceClient(s)
 * @return status of creating the alarm
 */
-(QStatus)createAlarm:(AJTMTimeServiceServerAlarmBase*) alarm;

/**
 * Create Alarm with description.
 *
 * @param alarm Methods of this TimeServiceServerAlarm are invoked
 * as a response to calls of the remote TimeServiceClient(s)
 * @param description Description to be added to the object when registering TimeServiceServerAlarm.
 * Since description is provided, org.allseen.Introspectable interface is added to the announced interfaces
 * to support Events & Actions feature.
 * @param language The language of the description
 * @param translator If not NULL, TimeServiceServerAlarm is registered with Translator
 * to support the feature of AllSeenIntrospectable.GetDescriptionLanguages()
 * @return status of creating the alarm
 */
-(QStatus)createAlarm:(AJTMTimeServiceServerAlarmBase*) alarm description:(NSString*) description language:(NSString*) language translator:(id<AJNTranslator>) translator;

/**
 * Register user defined custom TimeServiceServerAlarm.
 * To register custom Alarm inherit from TimeServiceAlarmBusObj.
 * This method registers the given alarmBusObj and searches for the interfaces to be added to AboutService
 * and later announced.
 * To exclude interfaces from being announced, notAnnounced vector should be provided.
 * @param alarmBusObj Custom Alarm to be registered
 * @param alarm Methods of this Alarm are invoked
 * as a response to calls of the remote TimeServiceClient(s)
 * @param notAnnounced AllJoyn name of the interfaces that should NOT be announced. If this vector is empty,
 * all the found interfaces are added to the AboutService to be announced.
 * @return status of creating the alarm
 */
-(QStatus)registerCustomAlarm:(AJTMTimeServiceServerAlarmBase*) alarmBusObj alarm:(id<AJTMTimeServiceServerAlarm>) alarm notAnnounced:(NSArray*) notAnnounced;

/**
 * Register user defined custom TimeServiceServerAlarm.
 * To register custom Alarm inherit from TimeServiceAlarmBusObj.
 * This method registers the given alarmBusObj and searches for the interfaces to be added to AboutService
 * and later announced.
 * To exclude interfaces from being announced, notAnnounced vector should be provided.
 * @param alarmBusObj Custom Alarm to be registered
 * @param alarm Methods of this TimeServiceServerAlarm are invoked
 * as a response to calls of the remote TimeServiceClient(s)
 * @param notAnnounced AllJoyn name of the interfaces that should NOT be announced. If this vector is empty,
 * all the found interfaces are added to the AboutService to be announced.
 * @param description Description to be added to the TimeServiceAlarmBusObject
 * Since description is provided, org.allseen.Introspectable interface is added to the announced interfaces
 * to support Events & Actions feature.
 * @param language The language of the description
 * @param translator If not NULL, TimeServiceAlarmBusObj is registered with Translator
 * to support the feature of AllSeenIntrospectable.GetDescriptionLanguages()
 * @return status of creating the alarm
 */
-(QStatus)registerCustomAlarm:(id<AJTMTimeServiceAlarmBusObj>) alarmBusObj alarm:(AJTMTimeServiceServerAlarmBase*) alarm notAnnounced:(NSArray*) notAnnounced description:(NSString*) description language:(NSString*) language translator:(id<AJNTranslator>) translator;

/**
 * Create Timer.
 *
 * @param timer Methods of this Timer are invoked
 * as a response to calls of the remote TimeServiceClient(s)
 * @return status of creating the timer
 */
-(QStatus)createTimer:(AJTMTimeServiceServerTimerBase*) timer;

/**
 * Create Timer with description.
 *
 * @param timer Methods of this TimeServiceServerTimer are invoked
 * as a response to calls of the remote TimeServiceClient(s)
 * @param description Description to be added to the object when registering TimeServiceServerTimer.
 * Since description is provided, org.allseen.Introspectable interface is added to the announced interfaces
 * to support Events & Actions feature.
 * @param language The language of the description
 * @param translator If not NULL, TimeServiceServerTimer is registered with Translator
 * to support the feature of AllSeenIntrospectable.GetDescriptionLanguages()
 * @return status of creating the timer
 */
-(QStatus)createTimer:(AJTMTimeServiceServerTimerBase*) timer description:(NSString*) description language:(NSString*) language translator:(id<AJNTranslator>) translator;

/**
 * Register user defined custom TimeServiceServerTimer.
 * To register custom Timer inherit from TimeServiceTimerBusObj.
 * This method registers the given timerBusObj and searches for the interfaces to be added to AboutService
 * and later announced.
 * To exclude interfaces from being announced, notAnnounced vector should be provided.
 * @param timerBusObj Custom Timer to be registered
 * @param timer Methods of this Timer are invoked
 * as a response to calls of the remote TimeServiceClient(s)
 * @param notAnnounced AllJoyn name of the interfaces that should NOT be announced. If this vector is empty,
 * all the found interfaces are added to the AboutService to be announced.
 * @return status of creating the timer
 */
-(QStatus)registerCustomTimer:(AJTMTimeServiceServerTimerBase*) timerBusObj timer:(id<AJTMTimeServiceServerTimer>) timer notAnnounced:(NSArray*) notAnnounced;//const std::vector<qcc::String>&

/**
 * Register user defined custom TimeServiceServerTimer.
 * To register custom Timer inherit from TimeServiceTimerBusObj.
 * This method registers the given timerBusObj and searches for the interfaces to be added to AboutService
 * and later announced.
 * To exclude interfaces from being announced, notAnnounced vector should be provided.
 * @param timerBusObj Custom Timer to be registered
 * @param timer Methods of this TimeServiceServerTimer are invoked
 * as a response to calls of the remote TimeServiceClient(s)
 * @param notAnnounced AllJoyn name of the interfaces that should NOT be announced. If this vector is empty,
 * all the found interfaces are added to the AboutService to be announced.
 * @param description Description to be added to the TimeServiceTimerBusObject
 * Since description is provided, org.allseen.Introspectable interface is added to the announced interfaces
 * to support Events & Actions feature.
 * @param language The language of the description
 * @param translator If not NULL, TimeServiceTimerBusObj is registered with Translator
 * to support the feature of AllSeenIntrospectable.GetDescriptionLanguages()
 * @return status of creating the timer
 */
-(QStatus)registerCustomTimer:(id<AJTMTimeServiceTimerBusObj>) timerBusObj timer:(AJTMTimeServiceServerTimerBase*) timer notAnnounced:(NSArray*) notAnnounced description:(NSString*) description language:(NSString*) language translator:(id<AJNTranslator>) translator;

/**
 * Create AlarmFactory.
 *
 * @param alarm Methods of this TimeServiceServerAlarmFactory are invoked
 * as a response to calls of the remote TimeServiceClient(s)
 * @return status of creating the AlarmFactory
 */
-(QStatus) createAlarmFactory:(AJTMTimeServiceServerAlarmFactoryBase*) alarmFactory;

/**
 * Create AlarmFactory with description.
 *
 * @param alarmFactory Methods of this TimeServiceServerAlarmFactory are invoked
 * as a response to calls of the remote TimeServiceClient(s)
 * @param description Description to be added to the object when TimeServiceServerAlarm is created
 * by the AlarmFactory.
 * Since description is provided, org.allseen.Introspectable interface is added to the announced interfaces
 * to support Events & Actions feature.
 * @param language The language of the description
 * @param translator If not NULL, Created TimeServiceServerAlarm is registered with Translator
 * to support the feature of AllSeenIntrospectable.GetDescriptionLanguages()
 *
 * @return status of creating the alarm
 */
-(QStatus) createAlarmFactory:(AJTMTimeServiceServerAlarmFactoryBase*) alarmFactory description:(NSString*) description language:(NSString*) language translator:(id<AJNTranslator>) translator;

/**
 * Create TimerFactory.
 *
 * @param timer Methods of this TimeServiceServerTimerFactory are invoked
 * as a response to calls of the remote TimeServiceClient(s)
 * @return status of creating the TimerFactory
 */
-(QStatus) createTimerFactory:(AJTMTimeServiceServerTimerFactoryBase*) timerFactory;

/**
 * Create TimerFactory with description.
 *
 * @param timerFactory Methods of this TimeServiceServerTimerFactory are invoked
 * as a response to calls of the remote TimeServiceClient(s)
 * @param description Description to be added to the object when TimeServiceServerTimer is created
 * by the TimerFactory.
 * Since description is provided, org.allseen.Introspectable interface is added to the announced interfaces
 * to support Events & Actions feature.
 * @param language The language of the description
 * @param translator If not NULL, Created TimeServiceServerTimer is registered with Translator
 * to support the feature of AllSeenIntrospectable.GetDescriptionLanguages()
 *
 * @return status of creating the timer
 */
-(QStatus) createTimerFactory:(AJTMTimeServiceServerTimerFactoryBase*) timerFactory description:(NSString*) description language:(NSString*) language translator:(id<AJNTranslator>) translator;

/**
 * Generate an object path.
 * To be called when creating a new instance of a custom alarm or timer.
 *
 * @param objectPath should contain the prefix for the object path, if status is ok the full object path is returned here.
 * @return status of creating the object path
 */
-(QStatus)generateObjectPath:(NSString*) objectPath;

@end


text:
.. highlight:: psql
.. _ref-set-license:

===============
``SET LICENSE``
===============

.. rubric:: Table of contents

.. contents::
    :local:

Synopsis
========

::

    SET LICENSE license_key

Description
===========

``SET LICENSE`` is a no-op statement (i.e., does nothing) and is supported for
backward compatibility with earlier versions of CrateDB.

Parameters
==========

License Key
-----------

The ``license_key`` parameter is ignored.

.. SEEALSO::

    :ref:`sys-cluster-license`


text:
<?php

namespace Symfony\Component\Form\Tests\ChoiceList\Factory;

use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\ChoiceList\ArrayChoiceList;
use Symfony\Component\Form\ChoiceList\ChoiceListInterface;
use Symfony\Component\Form\ChoiceList\Factory\ChoiceListFactoryInterface;
use Symfony\Component\Form\ChoiceList\Factory\PropertyAccessDecorator;
use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
use Symfony\Component\Form\ChoiceList\View\ChoiceListView;
use Symfony\Component\PropertyAccess\PropertyPath;

/**
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class PropertyAccessDecoratorTest extends TestCase
{
    /**
     * @var MockObject&ChoiceListFactoryInterface
     */
    private $decoratedFactory;

    /**
     * @var PropertyAccessDecorator
     */
    private $factory;

    protected function setUp(): void
    {
        $this->decoratedFactory = $this->createMock(ChoiceListFactoryInterface::class);
        $this->factory = new PropertyAccessDecorator($this->decoratedFactory);
    }

    public function testCreateFromChoicesPropertyPath()
    {
        $choices = [(object) ['property' => 'value']];

        $this->decoratedFactory->expects($this->once())
            ->method('createListFromChoices')
            ->with($choices, $this->isInstanceOf(\Closure::class))
            ->willReturnCallback(function ($choices, $callback) {
                return new ArrayChoiceList(array_map($callback, $choices));
            });

        $this->assertSame(['value' => 'value'], $this->factory->createListFromChoices($choices, 'property')->getChoices());
    }

    public function testCreateFromChoicesPropertyPathInstance()
    {
        $choices = [(object) ['property' => 'value']];

        $this->decoratedFactory->expects($this->once())
            ->method('createListFromChoices')
            ->with($choices, $this->isInstanceOf(\Closure::class))
            ->willReturnCallback(function ($choices, $callback) {
                return new ArrayChoiceList(array_map($callback, $choices));
            });

        $this->assertSame(['value' => 'value'], $this->factory->createListFromChoices($choices, new PropertyPath('property'))->getChoices());
    }

    public function testCreateFromChoicesFilterPropertyPath()
    {
        $filteredChoices = [
            'two' => (object) ['property' => 'value 2', 'filter' => true],
        ];
        $choices = [
            'one' => (object) ['property' => 'value 1', 'filter' => false],
        ] + $filteredChoices;

        $this->decoratedFactory->expects($this->once())
            ->method('createListFromChoices')
            ->with($choices, $this->isInstanceOf(\Closure::class), $this->isInstanceOf(\Closure::class))
            ->willReturnCallback(function ($choices, $value, $callback) {
                return new ArrayChoiceList(array_map($value, array_filter($choices, $callback)));
            });

        $this->assertSame(['value 2' => 'value 2'], $this->factory->createListFromChoices($choices, 'property', 'filter')->getChoices());
    }

    public function testCreateFromChoicesFilterPropertyPathInstance()
    {
        $filteredChoices = [
            'two' => (object) ['property' => 'value 2', 'filter' => true],
        ];
        $choices = [
                'one' => (object) ['property' => 'value 1', 'filter' => false],
        ] + $filteredChoices;

        $this->decoratedFactory->expects($this->once())
            ->method('createListFromChoices')
            ->with($choices, $this->isInstanceOf(\Closure::class), $this->isInstanceOf(\Closure::class))
            ->willReturnCallback(function ($choices, $value, $callback) {
                return new ArrayChoiceList(array_map($value, array_filter($choices, $callback)));
            });

        $this->assertSame(
            ['value 2' => 'value 2'],
            $this->factory->createListFromChoices($choices, new PropertyPath('property'), new PropertyPath('filter'))->getChoices()
        );
    }

    public function testCreateFromLoaderPropertyPath()
    {
        $loader = $this->createMock(ChoiceLoaderInterface::class);

        $this->decoratedFactory->expects($this->once())
            ->method('createListFromLoader')
            ->with($loader, $this->isInstanceOf(\Closure::class))
            ->willReturnCallback(function ($loader, $callback) {
                return new ArrayChoiceList((array) $callback((object) ['property' => 'value']));
            });

        $this->assertSame(['value' => 'value'], $this->factory->createListFromLoader($loader, 'property')->getChoices());
    }

    public function testCreateFromLoaderFilterPropertyPath()
    {
        $loader = $this->createMock(ChoiceLoaderInterface::class);
        $filteredChoices = [
            'two' => (object) ['property' => 'value 2', 'filter' => true],
        ];
        $choices = [
                'one' => (object) ['property' => 'value 1', 'filter' => false],
        ] + $filteredChoices;

        $this->decoratedFactory->expects($this->once())
            ->method('createListFromLoader')
            ->with($loader, $this->isInstanceOf(\Closure::class), $this->isInstanceOf(\Closure::class))
            ->willReturnCallback(function ($loader, $value, $callback) use ($choices) {
                return new ArrayChoiceList(array_map($value, array_filter($choices, $callback)));
            });

        $this->assertSame(['value 2' => 'value 2'], $this->factory->createListFromLoader($loader, 'property', 'filter')->getChoices());
    }

    // https://github.com/symfony/symfony/issues/5494
    public function testCreateFromChoicesAssumeNullIfValuePropertyPathUnreadable()
    {
        $choices = [null];

        $this->decoratedFactory->expects($this->once())
            ->method('createListFromChoices')
            ->with($choices, $this->isInstanceOf(\Closure::class))
            ->willReturnCallback(function ($choices, $callback) {
                return new ArrayChoiceList(array_map($callback, $choices));
            });

        $this->assertSame([null], $this->factory->createListFromChoices($choices, 'property')->getChoices());
    }

    // https://github.com/symfony/symfony/issues/5494
    public function testCreateFromChoiceLoaderAssumeNullIfValuePropertyPathUnreadable()
    {
        $loader = $this->createMock(ChoiceLoaderInterface::class);

        $this->decoratedFactory->expects($this->once())
            ->method('createListFromLoader')
            ->with($loader, $this->isInstanceOf(\Closure::class))
            ->willReturnCallback(function ($loader, $callback) {
                return new ArrayChoiceList((array) $callback(null));
            });

        $this->assertSame([], $this->factory->createListFromLoader($loader, 'property')->getChoices());
    }

    public function testCreateFromLoaderPropertyPathInstance()
    {
        $loader = $this->createMock(ChoiceLoaderInterface::class);

        $this->decoratedFactory->expects($this->once())
            ->method('createListFromLoader')
            ->with($loader, $this->isInstanceOf(\Closure::class))
            ->willReturnCallback(function ($loader, $callback) {
                return new ArrayChoiceList((array) $callback((object) ['property' => 'value']));
            });

        $this->assertSame(['value' => 'value'], $this->factory->createListFromLoader($loader, new PropertyPath('property'))->getChoices());
    }

    public function testCreateViewPreferredChoicesAsPropertyPath()
    {
        $list = $this->createMock(ChoiceListInterface::class);

        $this->decoratedFactory->expects($this->once())
            ->method('createView')
            ->with($list, $this->isInstanceOf(\Closure::class))
            ->willReturnCallback(function ($list, $preferred) {
                return new ChoiceListView((array) $preferred((object) ['property' => true]));
            });

        $this->assertSame([true], $this->factory->createView($list, 'property')->choices);
    }

    public function testCreateViewPreferredChoicesAsPropertyPathInstance()
    {
        $list = $this->createMock(ChoiceListInterface::class);

        $this->decoratedFactory->expects($this->once())
            ->method('createView')
            ->with($list, $this->isInstanceOf(\Closure::class))
            ->willReturnCallback(function ($list, $preferred) {
                return new ChoiceListView((array) $preferred((object) ['property' => true]));
            });

        $this->assertSame([true], $this->factory->createView($list, 'property')->choices);
    }

    // https://github.com/symfony/symfony/issues/5494
    public function testCreateViewAssumeNullIfPreferredChoicesPropertyPathUnreadable()
    {
        $list = $this->createMock(ChoiceListInterface::class);

        $this->decoratedFactory->expects($this->once())
            ->method('createView')
            ->with($list, $this->isInstanceOf(\Closure::class))
            ->willReturnCallback(function ($list, $preferred) {
                return new ChoiceListView((array) $preferred((object) ['category' => null]));
            });

        $this->assertSame([false], $this->factory->createView($list, 'category.preferred')->choices);
    }

    public function testCreateViewLabelsAsPropertyPath()
    {
        $list = $this->createMock(ChoiceListInterface::class);

        $this->decoratedFactory->expects($this->once())
            ->method('createView')
            ->with($list, null, $this->isInstanceOf(\Closure::class))
            ->willReturnCallback(function ($list, $preferred, $label) {
                return new ChoiceListView((array) $label((object) ['property' => 'label']));
            });

        $this->assertSame(['label'], $this->factory->createView($list, null, 'property')->choices);
    }

    public function testCreateViewLabelsAsPropertyPathInstance()
    {
        $list = $this->createMock(ChoiceListInterface::class);

        $this->decoratedFactory->expects($this->once())
            ->method('createView')
            ->with($list, null, $this->isInstanceOf(\Closure::class))
            ->willReturnCallback(function ($list, $preferred, $label) {
                return new ChoiceListView((array) $label((object) ['property' => 'label']));
            });

        $this->assertSame(['label'], $this->factory->createView($list, null, new PropertyPath('property'))->choices);
    }

    public function testCreateViewIndicesAsPropertyPath()
    {
        $list = $this->createMock(ChoiceListInterface::class);

        $this->decoratedFactory->expects($this->once())
            ->method('createView')
            ->with($list, null, null, $this->isInstanceOf(\Closure::class))
            ->willReturnCallback(function ($list, $preferred, $label, $index) {
                return new ChoiceListView((array) $index((object) ['property' => 'index']));
            });

        $this->assertSame(['index'], $this->factory->createView($list, null, null, 'property')->choices);
    }

    public function testCreateViewIndicesAsPropertyPathInstance()
    {
        $list = $this->createMock(ChoiceListInterface::class);

        $this->decoratedFactory->expects($this->once())
            ->method('createView')
            ->with($list, null, null, $this->isInstanceOf(\Closure::class))
            ->willReturnCallback(function ($list, $preferred, $label, $index) {
                return new ChoiceListView((array) $index((object) ['property' => 'index']));
            });

        $this->assertSame(['index'], $this->factory->createView($list, null, null, new PropertyPath('property'))->choices);
    }

    public function testCreateViewGroupsAsPropertyPath()
    {
        $list = $this->createMock(ChoiceListInterface::class);

        $this->decoratedFactory->expects($this->once())
            ->method('createView')
            ->with($list, null, null, null, $this->isInstanceOf(\Closure::class))
            ->willReturnCallback(function ($list, $preferred, $label, $index, $groupBy) {
                return new ChoiceListView((array) $groupBy((object) ['property' => 'group']));
            });

        $this->assertSame(['group'], $this->factory->createView($list, null, null, null, 'property')->choices);
    }

    public function testCreateViewGroupsAsPropertyPathInstance()
    {
        $list = $this->createMock(ChoiceListInterface::class);

        $this->decoratedFactory->expects($this->once())
            ->method('createView')
            ->with($list, null, null, null, $this->isInstanceOf(\Closure::class))
            ->willReturnCallback(function ($list, $preferred, $label, $index, $groupBy) {
                return new ChoiceListView((array) $groupBy((object) ['property' => 'group']));
            });

        $this->assertSame(['group'], $this->factory->createView($list, null, null, null, new PropertyPath('property'))->choices);
    }

    // https://github.com/symfony/symfony/issues/5494
    public function testCreateViewAssumeNullIfGroupsPropertyPathUnreadable()
    {
        $list = $this->createMock(ChoiceListInterface::class);

        $this->decoratedFactory->expects($this->once())
            ->method('createView')
            ->with($list, null, null, null, $this->isInstanceOf(\Closure::class))
            ->willReturnCallback(function ($list, $preferred, $label, $index, $groupBy) {
                return new ChoiceListView((array) $groupBy((object) ['group' => null]));
            });

        $this->assertSame([], $this->factory->createView($list, null, null, null, 'group.name')->choices);
    }

    public function testCreateViewAttrAsPropertyPath()
    {
        $list = $this->createMock(ChoiceListInterface::class);

        $this->decoratedFactory->expects($this->once())
            ->method('createView')
            ->with($list, null, null, null, null, $this->isInstanceOf(\Closure::class))
            ->willReturnCallback(function ($list, $preferred, $label, $index, $groupBy, $attr) {
                return new ChoiceListView((array) $attr((object) ['property' => 'attr']));
            });

        $this->assertSame(['attr'], $this->factory->createView($list, null, null, null, null, 'property')->choices);
    }

    public function testCreateViewAttrAsPropertyPathInstance()
    {
        $list = $this->createMock(ChoiceListInterface::class);

        $this->decoratedFactory->expects($this->once())
            ->method('createView')
            ->with($list, null, null, null, null, $this->isInstanceOf(\Closure::class))
            ->willReturnCallback(function ($list, $preferred, $label, $index, $groupBy, $attr) {
                return new ChoiceListView((array) $attr((object) ['property' => 'attr']));
            });

        $this->assertSame(['attr'], $this->factory->createView($list, null, null, null, null, new PropertyPath('property'))->choices);
    }
}