text:
:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:

The following is a set of guidelines for contributing to NodeMCU on GitHub. These are just guidelines, not rules, use your best judgment and feel free to propose changes to this document in a pull request.

It is appreciated but optional if you raise an issue _before_ you start changing NodeMCU, discussing the proposed change; emphasising that the you are proposing to develop the patch yourself, and outling the strategy for implementation. This type of discussion is what we should be doing on the issues list and it is better to do this before or in parallel to developing the patch rather than having "you should have done it this way" type of feedback on the PR itself.

### Table Of Contents

* [Development environment setup](#development-environment-setup)
* [Writing Documentation](#writing-documentation)
* [Working with Git and GitHub](#working-with-git-and-github)
  * [General flow](#general-flow)
  * [Keeping your fork in sync](#keeping-your-fork-in-sync)
  * [Commit messages](#commit-messages)

## Development environment setup
Use the platform and tools you feel most comfortable with. There are  no constraints imposed by this project. You have (at least) two options to set up the toolchain to build the NodeMCU firmware:
- [Full-fledged Linux enviroment](http://www.esp8266.com/wiki/doku.php?id=toolchain#how_to_setup_a_vm_to_host_your_toolchain), either physical or virtual.
- [Docker image](https://hub.docker.com/r/marcelstoer/nodemcu-build/) which allows to run the build inside the container as if you were running a build script on your local machine.

## Writing Documentation
The NodeMCU documentation is maintained within the same repository as the code. The primary reason is to keep the two in sync more easily. It's thus trivial for the NodeMCU team to verify that a PR includes the necessary documentation. Furthermore, the documentation is merged automatically with the code if it moves from branch X to Y.

The documentation consists of a collection of Markdown files (see note on Markdown syntax at end of chapter) stored in the [`/docs`](docs) directory. With every commit a human readable and browsable version is automatically built with [Read the Docs](https://readthedocs.io/) (RTD). The public NodeMCU documentation can be found at [nodemcu.readthedocs.io](http://nodemcu.readthedocs.io/).

There are essentially only two things to keep in mind if you're contributing a PR:

- If you add functions to or change functions of an *existing module* you should modify the module's `.md` file in [`/docs/en/modules`](docs/en/modules). Adhere to the existing documentation structure and keep functions in alphabetical order.
- If you add a *new module* you should, in addition to the above, also add a reference for the new `.md` file to [`mkdocs.yml`](./mkdocs.yml) (lines 32+). Note that modules are ordered alphabetically here as well.

If you also want to verify that all is well with your Markdown files you can install Python-based [MkDocs](http://www.mkdocs.org/), which is used by RTD to build the static HTML files, and run `mkdocs serve` in the root of your NodeMCU firmware directory.

A note on Markdown *syntax*. As Mkdocs is Python-based it's no surprise it uses a [Python Markdown implementation](https://pythonhosted.org/Markdown/). The good news is that it sticks pretty closely to John Gruber's Markdown and also [supports tables and fenced code blocks](http://www.mkdocs.org/user-guide/writing-your-docs/#markdown-extensions) just like GitHub does.

A collection of doc-writing hints and tips is maintained on the [wiki](https://github.com/nodemcu/nodemcu-firmware/wiki/Notes-about-writing-docs).

If you're interested in some NodeMCU history you're welcome to read [issue #774](https://github.com/nodemcu/nodemcu-firmware/issues/774)

## Working with Git and GitHub

*Pull requests for new features and major fixes should be opened against the `dev` branch.*

Avoid intermediate merge commits. [Rebase](https://www.atlassian.com/git/tutorials/merging-vs-rebasing) your feature branch onto `dev` to pull updates and verify your local changes against them before placing the pull request.

### General flow
1. [Fork](https://help.github.com/articles/fork-a-repo) the NodeMCU repo on GitHub.
1. [Create a branch](https://help.github.com/articles/creating-and-deleting-branches-within-your-repository/#creating-a-branch) in your fork on GitHub **based on the `dev` branch**.
1. Clone the fork on your machine with `git clone https://github.com/<your-account>/<nodemcu-fork>.git`
1. `cd <nodemcu-fork>` then run `git remote add upstream https://github.com/nodemcu/nodemcu-firmware.git`
1. `git checkout <branch-name>`
1. Make changes to the code base and commit them using e.g. `git commit -a -m 'Look ma, I did it'`
1. When you're done:
 1. [Squash your commits](http://www.andrewconnell.com/blog/squash-multiple-git-commits-into-one) into one. There are [several ways](http://stackoverflow.com/a/5201642/131929) of doing this.
 1. Bring your fork up-to-date with the NodeMCU upstream repo ([see below](#keeping-your-fork-in-sync)). Then rebase your branch on `dev` running `git rebase dev`.
1. `git push`
1. [Create a pull request](https://help.github.com/articles/creating-a-pull-request/) (PR) on GitHub.

This is just one way of doing things. If you're proficient in Git matters you're free to choose your own. If you want to read more then the [GitHub chapter in the Git book](http://git-scm.com/book/en/v2/GitHub-Contributing-to-a-Project#The-GitHub-Flow) is a way to start. [GitHub's own documenation](https://help.github.com/categories/collaborating/) contains a wealth of information as well.

### Keeping your fork in sync
You need to sync your fork with the NodeMCU upstream repository from time to time, latest before you rebase (see flow above).

1. `git fetch upstream`
1. `git checkout dev` but you may do this for `master` as well
1. `git merge upstream/dev`

### Commit messages

From: [http://git-scm.com/book/ch5-2.html](http://git-scm.com/book/ch5-2.html)
<pre>
Short (50 chars or less) summary of changes

More detailed explanatory text, if necessary.  Wrap it to about 72
characters or so.  In some contexts, the first line is treated as the
subject of an email and the rest of the text as the body.  The blank
line separating the summary from the body is critical (unless you omit
the body entirely); tools like rebase can get confused if you run the
two together.

Further paragraphs come after blank lines.

 - Bullet points are okay, too

 - Typically a hyphen or asterisk is used for the bullet, preceded by a
   single space, with blank lines in between, but conventions vary here
</pre>

Don't forget to [reference affected issues](https://help.github.com/articles/closing-issues-via-commit-messages/) in the commit message to have them closed automatically on GitHub.

[Amend](https://help.github.com/articles/changing-a-commit-message/) your commit messages if necessary to make sure what the world sees on GitHub is as expressive and meaningful as possible.


text:
/**
 *
 */
package org.apache.hadoop.hdfs.server.protocol;

import org.apache.hadoop.ipc.VersionedProtocol;

/**
 *
 * Interface for communication between FBTs at nodes
 * @author hanhlh
 *
 */
public interface FBTProtocol extends VersionedProtocol {

	public static final long versionID = 1L;

}

redpajama_set_name: RedPajamaGithub


text:
#pragma once

#ifndef _ZSUMMER_PUBLIC_H_
#define _ZSUMMER_PUBLIC_H_
#define _WIN32_WINNT 0x501

#include "../../utility/utility.h"
#include "../../depends/thread4z/thread.h"
#include "../../depends/log4z/log4z.h"
#include "../../network/SocketInterface.h"
#include <assert.h>
#include <string>
#include <iostream>
#include <map>
#include <list>
#include <queue>
#include <Mswsock.h>
#include <WinSock2.h>
#include <Windows.h>

namespace zsummer
{
	struct tagReqHandle
	{
		OVERLAPPED	 _overlapped;
		unsigned char _type;
		enum
		{
			HANDLE_ACCEPT,
			HANDLE_RECV,
			HANDLE_SEND,
			HANDLE_CONNECT,
			HANDLE_RECVFROM,
			HANDLE_SENDTO,
		};
	};

	enum LINK_STATUS
	{
		LS_UNINITIALIZE,
		LS_ESTABLISHED,
		LS_WAITCLOSE,
		LS_WAITCLEAR,
	};

	enum POST_COM_KEY
	{
		PCK_ACCEPT_CLOSE = 1,
		PCK_SOCKET_CLOSE,
		PCK_USER_DATA,
	};

	class CInitWSASocketEnv
	{
	public:
		CInitWSASocketEnv();
		~CInitWSASocketEnv();
	};
}
extern LoggerId g_coreID;
extern zsummer::CInitWSASocketEnv appInitSocket;

#define LCD( log ) LOG_DEBUG( g_coreID, log )
#define LCI( log ) LOG_INFO( g_coreID, log )
#define LCW( log ) LOG_WARN( g_coreID, log )
#define LCE( log ) LOG_ERROR( g_coreID, log )
#define LCA( log ) LOG_ALARM( g_coreID, log )
#define LCF( log ) LOG_FATAL( g_coreID, log )

#endif


text:
<link rel="stylesheet" href="static/css/bulma.css"/>
<link rel="stylesheet" href="static/css/ion.rangeSlider.css"/>
<link rel="stylesheet" href="static/css/font-awesome.min.css"/>
<link rel="stylesheet" href="static/css/custom.css"/>

<script src="static/js/jquery.min.js"></script>
<script src="static/js/ion.rangeSlider.min.js"></script>
<script src="static/js/main.js"></script>


text:
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.vfs.impl.local;

import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.LocalFileSystem.WatchRequest;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import org.jetbrains.annotations.*;

import java.io.File;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

/**
 * Unless stated otherwise, all paths are {@link SystemIndependent @SystemIndependent}.
 */
final class WatchRootsManager {
  private static final Logger LOG = Logger.getInstance(WatchRootsManager.class);

  private final FileWatcher myFileWatcher;

  private final NavigableMap<String, List<WatchRequest>> myRecursiveWatchRoots = WatchRootsUtil.createFileNavigableMap();
  private final NavigableMap<String, List<WatchRequest>> myFlatWatchRoots = WatchRootsUtil.createFileNavigableMap();
  private final NavigableSet<String> myOptimizedRecursiveWatchRoots = WatchRootsUtil.createFileNavigableSet();
  private final NavigableMap<String, SymlinkData> mySymlinksByPath = WatchRootsUtil.createFileNavigableMap();
  private final Int2ObjectMap<SymlinkData> mySymlinksById = new Int2ObjectOpenHashMap<>();
  private final NavigableSet<Pair<String, String>> myPathMappings = WatchRootsUtil.createMappingsNavigableSet();

  @SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized") private boolean myWatcherRequiresUpdate;  // synchronized on `myLock`
  private final Object myLock = new Object();

  WatchRootsManager(@NotNull FileWatcher fileWatcher, @NotNull Disposable parent) {
    myFileWatcher = fileWatcher;
    ApplicationManager.getApplication().getMessageBus().connect(parent).subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener() {
      @Override
      public void after(@NotNull List<? extends @NotNull VFileEvent> events) {
        synchronized (myLock) {
          if (myWatcherRequiresUpdate) {
            updateFileWatcher();
          }
        }
      }
    });
  }

  @NotNull Set<WatchRequest> replaceWatchedRoots(@NotNull Collection<WatchRequest> requestsToRemove,
                                                 @NotNull Collection<String> recursiveRootsToAdd,
                                                 @NotNull Collection<String> flatRootsToAdd) {
    Set<WatchRequest> recursiveRequestsToRemove = new HashSet<>(), flatRequestsToRemove = new HashSet<>();
    requestsToRemove.forEach(req -> (req.isToWatchRecursively() ? recursiveRequestsToRemove : flatRequestsToRemove).add(req));

    Set<WatchRequest> result = new HashSet<>(recursiveRootsToAdd.size() + flatRootsToAdd.size());

    synchronized (myLock) {
      updateWatchRoots(recursiveRootsToAdd, recursiveRequestsToRemove, result, myRecursiveWatchRoots, true);
      updateWatchRoots(flatRootsToAdd, flatRequestsToRemove, result, myFlatWatchRoots, false);
      if (myWatcherRequiresUpdate) {
        updateFileWatcher();
      }
    }

    return result;
  }

  void clear() {
    synchronized (myLock) {
      myRecursiveWatchRoots.clear();
      myOptimizedRecursiveWatchRoots.clear();
      myFlatWatchRoots.clear();
      myPathMappings.clear();
      mySymlinksById.values().forEach(SymlinkData::clear);
    }
  }

  void updateSymlink(int fileId, @NotNull String linkPath, @Nullable String linkTarget) {
    synchronized (myLock) {
      SymlinkData data = mySymlinksById.get(fileId);
      if (data != null) {
        if (FileUtil.pathsEqual(data.path, linkPath) && FileUtil.pathsEqual(data.target, linkTarget)) {
          // Avoid costly removal and re-addition of the request in case of no-op update
          return;
        }
        mySymlinksById.remove(fileId);
        mySymlinksByPath.remove(data.path);
        data.removeRequest(this);
      }

      data = new SymlinkData(fileId, linkPath, linkTarget);

      SymlinkData existing = mySymlinksByPath.get(linkPath);
      if (existing != null) {
        LOG.error("Path conflict. Existing symlink: " + existing + " vs. new symlink: " + data);
        return;
      }

      mySymlinksByPath.put(data.path, data);
      mySymlinksById.put(data.id, data);
      if (data.hasValidTarget()
          && WatchRootsUtil.isCoveredRecursively(myOptimizedRecursiveWatchRoots, data.path)) {
        addWatchSymlinkRequest(data.getWatchRequest());
      }
    }
  }

  void removeSymlink(int fileId) {
    synchronized (myLock) {
      SymlinkData data = mySymlinksById.remove(fileId);
      if (data != null) {
        mySymlinksByPath.remove(data.path);
        data.removeRequest(this);
      }
    }
  }

  private void updateFileWatcher() {
    myFileWatcher.setWatchRoots(() -> {
      synchronized (myLock) {
        if (!myWatcherRequiresUpdate) return null;
        myWatcherRequiresUpdate = false;
        return createCanonicalPathMap(myFlatWatchRoots.navigableKeySet(), myOptimizedRecursiveWatchRoots,
                                      myPathMappings, File.separatorChar == '\\');
      }
    });
  }

  @NotNull
  static CanonicalPathMap createCanonicalPathMap(@NotNull Set<String> flatWatchRoots,
                                                 @NotNull Set<String> optimizedRecursiveWatchRoots,
                                                 @NotNull Collection<Pair<String, String>> pathMappings,
                                                 boolean convertToForwardSlashes) {
    NavigableSet<@SystemDependent String> optimizedRecursiveWatchRootsCopy = WatchRootsUtil.createFileNavigableSet();
    List<Pair<@SystemDependent String, @SystemDependent String>> initialMappings = new ArrayList<>(pathMappings.size());

    // Ensure paths are system dependent
    if (!convertToForwardSlashes) {
      optimizedRecursiveWatchRootsCopy.addAll(optimizedRecursiveWatchRoots);
      initialMappings.addAll(pathMappings);
    }
    else {
      for (String recursiveWatchRoot: optimizedRecursiveWatchRoots) {
        optimizedRecursiveWatchRootsCopy.add(recursiveWatchRoot.replace('/', '\\'));
      }
      for (Pair<String, String> mapping: pathMappings) {
        initialMappings.add(new Pair<>(mapping.first.replace('/', '\\'),
                                       mapping.second.replace('/', '\\')));
      }
    }
    NavigableSet<@SystemDependent String> optimizedFlatWatchRoots =
      WatchRootsUtil.optimizeFlatRoots(flatWatchRoots, optimizedRecursiveWatchRootsCopy, convertToForwardSlashes);
    return new CanonicalPathMap(optimizedRecursiveWatchRootsCopy, optimizedFlatWatchRoots, initialMappings);
  }

  private void updateWatchRoots(@NotNull Collection<String> rootsToAdd,
                                @NotNull Set<WatchRequest> requestsToRemove,
                                @NotNull Set<WatchRequest> result,
                                @NotNull Map<String, List<WatchRequest>> roots,
                                boolean recursiveWatchRoots) {
    List<WatchSymlinkRequest> watchSymlinkRequestsToAdd = new SmartList<>();
    for (String root : rootsToAdd) {
      String watchRoot = prepareWatchRoot(root);
      if (watchRoot == null) continue;

      List<WatchRequest> requests = roots.computeIfAbsent(watchRoot, (key) -> new SmartList<>());
      boolean foundSameRequest = false;
      if (!requestsToRemove.isEmpty()) {
        for (WatchRequest currentRequest : requests) {
          if (requestsToRemove.remove(currentRequest)) {
            foundSameRequest = true;
            result.add(currentRequest);
          }
        }
      }

      if (!foundSameRequest) {
        WatchRequestImpl newRequest = new WatchRequestImpl(watchRoot, recursiveWatchRoots);
        requests.add(newRequest);
        result.add(newRequest);
        if (recursiveWatchRoots) {
          collectSymlinkRequests(newRequest, watchSymlinkRequestsToAdd);
        }
        if (requests.size() == 1 && !WatchRootsUtil.isCoveredRecursively(myOptimizedRecursiveWatchRoots, watchRoot)) {
          myWatcherRequiresUpdate = true;
          if (recursiveWatchRoots) {
            WatchRootsUtil.insertRecursivePath(myOptimizedRecursiveWatchRoots, watchRoot);
          }
        }
      }
    }

    List<WatchSymlinkRequest> watchSymlinkRequestsToRemove = new SmartList<>();
    for (WatchRequest request : requestsToRemove) {
      removeWatchRequest(request);
      if (recursiveWatchRoots) {
        collectSymlinkRequests((WatchRequestImpl)request, watchSymlinkRequestsToRemove);
      }
    }

    if (recursiveWatchRoots) {
      addWatchSymlinkRequests(watchSymlinkRequestsToAdd);
      removeWatchSymlinkRequests(watchSymlinkRequestsToRemove);
    }
  }

  private static @Nullable String prepareWatchRoot(@NotNull String root) {
    int index = root.indexOf(JarFileSystem.JAR_SEPARATOR);
    if (index >= 0) root = root.substring(0, index);
    try {
      Path rootPath = Paths.get(FileUtil.toSystemDependentName(root));
      if (!rootPath.isAbsolute()) {
        throw new InvalidPathException(root, "Watch roots should be absolute");
      }
      return FileUtil.toSystemIndependentName(rootPath.toString());
    }
    catch (InvalidPathException e) {
      LOG.warn("invalid watch root", e);
      return null;
    }
  }

  private void removeWatchRequest(@NotNull WatchRequest request) {
    String watchRoot = request.getRootPath();
    Map<String, List<WatchRequest>> roots = request.isToWatchRecursively() ? myRecursiveWatchRoots : myFlatWatchRoots;
    List<WatchRequest> requests = roots.get(watchRoot);
    if (requests != null) {
      requests.remove(request);
      if (requests.isEmpty()) {
        roots.remove(watchRoot);
        if (request.isToWatchRecursively()) {
          if (WatchRootsUtil.removeRecursivePath(myOptimizedRecursiveWatchRoots, myRecursiveWatchRoots, watchRoot)) {
            myWatcherRequiresUpdate = true;
          }
        }
        else if (!WatchRootsUtil.isCoveredRecursively(myOptimizedRecursiveWatchRoots, watchRoot)) {
          myWatcherRequiresUpdate = true;
        }
      }
    }
  }

  private void addWatchSymlinkRequests(@NotNull List<WatchSymlinkRequest> watchSymlinkRequestsToAdd) {
    for (WatchSymlinkRequest request : watchSymlinkRequestsToAdd) {
      if (!request.getRootPath().isEmpty() && !request.isRegistered()) {
        addWatchSymlinkRequest(request);
      }
    }
  }

  private void addWatchSymlinkRequest(@NotNull WatchSymlinkRequest request) {
    String watchRoot = request.getRootPath();
    Map<String, List<WatchRequest>> roots = request.isToWatchRecursively() ? myRecursiveWatchRoots : myFlatWatchRoots;
    List<WatchRequest> requests = roots.computeIfAbsent(watchRoot, (key) -> new SmartList<>());
    requests.add(request);
    if (requests.size() == 1 && !WatchRootsUtil.isCoveredRecursively(myOptimizedRecursiveWatchRoots, watchRoot)) {
      if (request.isToWatchRecursively()) {
        WatchRootsUtil.insertRecursivePath(myOptimizedRecursiveWatchRoots, watchRoot);
      }
    }
    if (request.setRegistered(true)) {
      myWatcherRequiresUpdate = true;
      myPathMappings.add(new Pair<>(watchRoot, request.getOriginalPath()));
    }
  }

  private void removeWatchSymlinkRequests(@NotNull List<WatchSymlinkRequest> watchSymlinkRequestsToRemove) {
    for (WatchSymlinkRequest request : watchSymlinkRequestsToRemove) {
      Ref<Boolean> remove = new Ref<>(true);
      WatchRootsUtil.forEachPathSegment(request.getOriginalPath(), '/', path -> {
        List<WatchRequest> requests = myRecursiveWatchRoots.get(path);
        if (requests != null && ContainerUtil.findInstance(requests, WatchRequestImpl.class) != null) {
          remove.set(false);
          return false;
        }
        return true;
      });
      if (remove.get()) {
        removeWatchSymlinkRequest(request);
      }
    }
  }

  private void removeWatchSymlinkRequest(@NotNull WatchSymlinkRequest request) {
    if (!request.isRegistered()) {
      return;
    }
    removeWatchRequest(request);
    if (request.setRegistered(false)) {
      myPathMappings.remove(new Pair<>(request.getRootPath(), request.getOriginalPath()));
      myWatcherRequiresUpdate = true;
    }
  }

  private void collectSymlinkRequests(@NotNull WatchRequestImpl newRequest,
                                      @NotNull Collection<WatchSymlinkRequest> watchSymlinkRequestsToAdd) {
    assert newRequest.isToWatchRecursively() : newRequest;
    WatchRootsUtil.collectByPrefix(mySymlinksByPath, newRequest.getRootPath(), e -> {
      if (e.getValue().hasValidTarget()) {
        watchSymlinkRequestsToAdd.add(e.getValue().getWatchRequest());
      }
    });
  }

  private static class WatchRequestImpl implements WatchRequest {
    private final String myFSRootPath;
    private final boolean myWatchRecursively;

    WatchRequestImpl(@NotNull String rootPath, boolean watchRecursively) {
      myFSRootPath = rootPath;
      myWatchRecursively = watchRecursively;
    }

    @Override
    public @NotNull @SystemIndependent String getRootPath() {
      return myFSRootPath;
    }

    @Override
    public boolean isToWatchRecursively() {
      return myWatchRecursively;
    }

    @Override
    public String toString() {
      return getRootPath();
    }
  }

  private static class WatchSymlinkRequest implements WatchRequest {
    private final SymlinkData mySymlinkData;
    private final boolean myWatchRecursively;
    private boolean myRegistered = false;

    WatchSymlinkRequest(@NotNull SymlinkData data, boolean watchRecursively) {
      mySymlinkData = data;
      assert mySymlinkData.hasValidTarget();
      myWatchRecursively = watchRecursively;
    }

    boolean isRegistered() {
      return myRegistered;
    }

    boolean setRegistered(boolean registered) {
      if (myRegistered != registered) {
        myRegistered = registered;
        return true;
      }
      return false;
    }

    @Override
    public @NotNull @SystemIndependent String getRootPath() {
      return Objects.requireNonNull(mySymlinkData.target);
    }

    @Override
    public boolean isToWatchRecursively() {
      return myWatchRecursively;
    }

    String getOriginalPath() {
      return mySymlinkData.path;
    }
  }

  private static class SymlinkData {
    final int id;
    final @NotNull @SystemIndependent String path;
    final @Nullable @SystemIndependent String target;
    private WatchSymlinkRequest myWatchRequest;

    SymlinkData(int id, @NotNull String path, @Nullable String target) {
      this.id = id;
      this.path = FileUtil.toSystemIndependentName(path);
      this.target = target != null ? FileUtil.toSystemIndependentName(target) : null;
    }

    @NotNull WatchSymlinkRequest getWatchRequest() {
      assert hasValidTarget();
      if (myWatchRequest == null) {
        myWatchRequest = new WatchSymlinkRequest(this, true);
      }
      return myWatchRequest;
    }

    boolean hasValidTarget() {
      return target != null;
    }

    void removeRequest(@NotNull WatchRootsManager manager) {
      if (myWatchRequest != null) {
        manager.removeWatchSymlinkRequest(myWatchRequest);
        myWatchRequest = null;
      }
    }

    void clear() {
      myWatchRequest = null;
    }

    @Override
    @NonNls
    public String toString() {
      return "SymlinkData{" + id + ", " + path + " -> " + target + '}';
    }
  }
}


text:
package com.github.dannil.scbjavaclient.client.financialmarkets.balanceofpayments.economicindicators;

import static org.junit.jupiter.api.Assertions.assertNotEquals;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import com.github.dannil.scbjavaclient.test.extensions.Date;
import com.github.dannil.scbjavaclient.test.extensions.Remote;
import com.github.dannil.scbjavaclient.test.extensions.Suite;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

@Suite
@Remote
public class FinancialMarketsBalanceOfPaymentsEconomicIndicatorsClientIT {

    private FinancialMarketsBalanceOfPaymentsEconomicIndicatorsClient client;

    @BeforeEach
    public void setup() {
        this.client = new FinancialMarketsBalanceOfPaymentsEconomicIndicatorsClient();
    }

    @Test
    @Date("2018-06-05")
    public void getBalanceOfPaymentsNet() {
        assertNotEquals(0, this.client.getBalanceOfPaymentsNet().size());
    }

    @Test
    @Date("2018-06-05")
    public void getBalanceOfPaymentsNetWithParametersEmptyLists() {
        assertNotEquals(0, this.client.getBalanceOfPaymentsNet(Collections.<String>emptyList(),
                Collections.<String>emptyList()).size());
    }

    @Test
    @Date("2018-06-05")
    public void getBalanceOfPaymentsNetWithParameters() {
        List<String> indicators = Arrays.asList("FM120", "FM140");
        List<String> quarters = Arrays.asList("2017K4", "2018K1");

        assertNotEquals(0, this.client.getBalanceOfPaymentsNet(indicators, quarters).size());
    }

}


text:
package com.thoughtworks.go.domain;

import java.util.ArrayList;
import java.util.List;

import com.thoughtworks.go.domain.config.Configuration;
import com.thoughtworks.go.domain.config.ConfigurationProperty;
import com.thoughtworks.go.plugin.access.config.PluginPreferenceStore;
import com.thoughtworks.go.plugin.access.packagematerial.PackageConfiguration;
import org.apache.commons.lang3.StringUtils;

public class ConfigurationDisplayUtil {
    public static List<ConfigurationProperty> getConfigurationPropertiesToBeUsedForDisplay(PluginPreferenceStore metadataStore, String pluginId, final Configuration configuration) {
        List<ConfigurationProperty> keysForDisplay = new ArrayList<>();
        boolean pluginDoesNotExist = !metadataStore.hasPreferenceFor(pluginId);

        for (ConfigurationProperty property : configuration) {
            boolean isNotASecureProperty = !property.isSecure();
            boolean isPartOfIdentity = metadataStore.hasOption(pluginId, property.getConfigurationKey().getName(), PackageConfiguration.PART_OF_IDENTITY);
            if (isNotASecureProperty && !StringUtils.isBlank(property.getValue()) && (pluginDoesNotExist || isPartOfIdentity)) {
                keysForDisplay.add(property);
            }
        }
        return keysForDisplay;
    }
}


text:
package org.quartz.examples.example1;

import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerUtils;
import org.quartz.impl.StdSchedulerFactory;

/**
 * This Example will demonstrate how to start and shutdown the Quartz
 * scheduler and how to schedule a job to run in Quartz.
 *
 * @author Bill Kratzer
 */
public class SimpleExample {

    public void run() throws Exception {
        Logger log = LoggerFactory.getLogger(SimpleExample.class);

        log.info("------- Initializing ----------------------");

        // First we must get a reference to a scheduler
        SchedulerFactory sf = new StdSchedulerFactory();
        Scheduler sched = sf.getScheduler();

        log.info("------- Initialization Complete -----------");

        log.info("------- Scheduling Jobs -------------------");

        // computer a time that is on the next round minute
        Date runTime = TriggerUtils.getEvenMinuteDate(new Date());

        // define the job and tie it to our HelloJob class
        JobDetail job = new JobDetail("job1", "group1", HelloJob.class);

        // Trigger the job to run on the next round minute
        SimpleTrigger trigger =
            new SimpleTrigger("trigger1", "group1", runTime);

        // Tell quartz to schedule the job using our trigger
        sched.scheduleJob(job, trigger);
        log.info(job.getFullName() + " will run at: " + runTime);

        // Start up the scheduler (nothing can actually run until the
        // scheduler has been started)
        sched.start();
        log.info("------- Started Scheduler -----------------");

        // wait long enough so that the scheduler as an opportunity to
        // run the job!
        log.info("------- Waiting 90 seconds... -------------");
        try {
            // wait 90 seconds to show jobs
            Thread.sleep(90L * 1000L);
            // executing...
        } catch (Exception e) {
        }

        // shut down the scheduler
        log.info("------- Shutting Down ---------------------");
        sched.shutdown(true);
        log.info("------- Shutdown Complete -----------------");
    }

    public static void main(String[] args) throws Exception {

        SimpleExample example = new SimpleExample();
        example.run();

    }

}


text:
Discussion at https://golang.org/issue/12750.

## Abstract
This proposal gives a big-picture overview of localization support for
Go, explaining how all pieces fit together.
It is intended as a guide to designing the individual packages and to allow
catching design issues early.

## Background
Localization can be a complex matter.
For many languages, localization is more than just translating an English format
string.
For example, a sentence may change depending on properties of the arguments such
as gender or plurality.
In turn, the rendering of the arguments may be influenced by, for example:
language, sentence context (start, middle, list item, standalone, etc.),
role within the sentence (case: dative, nominative, genitive, etc.),
formatting options, and
user-specific settings, like measurement system.

In other words, the format string is selected based on the arguments and the
arguments may be rendered differently based on the format string, or even the
position within the format string.

A localization framework should provide at least the following features:

1. mark and extract text in code to be translated,
1. injecting translated text received from a translator, and
1. formatting values, such as numbers, currencies, units, names, etc.

Language-specific parsing of values belongs in this list as well,
but we consider it to be out of scope for now.

### Localization in Go
Although we have drawn some ideas for the design from other localization
libraries, the design will inevitably be different in various aspects for Go.

Most frameworks center around the concept of a single user per machine.
This leads to concepts like default locale, per-locale loadable files, etc.
Go applications tend to be multi-user and single static libraries.

Also many frameworks predate CLDR-provided features such as varying values
based on plural and gender.
Retrofitting frameworks to use this data is hard and often results in clunky APIs.
Designing a framework from scratch allows designing with such features in mind.

### Definitions
We call a **message** the abstract notion of some semantic content to be
conveyed to the user.
Each message is identified by a key, which will often be
a fmt- or template-style format string.
A message definition defines concrete format strings for a message
called **variants**.
A single message will have at least one variant per supported language.

A message may take **arguments** to be substituted at given insertion points.
An argument may have 0 or more features.
An argument **feature** is a key-value pair derived from the value of this argument.
Features are used to select the specific variant for a message for a given
language at runtime.
A **feature value** is the value of an argument feature.
The set of possible feature values for an attribute can vary per language.
A **selector** is a user-provided string to select a variant based on a feature
or argument value.

## Proposal
Most messages in Go programs pass through either the fmt or one of the template
packages.
We treat each of these two types of packages separately.

### Package golang.org/x/text/message
Package message has drop-in replacements for most functions in the fmt package.
Replacing one of the print functions in fmt with the equivalent in package
message flags the string for extraction and causes language-specific rendering.

Consider a traditional use of fmt:

```go
fmt.Printf("%s went to %s.", person, city)
```

To localize this message, replace fmt with a message.Printer for a given language:

```go
p := message.NewPrinter(userLang)
p.Printf("%s went to %s.", person, city)
```

To localize all strings in a certain scope, the user could assign such a printer
to `fmt`.

Using the Printf of `message.Printer` has the following consequences:

* it flags the format string for translation,
* the format string is now a key used for looking up translations (the format
  string is still used as a format string in case of a missing translation),
* localizable types, like numbers are rendered corresponding to p's language.

In practice translations will be automatically injected from
a translator-supplied data source.
But let's do this manually for now.
The following adds a localized variant for Dutch:

```go
message.Set(language.Dutch, "%s went to %s.",  "%s is in %s geweest.")
```

Assuming p is configured with `language.Dutch`, the Printf above will now print
the message in Dutch.

In practice, translators do not see the code and may need more context than just
the format string.
The user may add context to the message by simply commenting the Go code:

```go
p.Printf("%s went to %s.", // Describes the location a person visited.
	person,                // The Person going to the location.
 	city,                  // The location visited.
)
```

The message extraction tool can pick up these comments and pass them to the
translator.

The section on Features and the Rationale chapter present more details on package
message.

### Package golang.org/x/text/{template|html/template}
Templates can be localized by using the drop-in replacement packages of equal name.
They add the following functionality:

* mark to-be-localized text in templates,
* substitute variants of localized text based on the language, and
* use the localized versions of the print builtins, if applicable.

The `msg` action marks text in templates for localization analogous to the
namesake construct in Soy.

Consider code using core's text/template:

```go
import "text/template"
import "golang.org/x/text/language"

const letter = `
Dear {{.Name}},
{{if .Attended}}
It was a pleasure to see you at the wedding.{{else}}
It is a shame you couldn't make it to the wedding.{{end}}
Best wishes,
Josie
`
// Prepare some data to insert into the template.
type Recipient struct {
	Name     string
	Attended bool
	Language language.Tag
}
var recipients = []Recipient{
	{"Mildred", true, language.English},
	{"Aurélie", false, language.French},
	{"Rens", false, language.Dutch},
}
func main() {
	// Create a new template and parse the letter into it.
	t := template.Must(template.New("letter").Parse(letter))

	// Execute the template for each recipient.
	for _, r := range recipients {
		if err := t.Execute(os.Stdout, r); err != nil {
			log.Println("executing template:", err)
		}
	}
}
```

To localize this program the user may adopt the program as follows:

```go
import "golang.org/x/text/template"

const letter = `
{{msg "Opening of a letter"}}Dear {{.Name}},{{end}}
{{if .Attended}}
{{msg}}It was a pleasure to see you at the wedding.{{end}}{{else}}
{{msg}}It is a shame you couldn't make it to the wedding.{{end}}{{end}}
{{msg "Closing of a letter, followed by name (f)"}}Best wishes,{{end}}
Josie
`
```

and

```go
func main() {
	// Create a new template and parse the letter into it.
	t := template.Must(template.New("letter").Parse(letter))

	// Execute the template for each recipient.
	for _, r := range recipients {
		if err := t.Language(r.Language).Execute(os.Stdout, r); err != nil {
			log.Println("executing template:", err)
		}
	}
}
```

To make this work, we distinguish between normal and language-specific templates.
A normal template behaves exactly like a template in core, but may be associated
with a set of language-specific templates.

A language-specific template differs from a normal template as follows:
It is associated with exactly one normal template, which we call its base template.

1. A Lookup of an associated template will find the first non-empty result of
   a Lookup on:
	1. the language-specific template itself,
	1. recursively, the result of Lookup on the template for the parent language
	   (as defined by language.Tag.Parent) associated with its base template, or
	1. the base template.
1. Any template obtained from a lookup on a language-specific template will itself
   be a language-specific template for the same language.
   The same lookup algorithm applies for such templates.
1. The builtins print, println, and printf will respectively call the Sprint,
   Sprintln, and Sprintf methods of a message.Printer for the associated language.

A top-level template called `Messages` holds all translations of messages
in language-specific templates. This allows registering of variants using
existing methods defined on templates.

```go
dutch := template.Messages.Language(language.Dutch)
template.Must(dutch.New(`Dear {{.Name}},`).Parse(`Lieve {{.Name}},`))
template.Must(dutch.
	New(`It was a pleasure to see you at the wedding.`).
	Parse(`Het was een genoegen om je op de bruiloft te zien.`))
	    // etc.
```

### Package golang.org/x/text/feature
So far we have addressed cases where messages get translated one-to-one in
different languages.
Translations are often not as simple.
Consider the message `"%[1]s went to %[2]"`, which has the arguments P (a person)
and D (a destination).
This one variant suffices for English.
In French, one needs two:

	gender of P is female: "%[1]s est allée à %[2]s.", and
	gender of P is male:   "%[1]s est allé à %[2]s."

The number of variants needed to properly translate a message can vary
wildly per language.
For example, Arabic has six plural forms.
At worst, the number of variants for a language is equal to the Cartesian product
of all possible values for the argument features for this language.

Package feature defines a mechanism for selecting message variants based on
linguistic features of its arguments.
Both the message and template packages allow selecting variants based on features.
CLDR provides data for plural and gender features.
Likewise-named packages in the text repo provide support for each.

An argument may have multiple features.
For example, a list of persons can have both a count attribute (the number of
people in the list) as well as a gender attribute (the combined gender of the
group of people in the list, the determination of which varies per language).

The feature.Select struct defines a mapping of selectors to variants.
In practice, it is created by a feature-specific, high-level wrapper.
For the above example, such a definition may look like:

```go
message.SetSelect(language.French, "%s went to %s",
	gender.Select(1, // Select on gender of the first argument.
		"female", "%[1]s est allée à %[2]s.",
		"other",  "%[1]s est allé à %[2]s."))
```

The "1" in the Select statement refers to the first argument, which was our person.
The message definition now expects the first argument to support the gender feature.
For example:

```go
type Person struct {
	Name string
	gender.Gender
}
person := Person{ "Joe", gender.Male }
p.Printf("%s went to %s.", person, city)
```

The plural package defines a feature type for plural forms.
An obvious consumer is the numbers package.
But any package that has any kind of amount or cardinality (e.g. lists) can use it.
An example usage:

```go
message.SetSelect(language.English, "There are %d file(s) remaining.",
    plural.Select(1,
		"zero",	 "Done!",
		"one",	 "One file remaining",
		"other", "There are %d files remaining."))
```

This works in English because the CLDR category "zero" and "one" correspond
exclusively to the values 0 and 1.
This is not the case, for example, for Serbian, where "one" is really a category
for a broad range of numbers ending in 1 but not 11.
To deal with such cases, we borrow a notation from ICU to support exact matching:

```go
message.SetSelect(language.English, "There are %d file(s) remaining.",
    plural.Select(1,
		"=0",	 "Done!",
		"=1",	 "One file remaining",
		"other", "There are %d files remaining."))
```

Besides "=", and in addition to ICU, we will also support the "<" and ">" comparators.

The template packages would add a corresponding ParseSelect to add translation variants.

### Value formatting
We now move from localizing messages to localizing values.
This is a non-exhaustive list of value type that support localized rendering:

* numbers
* currencies
* units
* lists
* dates (calendars, formatting with spell-out, intervals)
* time zones
* phone numbers
* postal addresses

Each type maps to a separate package that roughly provides the same types:

* Value: encapsulates a value and implements fmt.Formatter.
For example, currency.Value encapsulates the amount, the currency, and
whether it should be rendered as cash, accounting, etc.
* Formatter: a func of the form func(x interface{}) Value that creates or wraps
a Value to be rendered according to the Formatter's purpose.

Since a Formatter leaves the actual printing to the implementation of
fmt.Formatter, the value is not printed until after it is passed to one of the
print methods.
This allows formatting flags, as well as other context information to influence
the rendering.

The State object passed to Format needs to provide more information than
what is passed by fmt.State, namely:

* a `language.Tag`,
* locale settings that a user may override relative to the user locale setting
  (e.g. preferred time format, measurement system),
* sentence context, such as standalone, start-, mid-, or end-of-sentence, and
* formatting options, possibly defined by the translator.

To accommodate this, we either need to define a text repo-specific State
implementation that Format implementations can type assert to or
define a different Formatter interface.

#### Example: Currencies
We consider this pattern applied to currencies. The Value and Formatter type:

```go
// A Formatter associates formatting information with the given value. x may be a
// Currency, a Value, or a number if the Formatter is associated with a default currency.
type Formatter func(x interface{}) Value

func (f Formatter) NumberFormat(f number.Formatter) Formatter
...

var Default Formatter = Formatter(formISO)
var Symbol Formatter = Formatter(formSymbol)
var SpellOut Formatter = Formatter(formSpellOut)

type Value interface {
	amount interface{}
	currency Currency
	formatter *settings
}

// Format formats v. If State is a format.State, the value is formatted
// according to the given language. If State is not language-specific, it will
// use number plus ISO code for values and the ISO code for Currency.
func (v Value) Format(s fmt.State, verb rune)
func (v Value) Amount() interface{}
func (v Value) Float() (float64, error)
func (v Value) Currency() Currency
...
```

Usage examples:

```go
p := message.NewPrinter(language.AmericanEnglish)
p.Printf("You pay %s.", currency.USD.Value(3))                   // You pay USD 3.
p.Printf("You pay %s.", currency.Symbol(currency.USD.Value(3)))  // You pay $3.
p.Printf("You pay %s.", currency.SpellOut(currency.USD.Value(1)) // You pay 1 US Dollar.
spellout := currency.SpellOut.NumberFormat(number.SpellOut)
p.Printf("You pay %s.", spellout(currency.USD.Value(3)))   // You pay three US Dollars.
```

Formatters have option methods for creating new formatters.
Under the hood all formatter implementations use the same settings type, a
pointer of which is included as a field in Value.
So option methods can access a formatter's settings by formatting a dummy value.

Different types of currency types are available for different localized rounding
and accounting practices.

```go
v := currency.CHF.Value(3.123)
p.Printf("You pay %s.", currency.Cash.Value(v))  // You pay CHF 3.15.

spellCash := currency.SpellOut.Kind(currency.Cash).NumberFormat(number.SpellOut)
p.Printf("You pay %s.", spellCash(v))   // You pay three point fifteen Swiss Francs.
```

The API ensures unused tables are not linked in.
For example, the rather large tables for spelling out numbers and currencies
needed for number.SpellOut and currency.SpellOut are only linked in when
the respective formatters are called.

#### Example: units
Units are like currencies but have the added complexity that the amount and
unit may change per locale.
The Formatter and Value types are analogous to those of Currency.
It defines "constructors" for a selection of unit types.

```go
type Formatter func(x interface{}) Value
var (
	Symbol Formatter = Formatter(formSymbol)
	SpellOut Formatter = Formatter(formSpellOut)
)
// Unit sets the default unit for the formatter. This allows the formatter to
// create values directly from numbers.
func (f Formatter) Unit(u Unit) Formatter

// create formatted values:
func (f Formatter) Value(x interface{}, u Unit) Value
func (f Formatter) Meters(x interface{}) Value
func (f Formatter) KilometersPerHour(x interface{}) Value
…

type Unit int
const SpeedKilometersPerHour Unit = ...

type Kind int
const Speed Kind = ...
```

Usage examples:

```go
p := message.NewPrinter(language.AmericanEnglish)
p.Printf("%d", unit.KilometersPerHour(250))   // 155 mph
```

spelling out the unit names:

```go
p.Print(unit.SpellOut.KilometersPerHour(250)) // 155.343 miles per hour
```

Associating a default unit with a formatter allows it to format numbers directly:

```go
kmh := unit.SpellOut.Unit(unit.SpeedKilometersPerHour)
p.Print(kmh(250)) // 155.343 miles per hour
```

Spell out the number as well:

```go
spellout := unit.SpellOut.NumberFormat(number.SpellOut)
p.Print(spellout.KilometersPerHour(250))
// one hundred fifty-five point three four three miles per hour
```

or perhaps also

```go
p.Print(unit.SpellOut.KilometersPerHour(number.SpellOut(250)))
// one hundred fifty-five point three four three miles per hour
```

Using a formatter, like `number.SpellOut(250)`, just returns a Value wrapped
with the new formatting settings.
The underlying value is retained, allowing its features to select
the proper unit names.

There may be an ambiguity as to which unit to convert to when converting from
US to the metric system.
For example, feet can be converted to meters or centimeters.
Moreover, which one is to prefer may differ per language.
If this is an issue we may consider allowing overriding the default unit to
convert in a message.
For example:

	%[2:unit=km]f

Such a construct would allow translators to annotate the preferred unit override.

## Details and Rationale

### Formatting

The proposed Go API deviates from a common pattern in other localization APIs by
_not_ associating a Formatter with a language.
Passing the language through State has several advantages:

1. the user needs to specify a language for a message only once, which means
	1. less typing,
	1. no possibility of mismatch, and
	1. no need to initialize a formatter for each language (which may mean on
	   every usage),
1. the value is preserved up till selecting the variant, and
1. a string is not rendered until its context is known.

It prevents strings from being rendered prematurely, which, in turn, helps
picking the proper variant and allows translators to pass in options in
formatting strings.
The Formatter construct is a natural way of allowing for this flexibility and
allows for a straightforward and natural API for something that is otherwise
quite complex.

The Value types of the formatting packages conflate data with formatting.
However, formatting types often are strongly correlated to types.
Combining formatting types with values is not unlike associating the time zone
with a Time or rounding information with a number.
Combined with the fact that localized formatting is one of the main purposes
of the text repo, it seems to make sense.

#### Differences from the fmt package
Formatted printing in the message package differs from the equivalent in the
fmt package in various ways:

* An argument may be used solely for its features, or may be unused for
  specific variants.
  It is therefore possible to have a format string that has no
  substitutions even in the presence of arguments.
* Package message dynamically selects a variant based on the
  arguments' features and the configured language.
  The format string passed to a formatted print method is mostly used as a
  reference or key.
* The variant selection mechanism allows for the definition of variables
  (see the section on package feature).
  It seems unnatural to refer to these by position.
  We contemplate the usage of named arguments for such variables: `%[name]s`.
* Rendered text is always natural language and values render accordingly.
  For example, `[]int{1, 2, 3}` will be rendered, in English, as `"1, 2 and 3"`,
  instead of  `"[1 2 3]"`.
* Formatters may use information about sentence context.
  Such meta data must be derived by automated analysis or supplied by a
  translator.

Considering the differences with fmt we expect package message to do its own
parsing.
Different substitution points of the same argument may require a different State
object to be passed.
Using fmt's parser would require rewriting such arguments into different forms
and/or exposing more internals of fmt in the API.
It seems more straightforward for package message to do its own parsing.
Nonetheless, we aim to utilize as much of the fmt package as possible.

#### Currency
Currency is its own package.
In most localization APIs the currency formatter is part of the number formatter.
Currency data is large, though, and putting it in its own package
avoids linking it in unnecessarily.
Separating the currency package also allows greater control over options.
Currencies have specific locale-sensitive rounding and scale settings that
may interact poorly with options provided for a number formatter.

#### Units
We propose to have one large package that includes all unit types.
We could split this package up in,  for example, packages for energy, mass,
length, speed etc.
However, there is a lot of overlap in data (e.g. kilometers and kilometers per hour).
Spreading the tables across packages will make sharing data harder.
Also, not all units belong naturally in a specific package.

To mitigate the impact of including large tables, we can have composable modules
of data from which user can compose smaller formatters
(similar to the display package).

### Features

The proposed mechanism for features takes a somewhat different approach
to OS X and ICU.
It allows mitigating the combinatorial explosion that may occur when combining
features while still being legible.

#### Matching algorithm
The matching algorithm returns the first match on a depth-first search on all cases.
We also allow for variable assignment.
We define the following types (in Go-ey pseudo code):

	Select struct {
		Feature  string  	 // identifier of feature type
		Argument interface{} // Argument reference
		Cases []Case         // The variants.
	}
	Case   struct  { Selector string; Value interface{} }
	Var:    struct { Name string; Value interface{} }
	Value: Select or String
	SelectSequence: [](Select or Var)

To select a variant given a set of arguments:

1. Initialize a map m from argument name to argument value.
1. For each v in s:
	1. If v is of type Var, update m[v.Name] = Eval(v.Value, m)
	1. If v is of type Select, then let v be Eval(v, m).
	1. If v is of type string,  return v.

Eval(v, m): Value

1. If v is a string, return it.
1. Let f be the feature value for feature v.Feature of argument v.Argument.
1. For each case in v.Cases,
	1. return Eval(v) if f.Match(case.Selector, f, v.Argument)
1. Return nil (no match)

Match(s, cat, arg): string x string x interface{} // Implementation for numbers.

1. If s[0] == '=' return int(s[1:]) == arg.
1. If s[0] == '<' return int(s[1:]) < arg.
1. If s[0] == '>' return int(s[1:]) > arg.
1. If  s == cat return true.
1. return s == "other"

A simple data structure encodes the entire Select procedure, which makes it
trivially machine-readable, a condition for including it in a translation pipeline.

#### Full Example

Consider the message `"%[1]s invite %[2] to their party"`, where argument 1 an 2
are lists of respectively hosts and guests, and data:

```go
map[string]interface{}{
	"Hosts": []gender.String{
		gender.Male.String("Andy"),
		gender.Female.String("Sheila"),
	},
	"Guests": []string{ "Andy", "Mary", "Bob", "Linda", "Carl", "Danny" },
}
```

The following variant selector covers various cases for different values of the
arguments.
It limits the number of guests listed to 4.

```go
message.SetSelect(en, "%[1]s invite %[2]s and %[3]d other guests to their party.",
	plural.Select(1, // Hosts
		"=0", `There is no party. Move on!`,
		"=1", plural.Select(2, // Guests
			"=0", `%[1]s does not give a party.`,
			"other", plural.Select(3, // Other guests count
				"=0", gender.Select(1, // Hosts
					"female", "%[1]s invites %[2]s to her party.",
					"other ", "%[1]s invites %[2]s to his party."),
				"=1", gender.Select(1, // Hosts
					"female", "%[1]s invites %#[2]s and one other person to her party.",
					"other ", "%[1]s invites %#[2]s and one other person to his party."),
				"other", gender.Select(1, // Hosts
					"female", "%[1]s invites %#[2]s and %[3]d other people to her party.",
					"other ", "%[1]s invites %#[2]s and %[3]d other people to his party.")),
		"other", plural.Select(2, // Guests,
			"=0 ", "%[1]s do not give a party.",
			"other", plural.Select(3, // Other guests count
				"=0", "%[1]s invite %[2]s to their party.",
				"=1", "%[1]s invite %#[2]s and one other person to their party.",
				"other ", "%[1]s invite %#[2]s and %[3]d other people to their party."))))
```

<!-- ```go
template.Language(language.English).
New("{{.Hosts}} invite {{.Guests}} to their party.").
ParseSelect(plural.Select(".Hosts",
	"=0", `There is no party. Move on!`,
	"=1", plural.Select(".Guests",
		"=0", `{{.Hosts}} does not give a party.`,
		"<5", gender.Select(".Hosts",
			"female", `{{.Hosts}} invites {{.Guests}} to her party.`,
			"other ", `{{.Hosts}} invites {{.Guests}} to his party.`),
		"=5", gender.Select(".Hosts",
			"female", `{{.Hosts}} invites {{first 4 .Guests}} and one other
							person to her party.`,
			"other ", `{{.Hosts}} invites {{first 4 .Guests}} and one other
							person to his party.`),
		"other", gender.Select(".Hosts",
			"female", `{{.Hosts}} invites {{first 4 .Guests}} and {{offset 4 .Guests}}
							other people to her party.`,
			"other ", `{{.Hosts}} invites {{first 4 .Guests}} and {{offset 4 .Guests}}
							other people to his party.`),
				),
		"other", plural.Select(".Guests",
			"=0 ", `{{.Hosts}} do not give a party.`,
			"<5 ", `{{.Hosts}} invite {{.Guests}} to their party.`,
			"=5 ", `{{.Hosts}} invite {{first 4 .Guests}} and one other person
							to their party.`,
			"other ", `{{.Hosts}} invite {{first 4 .Guests}} and
							{{offset 4 .Guests}} other people to their party.`)))
``` -->

For English, we have three variables to deal with:
the plural form of the hosts and guests and the gender of the hosts.
Both guests and hosts are slices.
Slices have a plural feature (its cardinality) and gender (based on CLDR data).
We define the flag `#` as an alternate form for lists to drop the comma.

It should be clear how quickly things can blow up with when dealing with
multiple features.
There are 12 variants.
For other languages this could be quite a bit more.
Using the properties of the matching algorithm one can often mitigate this issue.
With a bit of creativity, we can remove the two cases where `Len(Guests) == 0`
and add another select block at the start of the list:

```go
message.SetSelect(en, "%[1]s invite %[2]s and %[3]d other guests to their party.",
	plural.Select(2, "=0", `There is no party. Move on!`),
	plural.Select(1,
		"=0", `There is no party. Move on!`,
		…
```

<!-- ```go
template.Language(language.English).
	New("{{.Hosts}} invite {{.Guests}} to their party.").
	ParseSelect(
		plural.Select(".Guests", "=0", `There is no party. Move on!`),
		plural.Select(".Hosts",
			"=0", `There is no party. Move on!`,
			…
``` -->

The algorithm will return from the first select when `len(Guests) == 0`,
so this case will not have to be considered later.

Using Var we can do a lot better, though:

```go
message.SetSelect(en, "%[1]s invite %[2]s and %[3]d other guests to their party.",
	feature.Var("noParty", "There is no party. Move on!"),
	plural.Select(1, "=0", "%[noParty]s"),
	plural.Select(2, "=0", "%[noParty]s"),

	feature.Var("their", gender.Select(1, "female", "her", "other ", "his")),
 	// Variables may be overwritten.
	feature.Var("their", plural.Select(1, ">1", "their")),
	feature.Var("invite", plural.Select(1, "=1", "invites", "other ", "invite")),

	feature.Var("guests", plural.Select(3, // other guests
		"=0", "%[2]s",
		"=1", "%#[2]s and one other person",
		"other", "%#[2]s and %[3]d other people"),
	feature.String("%[1]s %[invite]s %[guests]s to %[their]s party."))
```

<!--```go
template.Language(language.English).
    New("{{.Hosts}} invite {{.Guests}} to their party.").
    ParseSelect(
		feature.Var("noParty", "There is no party. Move on!"),
		plural.Select(".Hosts", "=0", `{{$noParty}}`),
		plural.Select(".Guests", "=0", `{{$noParty}}`),

		feature.Var("their", gender.Select(".Hosts",
			"female", "her",
			"other ", "his")),
	 	// Variables may be overwritten.
		feature.Var("their", plural.Select(".Hosts", ">1", "their")),
		feature.Var("invite", plural.Select(".Hosts",
			"=1", "invites",
			"other ", "invite")),

		plural.Select(".Guests",
			"<5", `{{.Hosts}} {{$invite}} {{.Guests}} to {{$their}} party.`,
			"=5", `{{.Hosts}} {{$invite}} {{first 4 .Guests}} and one other person
						to {{$their}} party.`,
			"other", `{{.Hosts}} {{$invite}} {{first 4 .Guests | printf  "%#v"}}
						and {{offset 4 .Guests}} other people to {{$their}} party.`))
```-->

This is essentially the same as the example before, but with the use of
variables to reduce the verbosity.
If one always shows all guests, there would only be one variant for describing
the guests attending a party!

#### Comparison to ICU
ICU has a similar approach to dealing with gender and plurals.
The above example roughly translates to:

```
`{num_hosts, plural,
  =0 {There is no party. Move on!}
  other {
    {gender_of_host, select,
      female {
        {num_guests, plural, offset:1
           =0 {{host} does not give a party.}
           =1 {{host} invites {guest} to her party.}
           =2 {{host} invites {guest} and one other person to her party.}
           other {{host} invites {guest} and # other people to her party.}}}
      male {
         {num_guests, plural, offset:1
            =0 {{host} does not give a party.}
            =1 {{host} invites {guest} to his party.}
            =2 {{host} invites {guest} and one other person to his party.}
            other {{host} invites {guest} and # other people to his party.}}}
      other {
         {num_guests, plural, offset:1
           =0 {{host} do not give a party.}
           =1 {{host} invite {guest} to their party.}
           =2 {{host} invite {guest} and one other person to their party.}
           other {{host} invite {guest} and # other people to their party.}}}}}}`
```

Comparison:

* In Go, features are associated with values, instead of passed separately.
* There is no Var construct in ICU.
* Instead the ICU notation is more flexible and allows for notations like:

	```
	"{1, plural,
		zero {Personne ne se rendit}
		one {{0} est {2, select, female {allée} other {allé}}}
		other {{0} sont {2, select, female {allées} other {allés}}}} à {3}"
	```

* In Go, strings can only be assigned to variables or used in leaf nodes of a
  select. We find this to result in more readable definitions.
* The Go notation is fully expressed in terms of Go structs:
	* There is no separate syntax to learn.
	* Most of the syntax is checked at compile time.
	* It is serializable and machine readable without needing another parser.
* In Go, feature types are fully generic.
* Go has no special syntax for constructs like offset (see the third argument
in ICU's plural select and the "#" for substituting offsets).
We can solve this with pipelines in templates and special interpretation for
flag and verb types for the Format implementation of lists.
* ICU's algorithm seems to prohibit the user of '<' and '>' selectors.

#### Comparison to OS X

OS X recently introduced support for handling plurals and prepared for support
for gender.
The data for selecting variants is stored in the stringsdict file.
This example from the referenced link shows how to vary sentences for
"number of files selected" in English:

```
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>%d files are selected</key>
    <dict>
        <key>NSStringLocalizedFormatKey</key>
        <string>%#@num_files_are@ selected</string>
        <key>num_files_are</key>
        <dict>
            <key>NSStringFormatSpecTypeKey</key>
            <string>NSStringPluralRuleType</string>
            <key>NSStringFormatValueTypeKey</key>
            <string>d</string>
            <key>zero</key>
            <string>No file is</string>
            <key>one</key>
            <string>A file is</string>
            <key>other</key>
            <string>%d files are</string>
        </dict>
    </dict>
</dict>
</plist>
```

The equivalent in the proposed Go format:

```go
message.SetSelect(language.English, "%d files are selected",
	feature.Var("numFilesAre", plural.Select(1,
		"zero",  "No file is",
		"one",   "A file is",
		"other", "%d files are")),
	feature.String("%[numFilesAre]s selected"))
```

A comparison between OS X and the proposed design:

* In both cases, the selection of variants can be represented in a data structure.
* OS X does not have a specific API for defining the variant selection in code.
* Both approaches allow for arbitrary feature implementations.
* OS X allows for a similar construct to Var to allow substitution of substrings.
* OS X has extended its printf-style format specifier to allow for named substitutions.
  The substitution string `"%#@foo@"` will substitute the variable foo.
  The equivalent in Go is the less offensive `"%[foo]v"`.

### Code organization
The typical Go deployment is that of a single statically linked binary.
Traditionally, though, most localization frameworks have grouped data in
per-language dynamically-loaded files.
We suggested some code organization methods for both use cases.

#### Example: statically linked package

In the following code, a single file called messages.go contains all collected
translations:

```go
import "golang.org/x/text/message"
func init() {
	for _, e := range entries{
		for _, t := range e {
			message.SetSelect(e.lang, t.key, t.value)
		}
	}
}
type entry struct {
	key   string
	value feature.Value
}
var entries = []struct{
	lang  language.Tag
	entry []entry
}{
	{ language.French, []entry{
		{ "Hello", feature.String("Bonjour") },
		{ "%s went to %s", feature.Select{ … } },
		…
	},
}

```

#### Example: dynamically loaded files

We suggest storing per-language data files in a messages subdirectory:

```go
func NewPrinter(t language.Tag) *message.Printer {
	r, err := os.Open(filepath.Join("messages", t.String() + ".json"))
	// handle error
	cat := message.NewCatalog()
	d := json.NewDecoder(r)
	for {
		var msg struct{ Key string; Value []feature.Value }
		if err := d.Decode(&msg); err == io.EOF {
			break
		} else if err != nil {
			// handle error
		}
		cat.SetSelect(t, msg.Key, msg.Value...)
	}
	return cat.NewPrinter(t)
}
```

## Compatibility

The implementation of the `msg` action will require some modification to core's
template/parse package.
Such a change would be backward compatible.

## Implementation Plan

Implementation would start with some of the rudimentary package in the text
repo, most notably format.
Subsequently, this allows the implementation of the formatting of some specific
types, like currencies.
The messages package will be implemented first.
The template package is more invasive and will be implemented at a later stage.
Work on infrastructure for extraction messages from templates and print
statements will allow integrating the tools with translation pipelines.


text:
<?php
// Copyright 2017 DAIMTO ([Linda Lawton](https://twitter.com/LindaLawtonDK)) :  [www.daimto.com](http://www.daimto.com/)
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by DAIMTO-Google-apis-Sample-generator 1.0.0
//     Template File Name:  methodTemplate.tt
//     Build date: 2017-10-08
//     PHP generator version: 1.0.0
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
// About
//
// Unofficial sample for the genomics v1alpha2 API for PHP.
// This sample is designed to be used with the Google PHP client library. (https://github.com/google/google-api-php-client)
//
// API Description: Upload, process, query, and search Genomics data in the cloud.
// API Documentation Link https://cloud.google.com/genomics
//
// Discovery Doc  https://www.googleapis.com/discovery/v1/apis/genomics/v1alpha2/rest
//
//------------------------------------------------------------------------------
// Installation
//
// The preferred method is via https://getcomposer.org. Follow the installation instructions https://getcomposer.org/doc/00-intro.md
// if you do not already have composer installed.
//
// Once composer is installed, execute the following command in your project root to install this library:
//
// composer require google/apiclient:^2.0
//
//------------------------------------------------------------------------------
// Load the Google API PHP Client Library.
require_once __DIR__ . '/vendor/autoload.php';
session_start();

/***************************************************
* Include this line for service account authencation.  Note: Not all APIs support service accounts.
//require_once __DIR__ . '/ServiceAccount.php';
* Include the following four lines Oauth2 authencation.
* require_once __DIR__ . '/Oauth2Authentication.php';
* $_SESSION['mainScript'] = basename($_SERVER['PHP_SELF']);   // Oauth2callback.php will return here.
* $client = getGoogleClient();
* $service = new Google_Service_Genomics($client);
****************************************************/

// Option paramaters can be set as needed.
 $optParams = array(

  //'filter' => '[YourValue]',  // A string for filtering Operations.The following filter fields are supported:* projectId: Required. Corresponds to  OperationMetadata.projectId.* createTime: The time this job was created, in seconds from the  [epoch](http://en.wikipedia.org/wiki/Unix_time). Can use `>=` and/or `<=`  operators.* status: Can be `RUNNING`, `SUCCESS`, `FAILURE`, or `CANCELED`. Only  one status may be specified.* labels.key where key is a label key.Examples:* `projectId = my-project AND createTime >= 1432140000`* `projectId = my-project AND createTime >= 1432140000 AND createTime <= 1432150000 AND status = RUNNING`* `projectId = my-project AND labels.color = *`* `projectId = my-project AND labels.color = red`

  //'pageToken' => '[YourValue]',  // The standard list page token.

  //'pageSize' => '[YourValue]',  // The maximum number of results to return. If unspecified, defaults to256. The maximum value is 2048.
  'fields' => '*'
);
// Single Request.
$results = operationsListExample($service, $name, $optParams);

// Paginiation Example
do {
    if (!$results->getNextPageToken())
		break;

	$optParams['pageToken'] = $results->getNextPageToken();
	$results = filesListExample($service, $name, $optParams);
} while($results->getNextPageToken());

/**
* Lists operations that match the specified filter in the request.
* @service Authenticated Genomics service.
* @optParams Optional paramaters are not required by a request.
* @name The name of the operation's parent resource.
* @return ListOperationsResponse
*/
function operationsListExample($service, $name, $optParams)
{
	try
	{
		// Parameter validation.
		if ($service == null)
			throw new Exception("service is required.");
		if ($optParams == null)
			throw new Exception("optParams is required.");
		if (name == null)
			throw new Exception("name is required.");
		// Make the request and return the results.
		return $service->operations->ListOperations($name, $optParams);
	}
	catch (Exception $e)
	{
		print "An error occurred: " . $e->getMessage();
	}
}
?>


text:
package com.github.horrorho.liquiddonkey.crypto;

import net.jcip.annotations.NotThreadSafe;
import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
import org.bouncycastle.crypto.params.KeyParameter;

/**
 * PBKDF2 generator.
 *
 * @author ahseya
 */
@NotThreadSafe
public final class PBKDF2 {

    private final PKCS5S2ParametersGenerator generator;

    public static PBKDF2 create() {
        return new PBKDF2();
    }

    PBKDF2() {
        this.generator = new PKCS5S2ParametersGenerator();
    }

    public byte[] generate(byte[] password, byte[] salt, int iterations, int keyLengthBytes) {
        generator.init(password, salt, iterations);
        return ((KeyParameter) generator.generateDerivedParameters(keyLengthBytes * 8)).getKey();
    }
}


text:
	<title>Linda Bellos's panel show appearances</title>

	<link rel="stylesheet" media="all" href="../style.css" type="text/css"/>

Linda Bellos's panel show appearances

Linda Bellos (born 1950-12-13[ref]) has appeared in 1 episodes between 1987-1987.  Linda Bellos on Wikipedia.

1987

1987-09-24 / Question Time


text:
<?php
class myAppendIterator extends AppendIterator {}
try {
	$it = new myAppendIterator();
	echo "no exception";
} catch (InvalidArgumentException $e) {
	echo 'InvalidArgumentException thrown';
}
?>


text:
/**
 */
package org.tud.inf.st.mbt.scenario.provider;

import java.util.Collection;
import java.util.List;

import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;

import org.eclipse.emf.common.util.ResourceLocator;

import org.eclipse.emf.ecore.EStructuralFeature;

import org.eclipse.emf.edit.provider.ComposeableAdapterFactory;
import org.eclipse.emf.edit.provider.IEditingDomainItemProvider;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.IItemPropertySource;
import org.eclipse.emf.edit.provider.IStructuredItemContentProvider;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.provider.ItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.ViewerNotification;

import org.tud.inf.st.mbt.actions.provider.AllEditPlugin;

import org.tud.inf.st.mbt.core.provider.AbstractModelElementItemProvider;

import org.tud.inf.st.mbt.scenario.ScenarioFactory;
import org.tud.inf.st.mbt.scenario.ScenarioPackage;
import org.tud.inf.st.mbt.scenario.SpatialBase;

/**
 * This is the item provider adapter for a {@link org.tud.inf.st.mbt.scenario.SpatialBase} object.
 * <!-- begin-user-doc -->
 * <!-- end-user-doc -->
 * @generated
 */
public class SpatialBaseItemProvider
	extends AbstractModelElementItemProvider
	implements
		IEditingDomainItemProvider,
		IStructuredItemContentProvider,
		ITreeItemContentProvider,
		IItemLabelProvider,
		IItemPropertySource {
	/**
	 * This constructs an instance from a factory and a notifier.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public SpatialBaseItemProvider(AdapterFactory adapterFactory) {
		super(adapterFactory);
	}

	/**
	 * This returns the property descriptors for the adapted class.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public List<IItemPropertyDescriptor> getPropertyDescriptors(Object object) {
		if (itemPropertyDescriptors == null) {
			super.getPropertyDescriptors(object);

			addXPropertyDescriptor(object);
			addYPropertyDescriptor(object);
			addWidthPropertyDescriptor(object);
			addHeightPropertyDescriptor(object);
		}
		return itemPropertyDescriptors;
	}

	/**
	 * This adds a property descriptor for the X feature.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected void addXPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_SpatialBase_x_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_SpatialBase_x_feature", "_UI_SpatialBase_type"),
				 ScenarioPackage.Literals.SPATIAL_BASE__X,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.INTEGRAL_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Y feature.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected void addYPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_SpatialBase_y_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_SpatialBase_y_feature", "_UI_SpatialBase_type"),
				 ScenarioPackage.Literals.SPATIAL_BASE__Y,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.INTEGRAL_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Width feature.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected void addWidthPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_SpatialBase_width_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_SpatialBase_width_feature", "_UI_SpatialBase_type"),
				 ScenarioPackage.Literals.SPATIAL_BASE__WIDTH,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.INTEGRAL_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Height feature.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected void addHeightPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_SpatialBase_height_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_SpatialBase_height_feature", "_UI_SpatialBase_type"),
				 ScenarioPackage.Literals.SPATIAL_BASE__HEIGHT,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.INTEGRAL_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This specifies how to implement {@link #getChildren} and is used to deduce an appropriate feature for an
	 * {@link org.eclipse.emf.edit.command.AddCommand}, {@link org.eclipse.emf.edit.command.RemoveCommand} or
	 * {@link org.eclipse.emf.edit.command.MoveCommand} in {@link #createCommand}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Collection<? extends EStructuralFeature> getChildrenFeatures(Object object) {
		if (childrenFeatures == null) {
			super.getChildrenFeatures(object);
			childrenFeatures.add(ScenarioPackage.Literals.SPATIAL_BASE__SCENARIOS);
		}
		return childrenFeatures;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EStructuralFeature getChildFeature(Object object, Object child) {
		// Check the type of the specified child object and return the proper feature to use for
		// adding (see {@link AddCommand}) it as a child.

		return super.getChildFeature(object, child);
	}

	/**
	 * This returns SpatialBase.gif.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object getImage(Object object) {
		return overlayImage(object, getResourceLocator().getImage("full/obj16/SpatialBase"));
	}

	/**
	 * This returns the label text for the adapted class.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getText(Object object) {
		String label = ((SpatialBase)object).getName();
		return label == null || label.length() == 0 ?
			getString("_UI_SpatialBase_type") :
			getString("_UI_SpatialBase_type") + " " + label;
	}

	/**
	 * This handles model notifications by calling {@link #updateChildren} to update any cached
	 * children and by creating a viewer notification, which it passes to {@link #fireNotifyChanged}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void notifyChanged(Notification notification) {
		updateChildren(notification);

		switch (notification.getFeatureID(SpatialBase.class)) {
			case ScenarioPackage.SPATIAL_BASE__X:
			case ScenarioPackage.SPATIAL_BASE__Y:
			case ScenarioPackage.SPATIAL_BASE__WIDTH:
			case ScenarioPackage.SPATIAL_BASE__HEIGHT:
				fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), false, true));
				return;
			case ScenarioPackage.SPATIAL_BASE__SCENARIOS:
				fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), true, false));
				return;
		}
		super.notifyChanged(notification);
	}

	/**
	 * This adds {@link org.eclipse.emf.edit.command.CommandParameter}s describing the children
	 * that can be created under this object.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected void collectNewChildDescriptors(Collection<Object> newChildDescriptors, Object object) {
		super.collectNewChildDescriptors(newChildDescriptors, object);

		newChildDescriptors.add
			(createChildParameter
				(ScenarioPackage.Literals.SPATIAL_BASE__SCENARIOS,
				 ScenarioFactory.eINSTANCE.createScenario()));
	}

	/**
	 * Return the resource locator for this item provider's resources.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public ResourceLocator getResourceLocator() {
		return AllEditPlugin.INSTANCE;
	}

}


text:
#import "TiProxy.h"
#import "TiPoint.h"
#import "TiColor.h"
#import "ListenerEntry.h"
#import "LayoutConstraint.h"
#import <QuartzCore/QuartzCore.h>

@class TiViewProxy;
@class TiAnimation;

/**
 Protocol for animation delegate.
 */
@protocol TiAnimationDelegate

@optional

/**
 Whether or not the animation should transition.

 The method is only called if the animation is a transition animation type.
 @param animation The animation this delegate is assigned to.
 @return _YES_ if the animation should transition, _NO_ otherwise.
 */
-(BOOL)animationShouldTransition:(TiAnimation *)animation;

/**
 Tells the delegate that the animation will start.
 @param animation The animation this delegate is assigned to.
 */
-(void)animationWillStart:(TiAnimation *)animation;

/**
 Tells the delegate that the animation did start.
 @param animation The animation this delegate is assigned to.
 */
-(void)animationDidStart:(TiAnimation *)animation;

/**
 Tells the delegate that the animation will complete.
 @param animation The animation this delegate is assigned to.
 */
-(void)animationWillComplete:(TiAnimation *)animation;

/**
 Tells the delegate that the animation did complete.
 @param animation The animation this delegate is assigned to.
 */
-(void)animationDidComplete:(TiAnimation *)animation;

@end

/**
 A type of proxy representing an animation to apply to a view.
 */
@interface TiAnimation : TiProxy {
@private
	NSNumber	*zIndex;
	NSNumber	*left;
	NSNumber	*right;
	NSNumber	*top;
	NSNumber	*bottom;
	NSNumber	*width;
	NSNumber	*height;
	NSNumber	*duration;
	TiPoint		*center;
	TiColor		*backgroundColor;
	TiColor		*color;
	NSNumber	*opacity;
	NSNumber	*opaque;
	NSNumber	*visible;
	NSNumber	*curve;
	NSNumber	*repeat;
	NSNumber	*autoreverse;
	NSNumber	*delay;
	TiProxy		*transform;
	NSNumber	*transition;
	TiViewProxy	*view;
    TiViewProxy *animatedViewProxy;

	// this is a temporary function passed in
	ListenerEntry *callback;

	NSObject<TiAnimationDelegate> *delegate;

	// for animation delegate
	UIView* animatedView;

	// for autoreverse
	LayoutConstraint autoreverseLayout;
	UIView *autoreverseView;
	id transformMatrix;
}

/**
 Provides access to animation delegate object.
 */
@property(nonatomic,assign,readwrite) NSObject<TiAnimationDelegate> *delegate;

@property(nonatomic,readwrite,assign) UIView* animatedView;
@property(nonatomic,readwrite,assign) UIView* autoreverseView;
@property(nonatomic,readwrite,assign) id transformMatrix;
@property(nonatomic,readonly) LayoutConstraint autoreverseLayout;
@property(nonatomic,readonly) ListenerEntry* callback;

// animatable properties against what is being animated
@property(nonatomic,retain,readwrite) NSNumber	*zIndex;
@property(nonatomic,retain,readwrite) NSNumber	*left;
@property(nonatomic,retain,readwrite) NSNumber	*right;
@property(nonatomic,retain,readwrite) NSNumber	*top;
@property(nonatomic,retain,readwrite) NSNumber	*bottom;
@property(nonatomic,retain,readwrite) NSNumber	*width;
@property(nonatomic,retain,readwrite) NSNumber	*height;
@property(nonatomic,retain,readwrite) NSNumber	*duration;
@property(nonatomic,retain,readwrite) TiPoint	*center;
@property(nonatomic,retain,readwrite) TiColor	*color;
@property(nonatomic,retain,readwrite) TiColor	*backgroundColor;
@property(nonatomic,retain,readwrite) NSNumber	*opacity;
@property(nonatomic,retain,readwrite) NSNumber	*opaque;
@property(nonatomic,retain,readwrite) NSNumber	*visible;

// properties that control the animation
@property(nonatomic,retain,readwrite) NSNumber	*curve;
@property(nonatomic,retain,readwrite) NSNumber	*repeat;
@property(nonatomic,retain,readwrite) NSNumber	*autoreverse;
@property(nonatomic,retain,readwrite) NSNumber	*delay;
@property(nonatomic,retain,readwrite) TiProxy	*transform;
@property(nonatomic,retain,readwrite) NSNumber	*transition;
@property(nonatomic,retain,readwrite) TiProxy	*view;

+(TiAnimation*)animationFromArg:(id)args context:(id<TiEvaluator>)context create:(BOOL)yn;

-(id)initWithDictionary:(NSDictionary*)properties context:(id<TiEvaluator>)context;

-(id)initWithDictionary:(NSDictionary*)properties context:(id<TiEvaluator>)context callback:(KrollCallback*)callback;

-(void)animate:(id)args;

/**
 Whether or not the animation is a transition animation type.
 @return _YES_ if the animation is a transition animation type, _NO_ otherwise.
 */
-(BOOL)isTransitionAnimation;

-(NSTimeInterval)animationDuration;
-(void)animationCompleted:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context;

@end


text:
"""Common functions."""

import sys

def log(msg, *args):
  if args:
    msg = msg % args
  print >>sys.stderr, msg


text:
1.  Install Docker.
2.  Set up an environment variable `LAB_MONOLITH_DB_HOST` and assign the docker host's IP,
    set `LAB_MONOLITH_DB_PORT` to some free port, e.g. 5432.

    For docker machine type `docker-machine env` and the value of `$DOCKER_HOST`,
    otherwise `localhost` is probably correct.

3.  Set up an environment variable `LAB_MONOLITH_DB_PASSWORD` and assign any password.

4.  `./start-db.sh`

    Starts a PostgreSQL database using the password from `LAB_MONOLITH_DB_PASSWORD`.

5.  `gradle bootRun`
6.  Open http://localhost:8080


text:
import { Component } from '@angular/core';
import { OnInit } from '@angular/core';
import { ProcessesService } from '../../../../Processes.service';
import './importModelFormBuilder.loader.ts';

@Component({
  selector: 'import',
  styles: [require('./importProcessModel.scss')],
  template: require('./importProcessModel.html')
})
export class ImportProcessModel implements OnInit {
   processModel;
   rules;
   error = undefined;
   formBuilder;
   buildedBusinessObjects = {};
   currentSelectedBusinessObject;
   currentSelectedFieldId;
   currentBofms;
   buildedBofps = {};
   success;
   owlFile;
   version = 5;

  constructor(protected service:ProcessesService) {}

  ngOnInit(): void {
  }

  onFileChange(event) {
    var that = this;
    this.owlFile = event.srcElement.files[0];
    var split = this.owlFile.name.split(".");
    if(split[split.length-1] !== "owl") {
      this.owlFile = undefined;
      event.target.value = "";
    }
  }

  uploadOWLModel(form):void {
    var that = this;
    var reader = new FileReader();
    if(this.owlFile) {
      reader.onload = function(e) {
        var body = {owlContent: reader.result, version: "0.7."+that.version}
        that.service.uploadOWLModel(body)
        .subscribe(
            data => {
               that.processModel = JSON.parse(data['_body']);
               that.processModel.boms.forEach(businessObject => {
                 that.buildedBusinessObjects[businessObject.id] = {};
               });
               that.initRules();
            },
            err => that.error = "Die OWL Datei konnte nicht richtig interpretiert werden!",
            () => {
            }
          );
      }
      reader.readAsText(this.owlFile);
    }
  }

  initRules():void{
    var that = this;
    this.service.getRules()
       .subscribe(
          data => {
             console.log(data);
             that.rules = JSON.parse(data['_body']);
             that.currentSelectedBusinessObject = that.processModel.boms[0];
             that.initFormBuilder(that.currentSelectedBusinessObject);
          },
          err => that.error = err,
          () => console.log('Request Complete')
        );
  }

  uploadProcessModel(form):void {
    var that = this;
    var processModelResult;
    this.getFormData(this.currentSelectedBusinessObject);
    processModelResult = this.processModel;
    processModelResult.bofms = this.getBofms();
    processModelResult.bofps = [];
    Object.keys(this.buildedBofps).forEach(a => processModelResult.bofps = processModelResult.bofps.concat((<any>Object).values(this.buildedBofps[a])));
    this.service.importProcessModel(processModelResult)
       .subscribe(
          data => {
             if(JSON.parse(data['_body']) === true){
               that.processModel = undefined;
               that.rules= undefined;
               that.error = undefined;
               that.formBuilder= undefined;
               that.buildedBusinessObjects = {};
               that.currentSelectedBusinessObject= undefined;
               that.currentSelectedFieldId= undefined;
               that.currentBofms= undefined;
               that.buildedBofps = {};
               that.success = "Das Prozessmodell wurde erfolgreich importiert!";
             } else {
               that.error = "Das Prozessmodell konnte nicht importiert werden!";
               window.scrollTo(0, 0);
             }
          },
          err => that.error = "Das Prozessmodell konnte nicht importiert werden!",
          () => console.log('Request Complete')
        );
  }

  getBofms(){
    var result = [];
    if(this.currentSelectedBusinessObject){
      for(var bom in this.buildedBusinessObjects) {
        if(Object.keys(this.buildedBusinessObjects[bom]).length > 0) {
          var values = JSON.parse(this.buildedBusinessObjects[bom]);
          values.forEach(value => {
            if(value.type !== "paragraph"){
              var type;
              switch (value.type) {
                case "text":
                  type = "STRING";
                  break;
                case "number":
                  type = "NUMBER";
                  break;
                case "date":
                  type = "DATE";
                  break;
                case "checkbox":
                  type = "CHECKBOX";
                  break;
                default:
                  type = "STRING";
                  break;
              }
              result.push({
                name: value.label,
                type: type,
                bomId: bom,
                id: value.name
              })
            }
          });
        }
      }
    }
    return result;
  }

  initFormBuilder(businessObject): void {
    var that = this;
    var options = {
      dataType: 'json', // default: 'xml',
      disableFields: ['autocomplete', 'button', 'checkbox-group', 'file', 'header', 'hidden', 'paragraph', 'select', 'textarea'],
      showActionButtons: false
    };
    this.formBuilder = jQuery(".formBuilder").formBuilder(options).data('formBuilder');

    /*//Timeout, otherwise the formData will still be the old value
    document.addEventListener("fieldAdded", function(e){
      setTimeout(function(){
        that.getFormData(that.currentSelectedBusinessObject, true);
      }, 250);
    });
    document.addEventListener("fieldRemoved", function(e){
      setTimeout(function(){
        that.getFormData(that.currentSelectedBusinessObject, true);
      }, 250);
    });*/
  }

  getFormData(businessObject, internal?:boolean): void {
    var that = this;
    if(this.currentSelectedBusinessObject !== businessObject){
      this.buildedBusinessObjects[this.currentSelectedBusinessObject.id] = this.formBuilder.formData;
      var formData = this.buildedBusinessObjects[businessObject.id];
      formData = jQuery.isEmptyObject(formData) ? undefined : formData === "[]" ? undefined : formData;
      if(formData !== undefined && !internal){
        //This is a necessary thing, otherwise setData will not work correctly
        this.formBuilder.actions.addField(
        	{
        		"type": "paragraph",
        		"subtype": "p",
        		"label": "Paragraph",
        		"className": "paragraph"
        	}
        );
        this.formBuilder.actions.setData(formData);
      } else {
        this.formBuilder.actions.clearFields();
      }
    } else {
      this.buildedBusinessObjects[businessObject.id] = this.formBuilder.formData;
    }
    this.currentSelectedBusinessObject = businessObject;
    this.currentBofms = this.getBofms().filter(b => b.bomId === this.currentSelectedBusinessObject.id);
    //Add new fields
    var allBofms = this.getBofms();
    allBofms.forEach(field => {
      var boms = that.processModel.boms.filter(bom => bom.id === field.bomId);
      if(!that.buildedBofps[field.id]) {
        that.buildedBofps[field.id] = {};
        boms.forEach(bom => {
          bom.stateIds.forEach(stateId => {
            that.buildedBofps[field.id][stateId] = {
              read: true,
              write: true,
              mandatory: false,
              stateId: stateId,
              bofmId: field.id
            }
          })
        })
      }
    });

    //remove deleted fields
    Object.keys(this.buildedBofps).forEach(fieldId => {
      if(allBofms.filter(b => b.id === fieldId).length < 1) {
          delete this.buildedBofps[fieldId];
      }
    });
  }

  getStateName(stateId): string {
    return this.processModel.states.filter(s => s.id === stateId)[0].name;
  }

  getSubjectModelName(stateId): string {
    var subjectModelId = this.processModel.states.filter(s => s.id === stateId)[0].subjectModelId;
    return this.processModel.subjectModels.filter(sm => sm.id === subjectModelId)[0].name;
  }
}


text:
package com.jivesoftware.authHelper.utils;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.NTCredentials;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthPolicy;
import org.apache.commons.httpclient.auth.AuthScope;

import java.net.Inet4Address;
import java.util.ArrayList;
import java.util.logging.Logger;

import static com.jivesoftware.authHelper.consts.AuthConsts.*;

/**
 * Created with IntelliJ IDEA.
 * User: dovamir
 * Date: 4/29/14
 * Time: 7:21 PM
 * To change this template use File | Settings | File Templates.
 */
public class CredentialsUtils {
    private static Logger logger = Logger.getLogger(CredentialsUtils.class.getName());
    private static boolean registeredNTLM;
    private static boolean registeredCLAIMS;
    private static boolean registeredKERBEROS;

    /*
    handle basic authentication with the provided creds
     */
    public static void setBasicAuthCredentials(HttpClient httpClient,
                                               UsernamePasswordCredentials credentials) {
        httpClient.getState().setCredentials(
                new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), credentials);

    }

    /*
    handle NTLMv1 and\or NTLMv2 authentication with the provided creds
    see http://www.websense.com/support/article/kbarticle/How-do-I-Check-NTLM-Version-for-XID-Compatibility
    for NTLM docs
    */
    public static void setNTLMCredentials(HttpClient httpClient, UsernamePasswordCredentials credentials,
                                          String domain) {
        initNTLMv2();

        String localHostName;
        try {
            localHostName = Inet4Address.getLocalHost().getHostName();
        } catch (Exception e) {
            localHostName = "";
        }

        AuthScope authscope = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT);
        httpClient.getState().setCredentials(
                authscope,
                new NTCredentials(
                        credentials.getUserName(),
                        credentials.getPassword(),
                        localHostName, domain));
    }

    /*
    handle KERBEROS authentication with provided creds
    */
    public static void setKerberosCredentials(HttpClient httpClient,
                                              UsernamePasswordCredentials credentials, String domain, String kdc) {
        try {
            //set the login scheme
            initKERBEROS(httpClient);

            System.setProperty(REALM, domain.toUpperCase());
            kdc = (kdc == null || kdc.isEmpty()) ? domain.toUpperCase() : kdc;
            System.setProperty(KDC, kdc);
        } catch (Exception e) {
            String message = "error  in initKERBEROSIfNeeded";
            logger.log(java.util.logging.Level.SEVERE, message, e);
        }
        try {
            logger.fine("attempting to create KERBEROS using apache http client3");
            ArrayList schemes = new ArrayList();
            schemes.add(NEGOTIATE);
            schemes.add(AuthPolicy.BASIC); //to support basic auth proxy on the way
            httpClient.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, schemes);
            AuthScope authscope = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, null);

            httpClient.getState().setCredentials(
                    authscope,
                    credentials);
        } catch (Exception e) {
            String message = "Can not create And Authenticate setKERBEROSCredentials";
            logger.log(java.util.logging.Level.SEVERE, message, e);

        }

    }

    /*
    make requests go through proxy with or without basic auth creds
     */
    public static void setProxyHost(HttpClient httpClient, UsernamePasswordCredentials proxyCredentials,
                                    String proxyHost, int proxyPort) {

        if (proxyHost != null && !proxyHost.isEmpty()) {
            httpClient.getHostConfiguration().setProxy(proxyHost, proxyPort);
            if (proxyCredentials != null) {
                HttpState state = new HttpState();
                state.setProxyCredentials(new AuthScope(proxyHost, proxyPort), proxyCredentials);
                httpClient.setState(state);
            }
        }
    }

    ///////private methods

    private static void initNTLMv2() {
        if (!registeredNTLM) {
            try {
                logger.info(" adding NTLMv2 based   authentication schema for HttpClient");
                AuthPolicy.registerAuthScheme(AuthPolicy.NTLM,
                        com.jivesoftware.authHelper.customescheme.ntlm2.CustomNTLM2Scheme.class);
                registeredNTLM = true;
            } catch (Throwable e) {
                logger.log(java.util.logging.Level.SEVERE,
                        "Could not add NTLM based on JCIFS authentication schema for HttpClient.", e);

            }
        }
    }

    private static void initKERBEROS(HttpClient httpClient) {
        if (!registeredKERBEROS) {
            try {
                logger.info("Globally adding KERBEROS ");
                System.setProperty(USE_SUBJECT_CREDS, "false");

                AuthPolicy.registerAuthScheme(NEGOTIATE,
                        com.jivesoftware.authHelper.customescheme.negotiate.CustomNegotiateScheme.class);
                registeredKERBEROS = true;
            } catch (Throwable e) {
                logger.log(java.util.logging.Level.SEVERE, "Could not add KERBEROS  for HttpClient.", e);
            }

        }
    }

}