text:
package io.imoji.sdk.objects;

import android.net.Uri;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Pair;

import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * An Imoji is a reference to a sticker within the ImojiSDK.
 */
public class Imoji implements Parcelable {

    public enum LicenseStyle {
        NonCommercial(1),
        CommercialPrint(2);

        private final int value;

        LicenseStyle(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }
    }

    public static class Metadata implements Parcelable {
        @Nullable
        private final Integer width;

        @Nullable
        private final Integer height;

        @Nullable
        private final Integer fileSize;

        @NonNull
        private final Uri uri;

        public Metadata(@NonNull Uri uri,
                        @Nullable Integer width,
                        @Nullable Integer height,
                        @Nullable Integer fileSize) {
            this.uri = uri;
            this.width = width;
            this.height = height;
            this.fileSize = fileSize;
        }

        @Nullable
        public Integer getWidth() {
            return width;
        }

        @Nullable
        public Integer getHeight() {
            return height;
        }

        @Nullable
        public Integer getFileSize() {
            return fileSize;
        }

        @NonNull
        public Uri getUri() {
            return uri;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Metadata metadata = (Metadata) o;

            return uri.equals(metadata.uri);

        }

        @Override
        public int hashCode() {
            return uri.hashCode();
        }

        /**
         * Parcelable Overrides
         */
        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(width != null ? width : 0);
            dest.writeInt(height != null ? height : 0);
            dest.writeInt(fileSize != null ? fileSize : 0);
            dest.writeString(this.uri.toString());
        }

        public static final Parcelable.Creator<Metadata> CREATOR
                = new Parcelable.Creator<Metadata>() {
            public Metadata createFromParcel(Parcel in) {
                return new Metadata(in);
            }

            public Metadata[] newArray(int size) {
                return new Metadata[size];
            }
        };

        private Metadata(Parcel in) {
            int val = in.readInt();
            this.width = val != 0 ? val : null;
            val = in.readInt();
            this.height = val != 0 ? val : null;
            val = in.readInt();
            this.fileSize = val != 0 ? val : null;
            this.uri = Uri.parse(in.readString());
        }
    }

    /**
     * A unique identifier for the imoji.
     */
    @NonNull
    private final String identifier;

    /**
     * One or more tags.
     */
    @NonNull
    private final List<String> tags;

    /**
     * A map of all the URL's of the Imoji images with RenderingOptions as the key.
     */
    @NonNull
    private final Map<RenderingOptions, Metadata> metadataMap;

    /**
     * The license style for the category attribution object.
     */
    @NonNull
    private final LicenseStyle licenseStyle;

    /**
     * Whether or not the Imoji has support for animation or not.
     */
    public boolean supportsAnimation() {
        return false;
    }

    /**
     * @return A unique identifier for the Imoji Sticker
     */
    @NonNull
    public String getIdentifier() {
        return identifier;
    }

    /**
     * @return One or more tags for the Imoji sticker
     */
    @NonNull
    public List<String> getTags() {
        return tags;
    }

    /**
     * @return The license style for the category attribution object.
     */
    @NonNull
    public LicenseStyle getLicenseStyle() {
        return licenseStyle;
    }

    /**
     * Gets a download Uri for an Imoji given the requested rendering options
     *
     * @param renderingOptions The Rendering options to use
     * @return A Uri for the Imoji with the supplied RenderingOptions
     */
    @Nullable
    public Uri urlForRenderingOption(RenderingOptions renderingOptions) {
        Metadata metadata = metadataMap.get(renderingOptions);
        return metadata != null ? metadata.uri : null;
    }

    /**
     * Gets the image dimensions for the Imoji and supplied RenderingOptions
     *
     * @param renderingOptions The Rendering options to use
     * @return The image dimensions if any for the Imoji and rendering options
     */
    @Nullable
    public Pair<Integer, Integer> imageDimensionsForRenderingOptions(RenderingOptions renderingOptions) {
        Metadata metadata = metadataMap.get(renderingOptions);

        return metadata != null && metadata.height != null && metadata.width != null ?
                new Pair<>(metadata.width, metadata.height) : null;
    }

    /**
     * Gets the download size for the Imoji and supplied RenderingOptions
     *
     * @param renderingOptions The Rendering options to use
     * @return The download size if any for the Imoji and rendering options. Returns 0 if not found.
     */
    public int fileSizeForRenderingOptions(RenderingOptions renderingOptions) {
        Metadata metadata = metadataMap.get(renderingOptions);
        return metadata != null && metadata.fileSize != null ? metadata.fileSize : 0;
    }

    /**
     * @return If the Imoji has animated GIF content available
     */
    public boolean hasAnimationCapability() {
        return metadataMap.get(RenderingOptions.animatedGifThumbnail()) != null;
    }

    /**
     * @return Gets either a bordered PNG thumbnail URL or GIF thumbnail URL if animation is
     * supported
     */
    public Uri getStandardThumbnailUri() {
        return this.getStandardThumbnailUri(true);
    }

    /**
     * @param supportAnimation Whether or not to fetch an animated URL or not
     * @return Gets either a bordered PNG thumbnail URL or GIF thumbnail URL if animation is
     * supported and requested
     */
    public Uri getStandardThumbnailUri(boolean supportAnimation) {
        if (supportAnimation && hasAnimationCapability()) {
            return this.urlForRenderingOption(RenderingOptions.animatedGifThumbnail());
        }

        return this.urlForRenderingOption(RenderingOptions.borderedPngThumbnail());
    }

    /**
     * @return Gets either a bordered PNG full size URL or GIF thumbnail URL if animation is
     * supported
     */
    public Uri getStandardFullSizeUri() {
        return this.getStandardFullSizeUri(true);
    }

    /**
     * @param supportAnimation Whether or not to fetch an animated URL or not
     * @return Gets either a bordered PNG full size URL or GIF thumbnail URL if animation is
     * supported and requested
     */
    public Uri getStandardFullSizeUri(boolean supportAnimation) {
        if (supportAnimation && hasAnimationCapability()) {
            return this.urlForRenderingOption(RenderingOptions.animatedGifFullSize());
        }

        return this.urlForRenderingOption(RenderingOptions.borderedPngFullSize());
    }

    public Imoji(@NonNull String identifier,
                 @NonNull List<String> tags,
                 @NonNull Map<RenderingOptions, Metadata> metadataMap,
                 @NonNull LicenseStyle licenseStyle) {
        this.identifier = identifier;
        this.tags = tags;
        this.metadataMap = metadataMap;
        this.licenseStyle = licenseStyle;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Imoji imoji = (Imoji) o;

        if (!identifier.equals(imoji.identifier)) return false;
        if (!tags.equals(imoji.tags)) return false;
        return metadataMap.equals(imoji.metadataMap);

    }

    @Override
    public int hashCode() {
        int result = identifier.hashCode();
        result = 31 * result + tags.hashCode();
        result = 31 * result + metadataMap.hashCode();
        return result;
    }

    /**
     * Parcelable Overrides
     */

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.identifier);
        dest.writeStringList(this.tags);
        dest.writeInt(this.licenseStyle.getValue());
        dest.writeInt(metadataMap.size());
        for (Map.Entry<RenderingOptions, Metadata> entry : metadataMap.entrySet()) {
            dest.writeParcelable(entry.getKey(), flags);
            dest.writeParcelable(entry.getValue(), flags);
        }
    }

    public static final Parcelable.Creator<Imoji> CREATOR
            = new Parcelable.Creator<Imoji>() {
        public Imoji createFromParcel(Parcel in) {
            return new Imoji(in);
        }

        public Imoji[] newArray(int size) {
            return new Imoji[size];
        }
    };

    private Imoji(Parcel in) {
        this.identifier = in.readString();
        this.tags = in.createStringArrayList();
        if (LicenseStyle.NonCommercial.getValue() == in.readInt()) {
            this.licenseStyle = LicenseStyle.NonCommercial;
        } else {
            this.licenseStyle = LicenseStyle.CommercialPrint;
        }

        int entryCount = in.readInt();
        if (entryCount > 0) {
            this.metadataMap = new HashMap<>(entryCount);
            for (int i = 0; i < entryCount; i++) {
                this.metadataMap.put(
                        in.<RenderingOptions>readParcelable(RenderingOptions.class.getClassLoader()),
                        in.<Metadata>readParcelable(Metadata.class.getClassLoader())
                );
            }
        } else {
            this.metadataMap = Collections.emptyMap();
        }
    }
}


text:
[Material Design](https://www.google.com/design/spec/material-design/) is a specification for a
unified system of visual, motion, and interaction design that adapts across different devices. Our
goal is to deliver a lean, lightweight set of AngularJS-native UI elements that implement the
material design specification for use in Angular single-page applications (SPAs).

![venn diagram](https://cloud.githubusercontent.com/assets/210413/5077572/30dfc2f0-6e6a-11e4-9723-07c918128f4f.png)

For developers using AngularJS, Angular Material is the reference implementation of Google's Material Design Specification. This project implements version 1.x of Angular Material and includes a rich set of reusable, well-tested, and accessible UI components.

Quick Links:

*  [API & Demos](#demos)
*  [Contributing](#contributing)
*  [Building](#building)
*  [Installing](#installing)

Please note that using Angular Material requires the use of **Angular 1.3.x** or higher. Angular
Material is targeted for all browsers with browser versions shown below with green boxes:

![ngm1_browser_support](https://cloud.githubusercontent.com/assets/210413/18553899/f3fbfbca-7b27-11e6-81c9-2937950c808e.png)

##  GitHub Universe

Based on the number of unique contributors and repository forks, GitHub Octoverse recently announced that Angular Material is one of the top 10 most-loved active projects on GitHub:

![angularongithubuniverse](https://cloud.githubusercontent.com/assets/210413/18553990/53cf2e32-7b28-11e6-8e08-29548fd3d786.jpg)

##  Online Documentation (and Demos)

- Visit [Material.AngularJS.org](https://material.angularjs.org/) online to review the API, see the
  components in action with live Demos, and study the Layout system.
- Or you can build the documentation and demos locally; see
  [Build Docs & Demos](https://github.com/angular/material/tree/master/docs/README.md) for details.

##  Our Release Processes

Angular Material has revised/improved its build processes. To preserve stability with applications currently using Angular Material, we will have three (3) types of releases:

*  `major` :  this type of release will be the Angular 2.x efforts maintained in a separate repository called [Material2](https://github.com/angular/material2). This type of release will not be used within Angular Material 1.x.
*  `minor`:  aka `master` contains patch release changes AND breaking changes and new features
*  `patch`:  non-breaking changes (no API, CSS, UX changes that will cause breaks in existing ngMaterial applications)

##### Patch Releases

The patch builds (1.0.4, 1.0.5, 1.0.6) are prepared based on commits in the `patch` branch; which contains only non-breaking changes (eg bug fix, some API additions, minimal non-breaking CSS changes ).  We will be building `patch` releases every week.

##### Minor Releases

The minor build (1.1.0, 1.2.0, 1.3.0,...) are prepared based on commits in the `master` branch; which will remain the daily development branch AND will be the source for the `minor` releases.

Our formal release of `minor` builds is much less frequent; probably 1x / Quarter. Developers can easily obtain the latest, full change-set from bower or npm using references to `@master`.

##### Changelog

The Changelog may contain releases for `patch` or `minor`. If you do not see a fix listed in the Changelog but the issue has been resolved or the PR merged, then those changes will be `master` available in the next *minor* release.

> for the purposes of Angular Material 1.x, you *could* think of the patch releases as being *minor* changes and the 'minor' releases as being *major* changes.

##  Contributing

Developers interested in contributing should read the following guidelines:

- [Issue Guidelines](.github/CONTRIBUTING.md#submit)
- [Contributing Guidelines](.github/CONTRIBUTING.md)
- [Coding Guidelines](docs/guides/CODING.md)
- [ChangeLog](CHANGELOG.md)

> Please do **not** ask general questions in an issue. Issues are only to report bugs, request
  enhancements, or request new features. For general questions and discussions, use the
  [Angular Material Forum](https://groups.google.com/forum/#!forum/ngmaterial).

It is important to note that for each release, the [ChangeLog](CHANGELOG.md) is a resource that will
itemize all:

- Bug Fixes
- New Features
- Breaking Changes

##  Building

Developers can easily build Angular Material using NPM and gulp.

* [Builds - Under the Hood](docs/guides/BUILD.md)

First install or update your local project's **npm** tools:

```bash
# First install all the NPM tools:
npm install

# Or update
npm update
```

Then run the **gulp** tasks:

```bash
# To build `angular-material.js/.css` and `Theme` files in the `/dist` directory
gulp build

# To build the Angular Material Docs and Demos in `/dist/docs` directory
gulp docs
```

For more details on how the build process works and additional commands (available for testing and
debugging) developers should read the [Build Instructions](docs/guides/BUILD.md).

##  Installing Build (Distribution Files)

#### Bower

For developers not interested in building the Angular Material library... use **bower** to install
and use the Angular Material distribution files.

Change to your project's root directory.

```bash
# To get the latest stable version, use Bower from the command line.
bower install angular-material

# To get the most recent, latest committed-to-master version use:
bower install angular-material#master
```

Visit [Bower-Material](https://github.com/angular/bower-material/blob/master/README.md) for more
details on how to install and use the Angular Material distribution files within your own local
project.

#### CDN

CDN versions of Angular Material are now available at
[Google Hosted Libraries](https://developers.google.com/speed/libraries/#angular-material).

With the Google CDN, you will not need to download local copies of the distribution files. Instead
simply reference the CDN urls to easily use those remote library files. This is especially useful
when using online tools such as [CodePen](http://codepen.io/), [Plunkr](http://plnkr.co/), or
[JSFiddle](http://jsfiddle.net/).

```html
  <head>

    <!-- Angular Material CSS now available via Google CDN; version 1.0.7 used here -->
    <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/0.11.2/angular-material.min.css">

  </head>
  <body>

    <!-- Angular Material Dependencies -->
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-animate.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-aria.min.js"></script>

    <!-- Angular Material Javascript now available via Google CDN; version 1.0.7 used here -->
    <script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.7/angular-material.min.js"></script>
  </body>
```

Developers seeking the latest, most-current build versions can use [GitCDN.link](//gitcdn.link) to
pull directly from the distribution GitHub
[Bower-Material](https://github.com/angular/bower-material) repository:

```html
  <head>

    <!-- Angular Material CSS using GitCDN to load directly from `bower-material/master` -->
    <link rel="stylesheet" href="https://gitcdn.link/repo/angular/bower-material/master/angular-material.css">

  </head>
  <body>

    <!-- Angular Material Dependencies -->
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-animate.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-aria.js"></script>

    <!-- Angular Material Javascript using GitCDN to load directly from `bower-material/master` -->
    <script src="https://gitcdn.link/repo/angular/bower-material/master/angular-material.js"></script>

  </body>
```

Once you have all the necessary assets installed, add `ngMaterial` as a dependency for your app:

```javascript
angular.module('myApp', ['ngMaterial']);
```

redpajama_set_name: RedPajamaGithub


text:
/*
 *  Some tests for .call() and .apply() with missing arguments.
 */

/*===
- Function.prototype.call()
undefined undefined undefined undefined
mythis undefined undefined undefined
mythis arg undefined undefined
- Function.prototype.apply()
undefined undefined undefined undefined
mythis undefined undefined undefined
mythis undefined undefined undefined
mythis undefined undefined undefined
mythis undefined undefined undefined
mythis arg undefined undefined
mythis undefined undefined undefined
mythis foo bar undefined
mythis FOO BAR undefined
TypeError
- Reflect.apply()
TypeError
TypeError
undefined undefined undefined undefined
mythis undefined undefined undefined
mythis undefined undefined undefined
mythis undefined undefined undefined
mythis undefined undefined undefined
mythis arg undefined undefined
mythis undefined undefined undefined
mythis foo bar undefined
mythis FOO BAR undefined
TypeError
done
===*/

function test() {
    function func(a,b,c) {
        'use strict';  // avoid 'this' coercion
        print(this, a, b, c);
    }

    var dummyFunc = function dummy(a,b) {};  // length: 2
    dummyFunc[0] = 'FOO';
    dummyFunc[1] = 'BAR';
    dummyFunc[2] = 'QUUX';

    // For .call() there are no required arguments.
    // This binding will be 'undefined'.
    print('- Function.prototype.call()');
    func.call();
    func.call('mythis');
    func.call('mythis', 'arg');

    // For .apply() there are similarly no required arguments.
    // argArray can be null/undefined and is treated like empty
    // array.  Array-like object is accepted (.length is respected);
    // other types cause a TypeError.  A function is an acceptable
    // input because it's an object and even has a .length!
    print('- Function.prototype.apply()');
    func.apply();
    func.apply('mythis');
    func.apply('mythis', void 0);
    func.apply('mythis', null);
    func.apply('mythis', []);
    func.apply('mythis', [ 'arg' ]);
    func.apply('mythis', {});  // no .length -> same as []
    func.apply('mythis', { length: 2, 0: 'foo', 1: 'bar', 2: 'quux-ignored' });
    func.apply('mythis', dummyFunc);
    try {
        func.apply('mythis', 123);
    } catch (e) {
        print(e.name);
    }

    // Reflect.apply() requires a callable first argument,
    // but is otherwise similar to Function.prototype.apply().
    print('- Reflect.apply()');
    try {
        Reflect.apply();
    } catch (e) {
        print(e.name);
    }
    try {
        Reflect.apply(123);
    } catch (e) {
        print(e.name);
    }
    Reflect.apply(func);
    Reflect.apply(func, 'mythis');
    Reflect.apply(func, 'mythis', void 0);
    Reflect.apply(func, 'mythis', null);
    Reflect.apply(func, 'mythis', []);
    Reflect.apply(func, 'mythis', [ 'arg' ]);
    Reflect.apply(func, 'mythis', {});
    Reflect.apply(func, 'mythis', { length: 2, 0: 'foo', 1: 'bar', 2: 'quux-ignored' });
    Reflect.apply(func, 'mythis', dummyFunc);
    try {
        Reflect.apply(func, 'mythis', 123);
    } catch (e) {
        print(e.name);
    }

    print('done');
}

try {
    test();
} catch (e) {
    print(e.stack || e);
}


text:
<?php

namespace DTS\eBaySDK\FileTransfer\Types;

/**
 *
 * @property \DTS\eBaySDK\FileTransfer\Types\FileAttachment $fileAttachment
 */
class DownloadFileResponse extends \DTS\eBaySDK\FileTransfer\Types\BaseServiceResponse
{
    /**
     * @var array Properties belonging to objects of this class.
     */
    private static $propertyTypes = array(
        'fileAttachment' => array(
            'type' => 'DTS\eBaySDK\FileTransfer\Types\FileAttachment',
            'unbound' => false,
            'attribute' => false,
            'elementName' => 'fileAttachment'
        )
    );

    /**
     * @param array $values Optional properties and values to assign to the object.
     */
    public function __construct(array $values = array())
    {
        list($parentValues, $childValues) = self::getParentValues(self::$propertyTypes, $values);

        parent::__construct($parentValues);

        if (!array_key_exists(__CLASS__, self::$properties)) {
            self::$properties[__CLASS__] = array_merge(self::$properties[get_parent_class()], self::$propertyTypes);
        }

        if (!array_key_exists(__CLASS__, self::$xmlNamespaces)) {
            self::$xmlNamespaces[__CLASS__] = 'http://www.ebay.com/marketplace/services';
        }

        if (!array_key_exists(__CLASS__, self::$requestXmlRootElementNames)) {
            self::$requestXmlRootElementNames[__CLASS__] = 'downloadFileResponse';
        }

        $this->setValues(__CLASS__, $childValues);
    }
}


text:
***************************
DEPRECATED: Tactics and Theorem Proving
***************************

.. warning::
   The interactive theorem-proving interface documented here has been
   deprecated in favor of :ref:`elaborator-reflection`.

Idris supports interactive theorem proving, and the analyse of context
through holes.  To list all unproven holes, use the command ``:m``.
This will display their qualified names and the expected types. To
interactively prove a holes, use the command ``:p name`` where ``name``
is the hole. Once the proof is complete, the command ``:a`` will append
it to the current module.

Once in the interactive prover, the following commands are available:

Basic commands
==============

-  ``:q`` - Quits the prover (gives up on proving current lemma).
-  ``:abandon`` - Same as :q
-  ``:state`` - Displays the current state of the proof.
-  ``:term`` - Displays the current proof term complete with its
   yet-to-be-filled holes (is only really useful for debugging).
-  ``:undo`` - Undoes the last tactic.
-  ``:qed`` - Once the interactive theorem prover tells you "No more
   goals," you get to type this in celebration! (Completes the proof and
   exits the prover)

Commonly Used Tactics
=====================

Compute
-------

-  ``compute`` - Normalises all terms in the goal (note: does not
   normalise assumptions)

::

    ----------                 Goal:                  ----------
     (Vect (S (S Z + (S Z) + (S n))) Nat) -> Vect (S (S (S (S n)))) Nat
    -lemma> compute
    ----------                 Goal:                  ----------
     (Vect (S (S (S (S n)))) Nat) -> Vect (S (S (S (S n)))) Nat
    -lemma>

Exact
-----

-  ``exact`` - Provide a term of the goal type directly.

::

    ----------                 Goal:                  ----------
     Nat
    -lemma> exact Z
    lemma: No more goals.
    -lemma>

Refine
------

-  ``refine`` - Use a name to refine the goal. If the name needs
   arguments, introduce them as new goals.

Trivial
-------

-  ``trivial`` - Satisfies the goal using an assumption that matches its
   type.

::

    ----------              Assumptions:              ----------
     value : Nat
    ----------                 Goal:                  ----------
     Nat
    -lemma> trivial
    lemma: No more goals.
    -lemma>

Intro
-----

-  ``intro`` - If your goal is an arrow, turns the left term into an
   assumption.

::

    ----------                 Goal:                  ----------
     Nat -> Nat -> Nat
    -lemma> intro
    ----------              Assumptions:              ----------
     n : Nat
    ----------                 Goal:                  ----------
     Nat -> Nat
    -lemma>

You can also supply your own name for the assumption:

::

    ----------                 Goal:                  ----------
    Nat -> Nat -> Nat
    -lemma> intro number
    ----------              Assumptions:              ----------
     number : Nat
    ----------                 Goal:                  ----------
    Nat -> Nat

Intros
------

-  ``intros`` - Exactly like intro, but it operates on all left terms at
   once.

::

    ----------                 Goal:                  ----------
     Nat -> Nat -> Nat
    -lemma> intros
    ----------              Assumptions:              ----------
     n : Nat
     m : Nat
    ----------                 Goal:                  ----------
     Nat
    -lemma>

let
---

-  ``let`` - Introduces a new assumption; you may use current
   assumptions to define the new one.

::

    ----------              Assumptions:              ----------
     n : Nat
    ----------                 Goal:                  ----------
     BigInt
    -lemma> let x = toIntegerNat n
    ----------              Assumptions:              ----------
     n : Nat
      x = toIntegerNat n: BigInt
    ----------                 Goal:                  ----------
     BigInt
    -lemma>

rewrite
-------

-  ``rewrite`` - Takes an expression with an equality type (x = y), and
   replaces all instances of x in the goal with y. Is often useful in
   combination with 'sym'.

::

    ----------              Assumptions:              ----------
     n : Nat
     a : Type
     value : Vect Z a
    ----------                 Goal:                  ----------
     Vect (mult n Z) a
    -lemma> rewrite sym (multZeroRightZero n)
    ----------              Assumptions:              ----------
     n : Nat
     a : Type
     value : Vect Z a
    ----------                 Goal:                  ----------
     Vect Z a
    -lemma>

induction
---------

-  ``induction`` - (``Note that this is still experimental`` and you may
   get strange results and error messages. We are aware of these and
   will finish the implementation eventually!) Prove the goal by
   induction. Each constructor of the datatype becomes a goal.
   Constructors with recursive arguments become induction steps, while
   simple constructors become base cases. Note that this only works for
   datatypes that have eliminators: a datatype definition must have the
   ``%elim`` modifier.

sourceLocation
--------------

-  ``sourceLocation`` - Solve the current goal with information about
   the location in the source code where the tactic was invoked. This is
   mostly for embedded DSLs and programmer tools like assertions that
   need to know where they are called. See
   ``Language.Reflection.SourceLocation`` for more information.

Less commonly-used tactics
==========================

-  ``applyTactic`` - Apply a user-defined tactic. This should be a
   function of type ``List (TTName, Binder TT) -> TT -> Tactic``, where
   the first argument represents the proof context and the second
   represents the goal. If your tactic will produce a proof term
   directly, use the ``Exact`` constructor from ``Tactic``.
-  ``attack`` - ?
-  ``equiv`` - Replaces the goal with a new one that is convertible with
   the old one
-  ``fill`` - ?
-  ``focus`` - ?
-  ``mrefine`` - Refining by matching against a type
-  ``reflect`` - ?
-  ``solve`` - Takes a guess with the correct type and fills a hole with
   it, closing a proof obligation. This happens automatically in the
   interactive prover, so ``solve`` is really only relevant in tactic
   scripts used for helping implicit argument resolution.
-  ``try`` - ?


text:
package org.datanucleus.tests.application;

import org.datanucleus.ClassLoaderResolver;
import org.datanucleus.identity.IdentityUtils;
import org.datanucleus.metadata.AbstractClassMetaData;
import org.datanucleus.metadata.AbstractMemberMetaData;
import org.datanucleus.metadata.MetaDataManager;
import org.datanucleus.tests.JDOPersistenceTestCase;
import org.jpox.samples.identity.application.ComposedIntIDBase;
import org.jpox.samples.identity.application.ComposedMixedIDBase;
import org.jpox.samples.identity.application.ComposedStringIDBase;

/**
 * Test convenience functions in IdentityUtils.
 */
public class IdentityUtilsTest extends JDOPersistenceTestCase
{
    private static boolean initialised = false;

    public IdentityUtilsTest(String name)
    {
        super(name);

        if (!initialised)
        {
            addClassesToSchema(new Class[]
                {
                    ComposedIntIDBase.class,
                    ComposedStringIDBase.class,
                    ComposedMixedIDBase.class
                });
            initialised = true;
        }
    }

    public void testGetValueForMemberInId()
    throws Exception
    {
        MetaDataManager mmgr = storeMgr.getNucleusContext().getMetaDataManager();
        ClassLoaderResolver clr = storeMgr.getNucleusContext().getClassLoaderResolver(null);

        // a). composed of two ints
        {
            org.jpox.samples.identity.application.ComposedIntIDBase.Key key =
                new org.jpox.samples.identity.application.ComposedIntIDBase.Key();
            key.code = 123;
            key.composed = 4567;

            AbstractClassMetaData cmd = mmgr.getMetaDataForClass(ComposedIntIDBase.class, clr);
            int[] pkNums = cmd.getPKMemberPositions();

            // Check code
            AbstractMemberMetaData pkMmd0 = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkNums[0]);
            assertEquals("code", pkMmd0.getName());
            Object pkVal0 = IdentityUtils.getValueForMemberInId(key, pkMmd0);
            assertEquals(123, pkVal0);

            // Check composed
            AbstractMemberMetaData pkMmd1 = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkNums[1]);
            assertEquals("composed", pkMmd1.getName());
            Object pkVal1 = IdentityUtils.getValueForMemberInId(key, pkMmd1);
            assertEquals(4567, pkVal1);
        }

        // b). composed of two Strings
        {
            org.jpox.samples.identity.application.ComposedStringIDBase.Key key =
                new org.jpox.samples.identity.application.ComposedStringIDBase.Key();
            key.code = "123";
            key.composed = "4567";

            AbstractClassMetaData cmd = mmgr.getMetaDataForClass(ComposedStringIDBase.class, clr);
            int[] pkNums = cmd.getPKMemberPositions();

            // Check code
            AbstractMemberMetaData pkMmd0 = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkNums[0]);
            assertEquals("code", pkMmd0.getName());
            Object pkVal0 = IdentityUtils.getValueForMemberInId(key, pkMmd0);
            assertEquals("123", pkVal0);

            // Check composed
            AbstractMemberMetaData pkMmd1 = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkNums[1]);
            assertEquals("composed", pkMmd1.getName());
            Object pkVal1 = IdentityUtils.getValueForMemberInId(key, pkMmd1);
            assertEquals("4567", pkVal1);
        }

        // b). composed of int+String+Double
        {
            org.jpox.samples.identity.application.ComposedMixedIDBase.Key key =
                new org.jpox.samples.identity.application.ComposedMixedIDBase.Key();
            key.code = 123;
            key.composed = "4567";
            key.doubleObjField = 5.0;

            AbstractClassMetaData cmd = mmgr.getMetaDataForClass(ComposedMixedIDBase.class, clr);
            int[] pkNums = cmd.getPKMemberPositions();

            // Check code
            AbstractMemberMetaData pkMmd0 = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkNums[0]);
            assertEquals("code", pkMmd0.getName());
            Object pkVal0 = IdentityUtils.getValueForMemberInId(key, pkMmd0);
            assertEquals(123, pkVal0);

            // Check composed
            AbstractMemberMetaData pkMmd1 = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkNums[1]);
            assertEquals("composed", pkMmd1.getName());
            Object pkVal1 = IdentityUtils.getValueForMemberInId(key, pkMmd1);
            assertEquals("4567", pkVal1);

            // Check composed
            AbstractMemberMetaData pkMmd2 = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkNums[2]);
            assertEquals("doubleObjField", pkMmd2.getName());
            Object pkVal2 = IdentityUtils.getValueForMemberInId(key, pkMmd2);
            assertEquals(5.0, pkVal2);
        }
    }
}


text:
// -----------------------------------------------------------------------------
//
// Copyright Microsoft Corporation
// 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 a tool.
//     Runtime Version:4.0.30319.42000
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace Microsoft.Azure.Commands.Batch.Models
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using Microsoft.Azure.Batch;

    public class PSAutoScaleEvaluation
    {

        internal Microsoft.Azure.Batch.AutoScaleEvaluation omObject;

        private PSAutoScaleRun autoScaleRun;

        internal PSAutoScaleEvaluation(Microsoft.Azure.Batch.AutoScaleEvaluation omObject)
        {
            if ((omObject == null))
            {
                throw new System.ArgumentNullException("omObject");
            }
            this.omObject = omObject;
        }

        public PSAutoScaleRun AutoScaleRun
        {
            get
            {
                if (((this.autoScaleRun == null)
                            && (this.omObject.AutoScaleRun != null)))
                {
                    this.autoScaleRun = new PSAutoScaleRun(this.omObject.AutoScaleRun);
                }
                return this.autoScaleRun;
            }
        }

        public string DataServiceId
        {
            get
            {
                return this.omObject.DataServiceId;
            }
        }
    }
}


text:
package org.xnio.nio;

import static org.xnio.IoUtils.safeClose;
import static org.xnio.nio.Log.log;
import static org.xnio.nio.Log.tcpServerLog;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;

import org.jboss.logging.Logger;
import org.xnio.ChannelListener;
import org.xnio.ManagementRegistration;
import org.xnio.IoUtils;
import org.xnio.LocalSocketAddress;
import org.xnio.Option;
import org.xnio.OptionMap;
import org.xnio.Options;
import org.xnio.StreamConnection;
import org.xnio.XnioExecutor;
import org.xnio.channels.AcceptListenerSettable;
import org.xnio.channels.AcceptingChannel;
import org.xnio.channels.UnsupportedOptionException;
import org.xnio.management.XnioServerMXBean;

final class NioTcpServer extends AbstractNioChannel<NioTcpServer> implements AcceptingChannel<StreamConnection>, AcceptListenerSettable<NioTcpServer> {
    private static final String FQCN = NioTcpServer.class.getName();

    private volatile ChannelListener<? super NioTcpServer> acceptListener;

    private final NioTcpServerHandle[] handles;

    private final ServerSocketChannel channel;
    private final ServerSocket socket;
    private final ManagementRegistration mbeanHandle;

    private static final Set<Option<?>> options = Option.setBuilder()
            .add(Options.REUSE_ADDRESSES)
            .add(Options.RECEIVE_BUFFER)
            .add(Options.SEND_BUFFER)
            .add(Options.KEEP_ALIVE)
            .add(Options.TCP_OOB_INLINE)
            .add(Options.TCP_NODELAY)
            .add(Options.CONNECTION_HIGH_WATER)
            .add(Options.CONNECTION_LOW_WATER)
            .add(Options.READ_TIMEOUT)
            .add(Options.WRITE_TIMEOUT)
            .create();

    @SuppressWarnings("unused")
    private volatile int keepAlive;
    @SuppressWarnings("unused")
    private volatile int oobInline;
    @SuppressWarnings("unused")
    private volatile int tcpNoDelay;
    @SuppressWarnings("unused")
    private volatile int sendBuffer = -1;
    @SuppressWarnings("unused")
    private volatile long connectionStatus = CONN_LOW_MASK | CONN_HIGH_MASK;
    @SuppressWarnings("unused")
    private volatile int readTimeout;
    @SuppressWarnings("unused")
    private volatile int writeTimeout;
    private volatile int tokenConnectionCount;
    volatile boolean resumed;

    private static final long CONN_LOW_MASK     = 0x000000007FFFFFFFL;
    private static final long CONN_LOW_BIT      = 0L;
    @SuppressWarnings("unused")
    private static final long CONN_LOW_ONE      = 1L;
    private static final long CONN_HIGH_MASK    = 0x3FFFFFFF80000000L;
    private static final long CONN_HIGH_BIT     = 31L;
    @SuppressWarnings("unused")
    private static final long CONN_HIGH_ONE     = 1L << CONN_HIGH_BIT;

    private static final AtomicIntegerFieldUpdater<NioTcpServer> keepAliveUpdater = AtomicIntegerFieldUpdater.newUpdater(NioTcpServer.class, "keepAlive");
    private static final AtomicIntegerFieldUpdater<NioTcpServer> oobInlineUpdater = AtomicIntegerFieldUpdater.newUpdater(NioTcpServer.class, "oobInline");
    private static final AtomicIntegerFieldUpdater<NioTcpServer> tcpNoDelayUpdater = AtomicIntegerFieldUpdater.newUpdater(NioTcpServer.class, "tcpNoDelay");
    private static final AtomicIntegerFieldUpdater<NioTcpServer> sendBufferUpdater = AtomicIntegerFieldUpdater.newUpdater(NioTcpServer.class, "sendBuffer");
    private static final AtomicIntegerFieldUpdater<NioTcpServer> readTimeoutUpdater = AtomicIntegerFieldUpdater.newUpdater(NioTcpServer.class, "readTimeout");
    private static final AtomicIntegerFieldUpdater<NioTcpServer> writeTimeoutUpdater = AtomicIntegerFieldUpdater.newUpdater(NioTcpServer.class, "writeTimeout");

    private static final AtomicLongFieldUpdater<NioTcpServer> connectionStatusUpdater = AtomicLongFieldUpdater.newUpdater(NioTcpServer.class, "connectionStatus");

    NioTcpServer(final NioXnioWorker worker, final ServerSocketChannel channel, final OptionMap optionMap) throws IOException {
        super(worker);
        this.channel = channel;
        final WorkerThread[] threads = worker.getAll();
        final int threadCount = threads.length;
        if (threadCount == 0) {
            throw log.noThreads();
        }
        final int tokens = optionMap.get(Options.BALANCING_TOKENS, -1);
        final int connections = optionMap.get(Options.BALANCING_CONNECTIONS, 16);
        if (tokens != -1) {
            if (tokens < 1 || tokens >= threadCount) {
                throw log.balancingTokens();
            }
            if (connections < 1) {
                throw log.balancingConnectionCount();
            }
            tokenConnectionCount = connections;
        }
        socket = channel.socket();
        if (optionMap.contains(Options.SEND_BUFFER)) {
            final int sendBufferSize = optionMap.get(Options.SEND_BUFFER, DEFAULT_BUFFER_SIZE);
            if (sendBufferSize < 1) {
                throw log.parameterOutOfRange("sendBufferSize");
            }
            sendBufferUpdater.set(this, sendBufferSize);
        }
        if (optionMap.contains(Options.KEEP_ALIVE)) {
            keepAliveUpdater.lazySet(this, optionMap.get(Options.KEEP_ALIVE, false) ? 1 : 0);
        }
        if (optionMap.contains(Options.TCP_OOB_INLINE)) {
            oobInlineUpdater.lazySet(this, optionMap.get(Options.TCP_OOB_INLINE, false) ? 1 : 0);
        }
        if (optionMap.contains(Options.TCP_NODELAY)) {
            tcpNoDelayUpdater.lazySet(this, optionMap.get(Options.TCP_NODELAY, false) ? 1 : 0);
        }
        if (optionMap.contains(Options.READ_TIMEOUT)) {
            readTimeoutUpdater.lazySet(this, optionMap.get(Options.READ_TIMEOUT, 0));
        }
        if (optionMap.contains(Options.WRITE_TIMEOUT)) {
            writeTimeoutUpdater.lazySet(this, optionMap.get(Options.WRITE_TIMEOUT, 0));
        }
        int perThreadLow, perThreadLowRem;
        int perThreadHigh, perThreadHighRem;
        if (optionMap.contains(Options.CONNECTION_HIGH_WATER) || optionMap.contains(Options.CONNECTION_LOW_WATER)) {
            final int highWater = optionMap.get(Options.CONNECTION_HIGH_WATER, Integer.MAX_VALUE);
            final int lowWater = optionMap.get(Options.CONNECTION_LOW_WATER, highWater);
            if (highWater <= 0) {
                throw badHighWater();
            }
            if (lowWater <= 0 || lowWater > highWater) {
                throw badLowWater(highWater);
            }
            final long highLowWater = (long) highWater << CONN_HIGH_BIT | (long) lowWater << CONN_LOW_BIT;
            connectionStatusUpdater.lazySet(this, highLowWater);
            perThreadLow = lowWater / threadCount;
            perThreadLowRem = lowWater % threadCount;
            perThreadHigh = highWater / threadCount;
            perThreadHighRem = highWater % threadCount;
        } else {
            perThreadLow = Integer.MAX_VALUE;
            perThreadLowRem = 0;
            perThreadHigh = Integer.MAX_VALUE;
            perThreadHighRem = 0;
            connectionStatusUpdater.lazySet(this, CONN_LOW_MASK | CONN_HIGH_MASK);
        }
        final NioTcpServerHandle[] handles = new NioTcpServerHandle[threadCount];
        for (int i = 0, length = threadCount; i < length; i++) {
            final SelectionKey key = threads[i].registerChannel(channel);
            handles[i] = new NioTcpServerHandle(this, key, threads[i], i < perThreadHighRem ? perThreadHigh + 1 : perThreadHigh, i < perThreadLowRem ? perThreadLow + 1 : perThreadLow);
            key.attach(handles[i]);
        }
        this.handles = handles;
        if (tokens > 0) {
            for (int i = 0; i < threadCount; i ++) {
                handles[i].initializeTokenCount(i < tokens ? connections : 0);
            }
        }
        mbeanHandle = worker.registerServerMXBean(
                new XnioServerMXBean() {
                    public String getProviderName() {
                        return "nio";
                    }

                    public String getWorkerName() {
                        return worker.getName();
                    }

                    public String getBindAddress() {
                        return String.valueOf(getLocalAddress());
                    }

                    public int getConnectionCount() {
                        final AtomicInteger counter = new AtomicInteger();
                        final CountDownLatch latch = new CountDownLatch(handles.length);
                        for (final NioTcpServerHandle handle : handles) {
                            handle.getWorkerThread().execute(() -> {
                                counter.getAndAdd(handle.getConnectionCount());
                                latch.countDown();
                            });
                        }
                        try {
                            latch.await();
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                        }
                        return counter.get();
                    }

                    public int getConnectionLimitHighWater() {
                        return getHighWater(connectionStatus);
                    }

                    public int getConnectionLimitLowWater() {
                        return getLowWater(connectionStatus);
                    }
                }
        );

    }

    private static IllegalArgumentException badLowWater(final int highWater) {
        return new IllegalArgumentException("Low water must be greater than 0 and less than or equal to high water (" + highWater + ")");
    }

    private static IllegalArgumentException badHighWater() {
        return new IllegalArgumentException("High water must be greater than 0");
    }

    public void close() throws IOException {
        try {
            channel.close();
        } finally {
            for (NioTcpServerHandle handle : handles) {
                handle.getWorkerThread().cancelKey(handle.getSelectionKey());
            }
            safeClose(mbeanHandle);
        }
    }

    public boolean supportsOption(final Option<?> option) {
        return options.contains(option);
    }

    public <T> T getOption(final Option<T> option) throws UnsupportedOptionException, IOException {
        if (option == Options.REUSE_ADDRESSES) {
            return option.cast(Boolean.valueOf(socket.getReuseAddress()));
        } else if (option == Options.RECEIVE_BUFFER) {
            return option.cast(Integer.valueOf(socket.getReceiveBufferSize()));
        } else if (option == Options.SEND_BUFFER) {
            final int value = sendBuffer;
            return value == -1 ? null : option.cast(Integer.valueOf(value));
        } else if (option == Options.KEEP_ALIVE) {
            return option.cast(Boolean.valueOf(keepAlive != 0));
        } else if (option == Options.TCP_OOB_INLINE) {
            return option.cast(Boolean.valueOf(oobInline != 0));
        } else if (option == Options.TCP_NODELAY) {
            return option.cast(Boolean.valueOf(tcpNoDelay != 0));
        } else if (option == Options.READ_TIMEOUT) {
            return option.cast(Integer.valueOf(readTimeout));
        } else if (option == Options.WRITE_TIMEOUT) {
            return option.cast(Integer.valueOf(writeTimeout));
        } else if (option == Options.CONNECTION_HIGH_WATER) {
            return option.cast(Integer.valueOf(getHighWater(connectionStatus)));
        } else if (option == Options.CONNECTION_LOW_WATER) {
            return option.cast(Integer.valueOf(getLowWater(connectionStatus)));
        } else {
            return null;
        }
    }

    public <T> T setOption(final Option<T> option, final T value) throws IllegalArgumentException, IOException {
        final Object old;
        if (option == Options.REUSE_ADDRESSES) {
            old = Boolean.valueOf(socket.getReuseAddress());
            socket.setReuseAddress(Options.REUSE_ADDRESSES.cast(value, Boolean.FALSE).booleanValue());
        } else if (option == Options.RECEIVE_BUFFER) {
            old = Integer.valueOf(socket.getReceiveBufferSize());
            final int newValue = Options.RECEIVE_BUFFER.cast(value, Integer.valueOf(DEFAULT_BUFFER_SIZE)).intValue();
            if (newValue < 1) {
                throw log.optionOutOfRange("RECEIVE_BUFFER");
            }
            socket.setReceiveBufferSize(newValue);
        } else if (option == Options.SEND_BUFFER) {
            final int newValue = Options.SEND_BUFFER.cast(value, Integer.valueOf(DEFAULT_BUFFER_SIZE)).intValue();
            if (newValue < 1) {
                throw log.optionOutOfRange("SEND_BUFFER");
            }
            final int oldValue = sendBufferUpdater.getAndSet(this, newValue);
            old = oldValue == -1 ? null : Integer.valueOf(oldValue);
        } else if (option == Options.KEEP_ALIVE) {
            old = Boolean.valueOf(keepAliveUpdater.getAndSet(this, Options.KEEP_ALIVE.cast(value, Boolean.FALSE).booleanValue() ? 1 : 0) != 0);
        } else if (option == Options.TCP_OOB_INLINE) {
            old = Boolean.valueOf(oobInlineUpdater.getAndSet(this, Options.TCP_OOB_INLINE.cast(value, Boolean.FALSE).booleanValue() ? 1 : 0) != 0);
        } else if (option == Options.TCP_NODELAY) {
            old = Boolean.valueOf(tcpNoDelayUpdater.getAndSet(this, Options.TCP_NODELAY.cast(value, Boolean.FALSE).booleanValue() ? 1 : 0) != 0);
        } else if (option == Options.READ_TIMEOUT) {
            old = Integer.valueOf(readTimeoutUpdater.getAndSet(this, Options.READ_TIMEOUT.cast(value, Integer.valueOf(0)).intValue()));
        } else if (option == Options.WRITE_TIMEOUT) {
            old = Integer.valueOf(writeTimeoutUpdater.getAndSet(this, Options.WRITE_TIMEOUT.cast(value, Integer.valueOf(0)).intValue()));
        } else if (option == Options.CONNECTION_HIGH_WATER) {
            old = Integer.valueOf(getHighWater(updateWaterMark(-1, Options.CONNECTION_HIGH_WATER.cast(value, Integer.valueOf(Integer.MAX_VALUE)).intValue())));
        } else if (option == Options.CONNECTION_LOW_WATER) {
            old = Integer.valueOf(getLowWater(updateWaterMark(Options.CONNECTION_LOW_WATER.cast(value, Integer.valueOf(Integer.MAX_VALUE)).intValue(), -1)));
        } else {
            return null;
        }
        return option.cast(old);
    }

    private long updateWaterMark(int reqNewLowWater, int reqNewHighWater) {
        // at least one must be specified
        assert reqNewLowWater != -1 || reqNewHighWater != -1;
        // if both given, low must be less than high
        assert reqNewLowWater == -1 || reqNewHighWater == -1 || reqNewLowWater <= reqNewHighWater;

        long oldVal, newVal;
        int oldHighWater, oldLowWater;
        int newLowWater, newHighWater;

        do {
            oldVal = connectionStatus;
            oldLowWater = getLowWater(oldVal);
            oldHighWater = getHighWater(oldVal);
            newLowWater = reqNewLowWater == -1 ? oldLowWater : reqNewLowWater;
            newHighWater = reqNewHighWater == -1 ? oldHighWater : reqNewHighWater;
            // Make sure the new values make sense
            if (reqNewLowWater != -1 && newLowWater > newHighWater) {
                newHighWater = newLowWater;
            } else if (reqNewHighWater != -1 && newHighWater < newLowWater) {
                newLowWater = newHighWater;
            }
            // See if the change would be redundant
            if (oldLowWater == newLowWater && oldHighWater == newHighWater) {
                return oldVal;
            }
            newVal = (long)newLowWater << CONN_LOW_BIT | (long)newHighWater << CONN_HIGH_BIT;
        } while (! connectionStatusUpdater.compareAndSet(this, oldVal, newVal));

        final NioTcpServerHandle[] conduits = handles;
        final int threadCount = conduits.length;

        int perThreadLow, perThreadLowRem;
        int perThreadHigh, perThreadHighRem;

        perThreadLow = newLowWater / threadCount;
        perThreadLowRem = newLowWater % threadCount;
        perThreadHigh = newHighWater / threadCount;
        perThreadHighRem = newHighWater % threadCount;

        for (int i = 0; i < conduits.length; i++) {
            NioTcpServerHandle conduit = conduits[i];
            conduit.executeSetTask(i < perThreadHighRem ? perThreadHigh + 1 : perThreadHigh, i < perThreadLowRem ? perThreadLow + 1 : perThreadLow);
        }

        return oldVal;
    }

    private static int getHighWater(final long value) {
        return (int) ((value & CONN_HIGH_MASK) >> CONN_HIGH_BIT);
    }

    private static int getLowWater(final long value) {
        return (int) ((value & CONN_LOW_MASK) >> CONN_LOW_BIT);
    }

    public NioSocketStreamConnection accept() throws IOException {
        final WorkerThread current = WorkerThread.getCurrent();
        final NioTcpServerHandle handle = handles[current.getNumber()];
        if (! handle.getConnection()) {
            return null;
        }
        final SocketChannel accepted;
        boolean ok = false;
        try {
            accepted = channel.accept();
            if (accepted != null) try {
                final SocketAddress localAddress = accepted.getLocalAddress();
                int hash;
                if (localAddress instanceof InetSocketAddress) {
                    final InetSocketAddress address = (InetSocketAddress) localAddress;
                    hash = address.getAddress().hashCode() * 23 + address.getPort();
                } else if (localAddress instanceof LocalSocketAddress) {
                    hash = ((LocalSocketAddress) localAddress).getName().hashCode();
                } else {
                    hash = localAddress.hashCode();
                }
                final SocketAddress remoteAddress = accepted.getRemoteAddress();
                if (remoteAddress instanceof InetSocketAddress) {
                    final InetSocketAddress address = (InetSocketAddress) remoteAddress;
                    hash = (address.getAddress().hashCode() * 23 + address.getPort()) * 23 + hash;
                } else if (remoteAddress instanceof LocalSocketAddress) {
                    hash = ((LocalSocketAddress) remoteAddress).getName().hashCode() * 23 + hash;
                } else {
                    hash = localAddress.hashCode() * 23 + hash;
                }
                accepted.configureBlocking(false);
                final Socket socket = accepted.socket();
                socket.setKeepAlive(keepAlive != 0);
                socket.setOOBInline(oobInline != 0);
                socket.setTcpNoDelay(tcpNoDelay != 0);
                final int sendBuffer = this.sendBuffer;
                if (sendBuffer > 0) socket.setSendBufferSize(sendBuffer);
                final WorkerThread ioThread = worker.getIoThread(hash);
                final SelectionKey selectionKey = ioThread.registerChannel(accepted);
                final NioSocketStreamConnection newConnection = new NioSocketStreamConnection(ioThread, selectionKey, handle);
                newConnection.setOption(Options.READ_TIMEOUT, Integer.valueOf(readTimeout));
                newConnection.setOption(Options.WRITE_TIMEOUT, Integer.valueOf(writeTimeout));
                ok = true;
                return newConnection;
            } finally {
                if (! ok) safeClose(accepted);
            }
        } catch (IOException e) {
            return null;
        } finally {
            if (! ok) {
                handle.freeConnection();
            }
        }
        // by contract, only a resume will do
        return null;
    }

    public String toString() {
        return String.format("TCP server (NIO) <%s>", Integer.toHexString(hashCode()));
    }

    public ChannelListener<? super NioTcpServer> getAcceptListener() {
        return acceptListener;
    }

    public void setAcceptListener(final ChannelListener<? super NioTcpServer> acceptListener) {
        this.acceptListener = acceptListener;
    }

    public ChannelListener.Setter<NioTcpServer> getAcceptSetter() {
        return new AcceptListenerSettable.Setter<NioTcpServer>(this);
    }

    public boolean isOpen() {
        return channel.isOpen();
    }

    public SocketAddress getLocalAddress() {
        return socket.getLocalSocketAddress();
    }

    public <A extends SocketAddress> A getLocalAddress(final Class<A> type) {
        final SocketAddress address = getLocalAddress();
        return type.isInstance(address) ? type.cast(address) : null;
    }

    public void suspendAccepts() {
        resumed = false;
        doResume(0);
    }

    public void resumeAccepts() {
        resumed = true;
        doResume(SelectionKey.OP_ACCEPT);
    }

    public boolean isAcceptResumed() {
        return resumed;
    }

    private void doResume(final int op) {
        if (op == 0) {
            for (NioTcpServerHandle handle : handles) {
                handle.suspend();
            }
        } else {
            for (NioTcpServerHandle handle : handles) {
                handle.resume();
            }
        }
    }

    public void wakeupAccepts() {
        tcpServerLog.logf(FQCN, Logger.Level.TRACE, null, "Wake up accepts on %s", this);
        resumeAccepts();
        final NioTcpServerHandle[] handles = this.handles;
        final int idx = IoUtils.getThreadLocalRandom().nextInt(handles.length);
        handles[idx].wakeup(SelectionKey.OP_ACCEPT);
    }

    public void awaitAcceptable() throws IOException {
        throw log.unsupported("awaitAcceptable");
    }

    public void awaitAcceptable(final long time, final TimeUnit timeUnit) throws IOException {
        throw log.unsupported("awaitAcceptable");
    }

    @Deprecated
    public XnioExecutor getAcceptThread() {
        return getIoThread();
    }

    NioTcpServerHandle getHandle(final int number) {
        return handles[number];
    }

    int getTokenConnectionCount() {
        return tokenConnectionCount;
    }
}


text:
<?php
namespace RecurlyTest\Listener;

use Recurly\Exception;
use Recurly\Listener\ErrorListener;
use Zend\Http\Response as HttpResponse;
use Zend\Mvc\MvcEvent;

class ErrorListenerTest extends \PHPUnit_Framework_TestCase
{
    public function testAttachEvent()
    {
        $listener = new ErrorListener();

        $eventManager = $this->getMock('Zend\EventManager\EventManagerInterface');
        $eventManager->expects($this->once())
                     ->method('attach')
                     ->with(MvcEvent::EVENT_DISPATCH_ERROR);

        $listener->attach($eventManager);
    }

    public function testFillEvent()
    {
        $event = new MvcEvent();
        $event->setParam('exception', new Exception\UnauthorizedException());

        $response = new HttpResponse();
        $event->setResponse($response);

        $listener = new ErrorListener();
        $listener->onError($event);
    }

    public function testFillEventWithoutException()
    {
        $event = new MvcEvent();

        $response = new HttpResponse();
        $event->setResponse($response);

        $listener = new ErrorListener();
        $listener->onError($event);

        $this->assertEquals(HttpResponse::STATUS_CODE_200, $response->getStatusCode());
    }
}


text:
<?php

final class PhabricatorAuditActionConstants extends Phobject {

  const CONCERN   = 'concern';
  const ACCEPT    = 'accept';
  const COMMENT   = 'comment';
  const RESIGN    = 'resign';
  const CLOSE     = 'close';
  const ADD_CCS = 'add_ccs';
  const ADD_AUDITORS = 'add_auditors';
  const INLINE = 'audit:inline';
  const ACTION = 'audit:action';

}


text:
using System.Web.Mvc;
using BlogIT.Web.Controllers;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace BlogIT.Web.Tests.Controllers
{
    [TestClass]
    public class HomeControllerTest
    {
        [TestMethod]
        public void Index()
        {
            // Arrange
            var controller = new HomeController();

            // Act
            var result = controller.Index() as ViewResult;

            // Assert
            Assert.IsNotNull(result);
        }

        [TestMethod]
        public void About()
        {
            // Arrange
            var controller = new HomeController();

            // Act
            var result = controller.About() as ViewResult;

            // Assert
            Assert.AreEqual("Your application description page.", result.ViewBag.Message);
        }

        [TestMethod]
        public void Contact()
        {
            // Arrange
            var controller = new HomeController();

            // Act
            var result = controller.Contact() as ViewResult;

            // Assert
            Assert.IsNotNull(result);
        }
    }
}


text:
namespace Microsoft.WindowsAzure.Storage.DataMovement
{
    using System;
    using System.Globalization;
    using Microsoft.WindowsAzure.Storage.Auth;
    using Microsoft.WindowsAzure.Storage.Blob;
    using Microsoft.WindowsAzure.Storage.File;

    /// <summary>
    /// Extension methods for CloudBlobs for use with BlobTransfer.
    /// </summary>
    internal static class StorageExtensions
    {
        /// <summary>
        /// Determines whether two blobs have the same Uri and SnapshotTime.
        /// </summary>
        /// <param name="blob">Blob to compare.</param>
        /// <param name="comparand">Comparand object.</param>
        /// <returns>True if the two blobs have the same Uri and SnapshotTime; otherwise, false.</returns>
        internal static bool Equals(
            CloudBlob blob,
            CloudBlob comparand)
        {
            if (blob == comparand)
            {
                return true;
            }

            if (null == blob || null == comparand)
            {
                return false;
            }

            return blob.Uri.Equals(comparand.Uri) &&
                blob.SnapshotTime.Equals(comparand.SnapshotTime);
        }

        internal static CloudFile GenerateCopySourceFile(
            this CloudFile file)
        {
            if (null == file)
            {
                throw new ArgumentNullException("file");
            }

            string sasToken = GetFileSASToken(file);

            if (string.IsNullOrEmpty(sasToken))
            {
                return file;
            }

            return new CloudFile(file.Uri, new StorageCredentials(sasToken));
        }

        private static string GetFileSASToken(CloudFile file)
        {
            if (null == file.ServiceClient.Credentials
                || file.ServiceClient.Credentials.IsAnonymous)
            {
                return string.Empty;
            }
            else if (file.ServiceClient.Credentials.IsSAS)
            {
                return file.ServiceClient.Credentials.SASToken;
            }

            // SAS life time is at least 10 minutes.
            TimeSpan sasLifeTime = TimeSpan.FromMinutes(Constants.CopySASLifeTimeInMinutes);

            SharedAccessFilePolicy policy = new SharedAccessFilePolicy()
            {
                SharedAccessExpiryTime = DateTime.Now.Add(sasLifeTime),
                Permissions = SharedAccessFilePermissions.Read,
            };

            return file.GetSharedAccessSignature(policy);
        }

        /// <summary>
        /// Append an auto generated SAS to a blob uri.
        /// </summary>
        /// <param name="blob">Blob to append SAS.</param>
        /// <returns>Blob Uri with SAS appended.</returns>
        internal static CloudBlob GenerateCopySourceBlob(
            this CloudBlob blob)
        {
            if (null == blob)
            {
                throw new ArgumentNullException("blob");
            }

            string sasToken = GetBlobSasToken(blob);

            if (string.IsNullOrEmpty(sasToken))
            {
                return blob;
            }

            Uri blobUri = null;

            if (blob.IsSnapshot)
            {
                blobUri = blob.SnapshotQualifiedUri;
            }
            else
            {
                blobUri = blob.Uri;
            }

            return Utils.GetBlobReference(blobUri, new StorageCredentials(sasToken), blob.BlobType);
        }

        /// <summary>
        /// Append an auto generated SAS to a blob uri.
        /// </summary>
        /// <param name="blob">Blob to append SAS.</param>
        /// <returns>Blob Uri with SAS appended.</returns>
        internal static Uri GenerateUriWithCredentials(
            this CloudBlob blob)
        {
            if (null == blob)
            {
                throw new ArgumentNullException("blob");
            }

            string sasToken = GetBlobSasToken(blob);

            if (string.IsNullOrEmpty(sasToken))
            {
                return blob.SnapshotQualifiedUri;
            }

            string uriStr = null;

            if (blob.IsSnapshot)
            {
                uriStr = string.Format(CultureInfo.InvariantCulture, "{0}&{1}", blob.SnapshotQualifiedUri.AbsoluteUri, sasToken.Substring(1));
            }
            else
            {
                uriStr = string.Format(CultureInfo.InvariantCulture, "{0}{1}", blob.Uri.AbsoluteUri, sasToken);
            }

            return new Uri(uriStr);
        }

        private static string GetBlobSasToken(CloudBlob blob)
        {
            if (null == blob.ServiceClient.Credentials
                || blob.ServiceClient.Credentials.IsAnonymous)
            {
                return string.Empty;
            }
            else if (blob.ServiceClient.Credentials.IsSAS)
            {
                return blob.ServiceClient.Credentials.SASToken;
            }

            // SAS life time is at least 10 minutes.
            TimeSpan sasLifeTime = TimeSpan.FromMinutes(Constants.CopySASLifeTimeInMinutes);

            SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy()
            {
                SharedAccessExpiryTime = DateTime.Now.Add(sasLifeTime),
                Permissions = SharedAccessBlobPermissions.Read,
            };

            CloudBlob rootBlob = null;

            if (!blob.IsSnapshot)
            {
                rootBlob = blob;
            }
            else
            {
                rootBlob = Utils.GetBlobReference(blob.Uri, blob.ServiceClient.Credentials, blob.BlobType);
            }

            return rootBlob.GetSharedAccessSignature(policy);
        }
    }
}


text:
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.

package com.azure.resourcemanager.storage.models;

import com.azure.core.util.ExpandableStringEnum;
import com.fasterxml.jackson.annotation.JsonCreator;
import java.util.Collection;

/** Default share permission for users using Kerberos authentication if RBAC role is not assigned. */
public final class DefaultSharePermission extends ExpandableStringEnum<DefaultSharePermission> {
    /** Static value None for DefaultSharePermission. */
    public static final DefaultSharePermission NONE = fromString("None");

    /** Static value StorageFileDataSmbShareReader for DefaultSharePermission. */
    public static final DefaultSharePermission STORAGE_FILE_DATA_SMB_SHARE_READER =
        fromString("StorageFileDataSmbShareReader");

    /** Static value StorageFileDataSmbShareContributor for DefaultSharePermission. */
    public static final DefaultSharePermission STORAGE_FILE_DATA_SMB_SHARE_CONTRIBUTOR =
        fromString("StorageFileDataSmbShareContributor");

    /** Static value StorageFileDataSmbShareElevatedContributor for DefaultSharePermission. */
    public static final DefaultSharePermission STORAGE_FILE_DATA_SMB_SHARE_ELEVATED_CONTRIBUTOR =
        fromString("StorageFileDataSmbShareElevatedContributor");

    /**
     * Creates or finds a DefaultSharePermission from its string representation.
     *
     * @param name a name to look for.
     * @return the corresponding DefaultSharePermission.
     */
    @JsonCreator
    public static DefaultSharePermission fromString(String name) {
        return fromString(name, DefaultSharePermission.class);
    }

    /**
     * Gets known DefaultSharePermission values.
     *
     * @return known DefaultSharePermission values.
     */
    public static Collection<DefaultSharePermission> values() {
        return values(DefaultSharePermission.class);
    }
}


text:
layout: post
microblog: true
date: 2017-05-13 00:31 +0300
guid: http://desparoz.micro.blog/2017/05/12/agree-with-gruber.html
---
Agree with @gruber 5/5. 🔗 Daring Fireball: Dropping Tech Giants — [daringfireball.net/2017/05/d...](https://daringfireball.net/2017/05/dropping_tech_giants)


text:
import logging
import re

from cattle.plugins.docker.util import add_to_env, add_label, \
    is_nonrancher_container
from cattle.utils import get_or_create_map, get_or_create_list

log = logging.getLogger('docker')

def setup_network_mode(instance, compute, client, create_config, start_config):
    """
    Based on the network configuration we choose the network mode to set in
    Docker.  We only really look for none, host, or container.  For all
    all other configurations we assume bridge mode
    """
    try:
        kind = instance.nics[0].network.kind
        if kind == 'dockerHost':
            start_config['network_mode'] = 'host'
            del start_config['links']
        elif kind == 'dockerNone':
            create_config['network_disabled'] = True
            del start_config['links']
        elif kind == 'dockerContainer':
            id = instance.networkContainer.uuid
            other = compute.get_container(client, instance.networkContainer)
            if other is not None:
                id = other['Id']
            start_config['network_mode'] = 'container:{}'.format(id)
            del start_config['links']
    except (KeyError, AttributeError, IndexError):
        pass

def setup_mac_and_ip(instance, create_config):
    """
    Configures the mac address and primary ip address for the the supplied
    container. The mac_address is configured directly as part of the native
    docker API. The primary IP address is set as an environment variable on the
    container. Another Rancher micro-service will detect this environment
    variable when the container is started and inject the IP into the
    container.

    Note: while an instance can technically have more than one nic based on the
    resource schema, this implementation assumes a single nic for the purpose
    of configuring the mac address and IP.
    """
    mac_address = None
    device_number = None
    for nic in instance.nics:
        if device_number is None:
            mac_address = nic.macAddress
            device_number = nic.deviceNumber
        elif device_number > nic.deviceNumber:
            mac_address = nic.macAddress
            device_number = nic.deviceNumber
    create_config["mac_address"] = mac_address

    try:
        if instance.nics and instance.nics[0].ipAddresses:
            # Assume one nic
            nic = instance.nics[0]
            ip_address = None
            for ip in nic.ipAddresses:
                if ip.role == 'primary':
                    ip_address = '{0}/{1}'.format(ip.address,
                                                  ip.subnet.cidrSize)
                    break

            if ip_address:
                add_label(create_config,
                          {'io.rancher.container.ip': ip_address})
    except (KeyError, AttributeError):
        pass

def setup_ports(instance, create_config, start_config):
    """
    Sets up a container's config for rancher-managed ports by removing the
    native docker port configuration. We do this because rancher emulates ports
    outside of Docker's direct purview to allow for multi-host networking.

    Note that a non-rancher container (one created and started outside the
    rancher API) will not have its port configuration manipulated. This is
    because on a container restart, we would not be able to properly rebuild
    the port config because it depends on manipulating the create_config.
    """
    if not _has_service(instance, 'portService') or is_nonrancher_container(
            instance):
        return

    if 'ports' in create_config:
        del create_config['ports']

    start_config['publish_all_ports'] = False

def setup_links(instance, create_config, start_config):
    """
    Sets up a container's config for rancher-managed links by removing the
    docker native link configuration and emulating links through environment
    variables.

    Note that a non-rancher container (one created and started outside the
    rancher API) container will not have its link configuration manipulated.
    This is because on a container restart, we would not be able to properly
    rebuild the link configuration because it depends on manipulating the
    create_config.
    """
    if not _has_service(instance, 'linkService') or is_nonrancher_container(
            instance):
        return

    if 'links' in start_config:
        del start_config['links']

    result = {}
    for link in instance.instanceLinks:
        link_name = link.linkName
        _add_link_env(link_name, link, result)
        _copy_link_env(link_name, link, result)

        try:
            for name in link.data.fields.instanceNames:
                _add_link_env(name, link, result, in_ip=link_name)
                _copy_link_env(name, link, result)

                # This does assume the format {env}_{name}
                parts = name.split('_', 1)
                if len(parts) == 1:
                    continue

                _add_link_env(parts[1], link, result, in_ip=link_name)
                _copy_link_env(parts[1], link, result)
        except AttributeError:
            pass

    if len(result) > 0:
        add_to_env(create_config, **result)

def _copy_link_env(name, link, result):
    try:
        targetInstance = link.targetInstance
        if targetInstance.data.dockerInspect.Config.Env is None:
            return

        ignores = set()

        for env in targetInstance.data.dockerInspect.Config.Env:
            parts = env.split('=', 1)
            if len(parts) == 1:
                continue

            if parts[1].startswith('/cattle/'):
                env_name = to_env_name(parts[1][len('/cattle/'):])
                ignores.add(env_name + '_NAME')
                ignores.add(env_name + '_PORT')
                ignores.add(env_name + '_ENV')

        for env in targetInstance.data.dockerInspect.Config.Env:
            should_ignore = False
            for ignore in ignores:
                if env.startswith(ignore):
                    should_ignore = True
                    break

            if should_ignore:
                continue

            parts = env.split('=', 1)
            if len(parts) == 1:
                continue
            key, value = parts[0], parts[1]
            if key in ['HOME', 'PATH']:
                continue

            result['{}_ENV_{}'.format(to_env_name(name), key)] = value
    except AttributeError:
        pass

def to_env_name(name):
    return re.sub(r'[^a-zA-Z0-9_]', '_', name).upper()

def _add_link_env(name, link, result, in_ip=None):
    try:
        result['{0}_NAME'.format(to_env_name(name)).upper()] =\
            '/cattle/{0}'.format(name)

        if link.data.fields.ports is None:
            return

        for link_port in link.data.fields.ports:
            proto = link_port.protocol
            ip = name.lower()
            if in_ip is not None:
                ip = in_ip
            dst = link_port.privatePort
            port = link_port.privatePort

            full_port = '{0}://{1}:{2}'.format(proto, ip, dst)

            data = {
                'NAME': '/cattle/{0}'.format(name),
                'PORT': full_port,
                'PORT_{0}_{1}'.format(port, proto): full_port,
                'PORT_{0}_{1}_ADDR'.format(port, proto): ip,
                'PORT_{0}_{1}_PORT'.format(port, proto): dst,
                'PORT_{0}_{1}_PROTO'.format(port, proto): proto,
            }

            for k, v in data.items():
                result['{0}_{1}'.format(to_env_name(name), k).upper()] = v
    except AttributeError:
        pass

def setup_ipsec(instance, host, create_config, start_config):
    """
    If the supplied instance is a network agent, configures the ports needed
    to achieve multi-host networking.
    """
    if instance.get('agentId') is None:
        network_agent = False
    elif instance.get('systemContainer') is None or \
            instance.get('systemContainer') == 'NetworkAgent':
        network_agent = True
    else:
        network_agent = False

    if not network_agent or \
            not _has_service(instance, 'ipsecTunnelService'):
        return

    try:
        host_id = str(host.id)
        nat = instance.data.ipsec[host_id]['nat']
        isakmp = instance.data.ipsec[host_id]['isakmp']

        ports = get_or_create_list(create_config, 'ports')
        binding = get_or_create_map(start_config, 'port_bindings')

        ports.append((500, 'udp'))
        ports.append((4500, 'udp'))
        binding['500/udp'] = ('0.0.0.0', isakmp)
        binding['4500/udp'] = ('0.0.0.0', nat)
    except (KeyError, AttributeError):
        pass

def _has_service(instance, kind):
    try:
        for nic in instance.nics:
            if nic.deviceNumber != 0:
                continue

            for service in nic.network.networkServices:
                if service.kind == kind:
                    return True
    except (KeyError, AttributeError):
        pass

    return False


text:
import {parseTemplate} from '@angular/compiler';
import {Node} from '@angular/compiler/src/render3/r3_ast';

/**
 * Parses the given HTML content using the Angular compiler. In case the parsing
 * fails, null is being returned.
 */
export function parseHtmlGracefully(htmlContent: string, filePath: string): Node[]|null {
  try {
    return parseTemplate(htmlContent, filePath).nodes;
  } catch {
    // Do nothing if the template couldn't be parsed. We don't want to throw any
    // exception if a template is syntactically not valid. e.g. template could be
    // using preprocessor syntax.
    return null;
  }
}


text:
<?xml version="1.0" encoding="utf-8" ?>
<pluggable type="plugin">
	<name>Route 301</name>
	<license url="http://www.apache.org/licenses/LICENSE-2.0.html">Apache Software License 2.0</license>
	<author url="http://habariproject.org/">Habari Community</author>
	<version>0.6.6</version>
	<url>http://habariproject.org/</url>
	<description><![CDATA[Assign user-defined rules to existing or custom rules.]]></description>
	<copyright>2007</copyright>
</pluggable>


text:
// @flow
import React, { useState } from 'react'
import { makeStyles, withStyles } from '@material-ui/core/styles'
import Button from '@material-ui/core/Button'
import Dialog from '@material-ui/core/Dialog'
import TextField from './TextField'
import IconButton from '@material-ui/core/IconButton'
import CloseIcon from '@material-ui/icons/Close'
import Collapse from '@material-ui/core/Collapse'
import ExpandMoreIcon from '@material-ui/icons/ExpandMore'
import Fade from '@material-ui/core/Fade'
import DateFnsUtils from '@date-io/date-fns'
import enLocale from 'date-fns/locale/en-US'
import frLocale from 'date-fns/locale/fr'
import ptLocale from 'date-fns/locale/pt-BR'
import esLocale from 'date-fns/locale/es'
import { MuiPickersUtilsProvider } from '@material-ui/pickers'
import MuiAccordion from '@material-ui/core/Accordion'
import MuiAccordionSummary from '@material-ui/core/AccordionSummary'
import MuiAccordionDetails from '@material-ui/core/AccordionDetails'
import DialogActions from '@material-ui/core/DialogActions'
import MuiDialogContent from '@material-ui/core/DialogContent'
import DialogContentText from '@material-ui/core/DialogContentText'
import DialogTitle from '@material-ui/core/DialogTitle'
import MenuIcon from '@material-ui/icons/MoreVert'
import Menu from '@material-ui/core/Menu'
import MenuItem from '@material-ui/core/MenuItem'

import Typography from '@material-ui/core/Typography'
import { useIntl, FormattedMessage, defineMessages } from 'react-intl'
import clone from 'clone-deep'

import FeatureHeader from '../internal/FeatureHeader'
import MediaCarousel from './MediaCarousel'
import { defaultGetPreset } from '../utils/helpers'
import { get, set } from '../utils/get_set'
import Field from './Field'
import type { Observation } from 'mapeo-schema'
import type {
  PresetWithAdditionalFields,
  GetMedia,
  Attachment,
  Key
} from '../types'

const m = defineMessages({
  confirmCloseTitle: 'Close without saving changes?',
  confirmCloseDescription:
    'You have made some changes, closing without saving will loose the changes you make',
  confirmCloseButtonConfirm: 'Discard changes',
  confirmCloseButtonCancel: 'Cancel',
  confirmDeleteTitle: 'Delete observation?',
  confirmDeleteButtonConfirm: 'Yes, delete',
  confirmDeleteButtonCancel: 'Cancel',
  // Header for section that includes the additional details for an observation
  detailsHeader: 'Details',
  // Header for section with additional fields that are not defined in the preset
  additionalHeader: 'Additional data',
  // Cancel button once observation has been edited
  cancelEditButton: 'Cancel',
  // Save edit button
  saveEditButton: 'Save',
  // Menu item to delete an observation
  deleteObservationMenuItem: 'Delete observation'
})

export type ImageMediaItem = {
  src: string,
  type: 'image'
}

type Props = {
  open?: boolean,
  onRequestClose: () => void,
  onDelete: (id: string) => void,
  observation: Observation,
  // The initial image to show in the media carousel
  initialImageIndex?: number,
  onSave: (observation: Observation) => void,
  getPreset?: Observation => PresetWithAdditionalFields | void,
  /**
   * For a given attachment, return `src` and `type`
   */
  getMedia: GetMedia
}

const localeMap = {
  en: enLocale,
  fr: frLocale,
  pt: ptLocale,
  es: esLocale
}

function getLocaleData (locale) {
  if (!locale) return localeMap.en
  return localeMap[locale] || localeMap[locale.split('-')[0]] || localeMap.en
}

function defaultGetMedia ({ type, id }: Attachment) {
  if (type && type.split('/')[0] !== 'image') return
  return {
    type: 'image',
    src: id
  }
}

const ConfirmCloseDialog = ({ open, onCancel, onConfirm }) => (
  <Dialog
    disableBackdropClick
    open={open}
    onClose={onCancel}
    aria-labelledby='close-dialog-title'
    aria-describedby='close-dialog-description'
  >
    <DialogTitle id='close-dialog-title'>
      <FormattedMessage {...m.confirmCloseTitle} />
    </DialogTitle>
    <MuiDialogContent>
      <DialogContentText id='close-dialog-description'>
        <FormattedMessage {...m.confirmCloseDescription} />
      </DialogContentText>
    </MuiDialogContent>
    <DialogActions>
      <Button onClick={onCancel} color='primary'>
        <FormattedMessage {...m.confirmCloseButtonCancel} />
      </Button>
      <Button onClick={onConfirm} color='primary' autoFocus>
        <FormattedMessage {...m.confirmCloseButtonConfirm} />
      </Button>
    </DialogActions>
  </Dialog>
)

const ConfirmDeleteDialog = ({ open, onCancel, onConfirm }) => (
  <Dialog
    disableBackdropClick
    open={open}
    onClose={onCancel}
    aria-labelledby='delete-dialog-title'
  >
    <DialogTitle id='delete-dialog-title'>
      <FormattedMessage {...m.confirmDeleteTitle} />
    </DialogTitle>
    <DialogActions>
      <Button onClick={onCancel} color='primary'>
        <FormattedMessage {...m.confirmDeleteButtonCancel} />
      </Button>
      <Button onClick={onConfirm} color='primary' autoFocus>
        <FormattedMessage {...m.confirmDeleteButtonConfirm} />
      </Button>
    </DialogActions>
  </Dialog>
)

const Accordion = withStyles({
  root: {
    border: '1px solid rgba(0, 0, 0, .125)',
    boxShadow: 'none',
    '&:before': {
      display: 'none'
    },
    '&$expanded': {
      margin: 'auto'
    }
  },
  expanded: {}
})(MuiAccordion)

const AccordionSummary = withStyles({
  root: {
    '&$expanded': {
      minHeight: 48
    }
  },
  content: {
    '&$expanded': {
      margin: '12px 0'
    }
  },
  expanded: {}
})(MuiAccordionSummary)

const AccordionDetails = withStyles({
  root: {
    display: 'flex',
    flexDirection: 'column',
    flexWrap: 'wrap',
    padding: '0 21px 10px 21px',
    '& > div:first-child': {
      marginTop: 10
    }
  }
})(MuiAccordionDetails)

const ObservationActions = ({ onDeleteClick }) => {
  const [anchorEl, setAnchorEl] = React.useState(null)
  const [confirm, setConfirm] = useState(null)

  const handleOpenClick = event => {
    setAnchorEl(event.currentTarget)
  }

  const handleClose = () => {
    setAnchorEl(null)
  }

  const createHandleItemClick = (action: () => any = () => {}) => () => {
    // Can't setState to a function
    setConfirm(state => didConfirm => {
      setConfirm(null)
      if (didConfirm) action()
      handleClose()
    })
  }

  return (
    <>
      <IconButton
        aria-controls='simple-menu'
        aria-haspopup='true'
        onClick={handleOpenClick}
      >
        <MenuIcon />
      </IconButton>
      <Menu
        id='simple-menu'
        anchorEl={anchorEl}
        keepMounted
        open={Boolean(anchorEl)}
        onClose={handleClose}
      >
        <MenuItem onClick={createHandleItemClick(onDeleteClick)}>
          <FormattedMessage {...m.deleteObservationMenuItem} />
        </MenuItem>
      </Menu>
      <ConfirmDeleteDialog
        open={!!confirm}
        onConfirm={() => confirm && confirm(true)}
        onCancel={() => confirm && confirm(false)}
      />
    </>
  )
}

const DialogContent = ({
  open = false,
  onRequestClose,
  onSave,
  onDelete,
  observation,
  initialImageIndex,
  getPreset = defaultGetPreset,
  getMedia = defaultGetMedia
}: {
  ...$Exact<Props>,
  onRequestClose: (shouldConfirm: boolean) => void
}) => {
  const cx = useStyles()
  const [values, setValues] = useState(
    observation.tags ? clone(observation.tags) : {}
  )
  const [dirty, setDirty] = useState(false)
  const { locale } = useIntl()

  const handleSave = () => {
    onSave(set(observation, 'tags', values))
    onRequestClose(false)
  }

  const handleRequestClose = () => {
    // Ask for confirmation if form is dirty
    onRequestClose(dirty)
  }

  const handleDeleteClick = () => {
    onRequestClose(false)
    onDelete(observation.id)
  }

  const handleChange = (key: Key, newValue: any) => {
    setDirty(true)
    setValues(set(values, key, newValue))
  }

  const preset = getPreset(observation) || {}
  const coords =
    observation.lat != null && observation.lon != null
      ? {
          latitude: observation.lat,
          longitude: observation.lon
        }
      : undefined

  const descriptionKey = values.note ? 'note' : 'notes'

  const mediaItems: ImageMediaItem[] = (observation.attachments || []).reduce(
    (acc, cur) => {
      const item = getMedia(cur, { width: 800, height: 600 })
      // $FlowFixMe - need to fix type refinement here
      if (item && item.type === 'image') acc.push(item)
      return acc
    },
    []
  )

  return (
    <MuiPickersUtilsProvider
      utils={DateFnsUtils}
      locale={getLocaleData(locale)}
    >
      <>
        <IconButton
          className={cx.closeButton}
          color='inherit'
          onClick={handleRequestClose}
          aria-label='Close'
        >
          <CloseIcon />
        </IconButton>
        {mediaItems.length > 0 && (
          <div className={cx.mediaWrapper}>
            <MediaCarousel
              items={mediaItems}
              initialIndex={initialImageIndex}
              className={cx.media}
            />
          </div>
        )}
        <FeatureHeader
          icon={preset.icon}
          name={preset.name}
          coords={coords}
          createdAt={new Date(observation.created_at)}
          action={<ObservationActions onDeleteClick={handleDeleteClick} />}
        />
        <TextField
          value={values[descriptionKey]}
          onChange={newValue => handleChange(descriptionKey, newValue)}
          multiline
          margin='dense'
          label='Description'
          className={cx.descriptionField}
        />
        {preset.fields.length > 0 && (
          <Accordion TransitionProps={{ unmountOnExit: true }}>
            <AccordionSummary
              expandIcon={<ExpandMoreIcon />}
              aria-controls='panel1a-content'
              id='panel1a-header'
            >
              <Typography component='h2' className={cx.sectionHeading}>
                <FormattedMessage {...m.detailsHeader} />
              </Typography>
            </AccordionSummary>
            <AccordionDetails>
              {preset.fields.map(field => (
                <Field
                  key={field.id}
                  field={field}
                  value={get(values, field.key)}
                  onChange={handleChange}
                />
              ))}
            </AccordionDetails>
          </Accordion>
        )}
        {Array.isArray(preset.additionalFields) &&
          preset.additionalFields.length > 0 && (
            <Accordion>
              <AccordionSummary
                expandIcon={<ExpandMoreIcon />}
                aria-controls='panel1a-content'
                id='panel1a-header'
              >
                <Typography component='h2' className={cx.sectionHeading}>
                  <FormattedMessage {...m.additionalHeader} />
                </Typography>
              </AccordionSummary>
              <AccordionDetails>
                {preset.additionalFields.map(field => (
                  <Field
                    key={field.id}
                    field={field}
                    value={get(values, field.key)}
                    onChange={handleChange}
                  />
                ))}
              </AccordionDetails>
            </Accordion>
          )}
        <Fade in={dirty}>
          <Collapse in={dirty} className={cx.actions}>
            <Button
              color='default'
              variant='contained'
              className={cx.button}
              onClick={handleRequestClose}
            >
              <FormattedMessage {...m.cancelEditButton} />
            </Button>
            <Button
              color='primary'
              variant='contained'
              className={cx.button}
              onClick={handleSave}
            >
              <FormattedMessage {...m.saveEditButton} />
            </Button>
          </Collapse>
        </Fade>
      </>
    </MuiPickersUtilsProvider>
  )
}

const ObservationDialog = ({ open, onRequestClose, ...otherProps }: Props) => {
  const [confirm, setConfirm] = useState(null)

  const handleRequestClose = shouldConfirm => {
    if (!shouldConfirm) {
      setConfirm(null)
      onRequestClose()
      return
    }
    setConfirm(state => didConfirm => {
      setConfirm(null)
      if (didConfirm) onRequestClose()
    })
  }
  return (
    <>
      <Dialog
        disableBackdropClick
        open={open}
        onClose={handleRequestClose}
        scroll='body'
        fullWidth
        maxWidth='sm'
      >
        {open && (
          <DialogContent {...otherProps} onRequestClose={handleRequestClose} />
        )}
      </Dialog>
      <ConfirmCloseDialog
        open={!!confirm}
        onConfirm={() => confirm && confirm(true)}
        onCancel={() => confirm && confirm(false)}
      />
    </>
  )
}

export default ObservationDialog

const useStyles = makeStyles(theme => ({
  closeButton: {
    position: 'absolute',
    zIndex: 999,
    left: 0,
    top: 0,
    color: 'white',
    backgroundColor: 'rgba(0,0,0,0.4)',
    borderRadius: '0 0 4px 0',
    '&:hover': {
      backgroundColor: 'rgba(0,0,0,0.5)'
    }
  },
  descriptionField: {
    boxSizing: 'border-box',
    margin: '0 10px 13.5px 10px',
    width: 'calc(100% - 20px)',
    '& .MuiInputBase-inputMultiline': theme.typography.body1,
    '& .MuiInputLabel-root': {
      opacity: 0,
      transition: 'opacity 200ms cubic-bezier(0.0, 0, 0.2, 1)'
    },
    '&:hover .MuiInputLabel-root, & .MuiInputLabel-root.Mui-focused': {
      opacity: 1
    },
    '& .MuiOutlinedInput-notchedOutline': {
      borderColor: 'rgba(0,0,0,0)'
    }
  },
  sectionHeading: {
    fontWeight: 500
  },
  mediaWrapper: {
    width: '100%',
    paddingTop: '75%',
    position: 'relative',
    height: 0
  },
  media: {
    position: 'absolute',
    top: 0,
    left: 0,
    width: '100%',
    height: '100%'
  },
  details: {
    flexDirection: 'column',
    flex: 1,
    minWidth: 320,
    flexBasis: '33%',
    backgroundColor: 'white',
    overflowY: 'scroll'
  },
  actions: {
    margin: '0 10px',
    textAlign: 'right'
  },
  button: {
    marginLeft: theme.spacing(1),
    marginTop: 14,
    marginBottom: 14
  }
}))