text:
**Geotrek**, *paths* management for *National Parks* and *Tourism organizations*.

.. image:: http://geotrek.fr/images/logo-128.png

:master: |master-status| |master-coverage|
:develop: |develop-status|

.. |master-status| image::
    https://api.travis-ci.org/makinacorpus/Geotrek.png?branch=master
    :alt: Build Status
    :target: https://travis-ci.org/makinacorpus/Geotrek

.. |master-coverage| image::
    https://coveralls.io/repos/makinacorpus/Geotrek/badge.png?branch=master
    :alt: Coverage
    :target: https://coveralls.io/r/makinacorpus/Geotrek

.. |develop-status| image::
    https://api.travis-ci.org/makinacorpus/Geotrek.png?branch=develop
    :alt: Build Status
    :target: https://travis-ci.org/makinacorpus/Geotrek

In brief
--------

* Manage paths, treks and POIs
* Track maintenance of equipments and infrastructures
* Control objets by district, protected areas, physical and legal status of paths
* Compute 3D attributes using DEM draping
* Publish a public website (e.g. `PNE <http://rando.ecrins-parcnational.fr>`_, `PNM-PNAM <http://rando.mercantour.eu>`_)

.. image:: http://geotrek.fr/images/capture-3.jpg

.. image:: http://geotrek.fr/images/geotrek_rando.png

.. image:: http://geotrek.fr/images/capture-webgl.jpg

More information on product website http://geotrek.fr

Documentation
-------------

* More info at http://geotrek.fr (*french*)
* `Installation and configuration instructions <http://geotrek.readthedocs.org>`_
* Help us translate `on Transifex <https://www.transifex.com/organization/makina-corpus>`_

License
-------

    * OpenSource - BSD
    * Copyright (c) 2012-2014 - Parc National des Écrins - Parc National du Mercantour - Parco delle Alpi Marittime - Makina Corpus

.. image:: http://geotrek.fr/images/logo-pne.png
    :target: http://www.ecrins-parcnational.fr

.. image:: http://geotrek.fr/images/logo-pnm.png
    :target: http://www.mercantour.eu

.. image:: http://geotrek.fr/images/logo-pnam.png
    :target: http://www.parcoalpimarittime.it

.. image:: http://geotrek.fr/images/logo-pnrgc.png
    :target: http://www.parc-grands-causses.fr

.. image:: http://geotrek.fr/images/logo-guillestrois.png
    :target: http://www.guillestrois.com

.. image:: http://depot.makina-corpus.org/public/logo.gif
    :target: http://www.makina-corpus.com

redpajama_set_name: RedPajamaGithub


text:
layout: post
title: "CSS Color units"
subtitle: "Different ways to define colors"
section: css
---

**Colors** are widely used in CSS, whether for text color, background color, gradients, shadows, borders... There are several ways to define colors in CSS, each with their own pros and cons.

The `color` property defines the color of the **text**. It is pretty straightforward. What is more important is the different types of **color units** available.

### Color names

CSS provides [145 colors names](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value), from the most basic (black, white, orange, yellow, blue...) to the more specific (lawngreen, orchid, crimson...).

{% highlight css %}
body{ color: black;}
a{ color: orange;}
{% endhighlight %}

Because the color names are hard to remember, and because you probably want very specific colors, color names are not often used.

### rgb

Computer monitors, TVs, mobile phones, all use the RGB color model to display colors. Basically, each color is defined by a combination of Red, Green, and Blue. There are 256 possible values for Red, Green or Blue. Because computers start counting at 0 (zero), the maximum value is 255.

Considering a color is the result of a _combination_ of Red, Green and Blue, and because each of these 3 colors have 256 possible values, there are `256 * 256 * 256 = 16,777,216` possible colors available.

Because the RGB model is directly related to how colors are _physically_ rendered, it has become a CSS color unit.

For example, the red color of this website is 219 amounts of Red, 78 of Green, and 68 of Blue:

{% highlight css %}
a{ color: rgb(219, 78, 68);}
{% endhighlight %}

The black color is no amount of either Red, Green or Blue:

{% highlight css %}
body{ color: rgb(0, 0, 0);}
{% endhighlight %}

On the other side of the spectrum, white is the full amount of each Red, Green and Blue:

{% highlight css %}
body{ color: rgb(255, 255, 255);}
{% endhighlight %}

### rgba

The `rgba` color unit is `rgb` to which we add an **alpha** value (ranging from 0 to 1, in decimal values), which defines how transparent the color is:

{% highlight css %}
body{ color: rgba(0, 0, 0, 0.8);}
{% endhighlight %}

A slightly transparent black color.
{: .info}

The purpose of a color being transparent is to blend with the background, and consequently look slightly different depending on the context. It is particularly useful for **background colors**.

### hsl and hsla

**HSL** is another way to define a color. Think of it as a **color wheel**.

Source: Wikipedia

Instead of a color being a combination of Red, Green and Blue, you define:

* the **Hue** a value ranging from 0 to 360, defines _which color_ you want.
* the **Saturation** percentage, ranging from 0% to 100%, defines _how much_ of that color you want.
* the **Lightness** percentage, ranging from 0% to 100%, defines _how bright_ you want that color to be.

Again, the red color of this website is defined this way in HSL:

{% highlight css %}
a{ color: hsl(4, 68%, 56%);}
{% endhighlight %}

`4` indicates it's red
`68%` indicates the red is quite prominent
`56%` indicates it's halfway between black and white

The `hsl` color unit is easier to understand than `rgb` because the expected result is clearer. You basically define a color in 3 separate steps, and can play around with each value to come up with the color you want. If you want a yellow shade, you can start with a value like `hsl(50, 68%, 56%)`, and alter the Saturation and Lightness value to find the specific shade you're looking for.

I consider `hsl` to be **human-readable**, whereas `rgb` is more **computer-readable**.

`hsla` is the same as `hsl`, with the added value of being able to define an **alpha** value:

{% highlight css %}
body{ color: hsla(4, 68%, 56%, 0.5);}
{% endhighlight %}

A transparent red color.
{: .info}

### Hexadecimal

Colors in CSS can also be defined with **hexadecimal values**, like `#db4e44`.

To understand what hexadecimal values are, let's look at how binary and decimal work:

        binary
        2 possible values

      0
      1

        decimal
        10 possible values

      0
      1
      2
      3
      4
      5
      6
      7
      8
      9

        hexadecimal
        16 possible values

      0
      1
      2
      3
      4
      5
      6
      7
      8
      9
      A
      B
      C
      D
      E
      F

Consider the 0-9 numbers and the A-F letters as **symbols**.

Humans use the **decimal** system. We have 10 symbols to form numbers.

In **hexadecimal**, we have 16 symbols to form numbers. Because 0-9 are not enough symbols, we also use A-F. And it starts at zero. So:

* the number `4` in hexadecimal is `4`
* the number `12` in hexadecimal is `C`
* the number `16` in hexadecimal is `10` because after you've run out of symbols (the last one being `F`), you add a second symbol to the left and increment (`0` becomes `1`) and the right one starts over (from `F` to `0`)

#### Do I have to remember this?

Not at all! It is here to provide an explanation of how hexadecimal values work. The most important thing to remember is that there are 16 hexadecimal symbols.

Just like RGB, a hexadecimal color value is a combination of Red, Green, and Blue, each of them being represent as a hexadecimal value, like `DB` for Red, `4E` for Green, and `44` for Blue.

Because Red, Green or Blue can only have 2 symbols, their possible values are `16 * 16 = 256`, which mirrors the RGB color unit!

#### Why not use RGB then?

Usually, when choosing colors, you **don't write** them directly. You either use a color picker, or copy/paste it from Photoshop, or choose a [colour palette](https://www.colourlovers.com/palettes) somewhere.

Hexadecimal values are easier to **copy and paste**, as they only comprise 6 characters.

![Photoshop one field for hex](/images/photoshop-color-picker.png)

#### It is easier to copy paste a single field than 3 separate ones.

In CSS, you only need to prepend a hexadecimal color value with a hash `#`.

### Which one to pick?

If you don't intend to use any transparent color, stick to **hexadecimal** values, as they are easier to copy/paste and don't take much space in your code.

If you want some transparency, convert your color from hex to rgba, and use the `rgba` color unit.

If you want to play around with your color directly in the browser, try `hsl`.


text:
package s3

import (
	"context"
	"fmt"
	"io/ioutil"
	"os"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3"
	"github.com/aws/aws-sdk-go/service/s3/s3manager"
	"github.com/aws/aws-sdk-go/service/s3/s3manager/s3manageriface"
	"github.com/mholt/archiver/v3"

	"github.com/dollarshaveclub/furan/v2/pkg/datalayer"
	"github.com/dollarshaveclub/furan/v2/pkg/models"
)

type CacheManager struct {
	AccessKeyID, SecretAccessKey string // AWS credentials scoped to S3 only
	Region, Bucket, Keypfx       string
	DL                           datalayer.DataLayer
	S3UploaderFactoryFunc        func(s *session.Session) s3manageriface.UploaderAPI
	S3DownloaderFactoryFunc      func(s *session.Session) s3manageriface.DownloaderAPI
}

var _ models.CacheFetcher = &CacheManager{}

func (cm *CacheManager) dlclient() (s3manageriface.DownloaderAPI, error) {
	sess, err := session.NewSession(&aws.Config{
		Region:      &cm.Region,
		Credentials: credentials.NewStaticCredentials(cm.AccessKeyID, cm.SecretAccessKey, ""),
	})
	if err != nil {
		return nil, fmt.Errorf("error getting aws session: %v", err)
	}
	if cm.S3DownloaderFactoryFunc == nil {
		cm.S3DownloaderFactoryFunc = func(sess *session.Session) s3manageriface.DownloaderAPI {
			return s3manager.NewDownloader(sess)
		}
	}
	return cm.S3DownloaderFactoryFunc(sess), nil
}

func (cm *CacheManager) ulclient() (s3manageriface.UploaderAPI, error) {
	sess, err := session.NewSession(&aws.Config{
		Region:      &cm.Region,
		Credentials: credentials.NewStaticCredentials(cm.AccessKeyID, cm.SecretAccessKey, ""),
	})
	if err != nil {
		return nil, fmt.Errorf("error getting aws session: %v", err)
	}
	if cm.S3UploaderFactoryFunc == nil {
		cm.S3UploaderFactoryFunc = func(sess *session.Session) s3manageriface.UploaderAPI {
			return s3manager.NewUploader(sess)
		}
	}
	return cm.S3UploaderFactoryFunc(sess), nil
}

func (cm *CacheManager) keyForBuild(b models.Build) string {
	// Example key: keyprefix/acmecorp/widgets_buildcache.tar.gz
	return cm.Keypfx + b.GitHubRepo + "_buildcache.tar.gz"
}

func awsError(err error) error {
	aerr, ok := err.(awserr.Error)
	if ok {
		// only return the short error message, not the full multiline details
		return fmt.Errorf(aerr.Code())
	}
	return err
}

// Fetch fetches the cache for a build from S3 and returns the temporary filesystem path where it can be found.
// Caller is responsible for cleaning the path up when finished with the data.
func (cm *CacheManager) Fetch(ctx context.Context, b models.Build) (string, error) {
	dlc, err := cm.dlclient()
	if err != nil {
		return "", fmt.Errorf("error getting S3 downloader: %w", err)
	}
	f, err := ioutil.TempFile("", "s3-cache-fetch-*.tar.gz")
	if err != nil {
		return "", fmt.Errorf("error creating temp file: %w", err)
	}
	defer os.Remove(f.Name())
	defer f.Close()
	key := cm.keyForBuild(b)
	cm.DL.AddEvent(ctx, b.ID, fmt.Sprintf("downloading cache: s3://%v/%v", cm.Bucket, key))
	start := time.Now().UTC()
	n, err := dlc.DownloadWithContext(ctx, f, &s3.GetObjectInput{
		Bucket: &cm.Bucket,
		Key:    &key,
	})
	if err != nil {
		// only return the short error since this is probably going into a build event
		return "", fmt.Errorf("error downloading cache from S3: %w", awsError(err))
	}
	cm.DL.AddEvent(ctx, b.ID, fmt.Sprintf("successfully downloaded cache from S3 (size %v bytes; elapsed: %v)", n, time.Since(start)))
	start = time.Now().UTC()
	dir, err := ioutil.TempDir("", "build-cache-*")
	if err != nil {
		return "", fmt.Errorf("error getting temp dir: %w", err)
	}
	if err := archiver.Unarchive(f.Name(), dir); err != nil {
		os.RemoveAll(dir)
		return "", fmt.Errorf("error unarchiving build cache: %w", err)
	}
	cm.DL.AddEvent(ctx, b.ID, fmt.Sprintf("successfully unarchived build cache (elapsed: %v)", time.Since(start)))
	return dir, nil
}

// Save persists the cache for a build located at path in S3.
// Caller is responsible for cleaning up the path after Save returns.
func (cm *CacheManager) Save(ctx context.Context, b models.Build, path string) error {
	ulc, err := cm.ulclient()
	if err != nil {
		return fmt.Errorf("error getting s3 uploader: %w", err)
	}
	f, err := ioutil.TempFile("", "s3-cache-save-*.tar.gz")
	if err != nil {
		return fmt.Errorf("error getting temp file: %w", err)
	}
	f.Close()
	defer os.Remove(f.Name())
	tgz := archiver.NewTarGz()
	tgz.OverwriteExisting = true
	cm.DL.AddEvent(ctx, b.ID, "archiving build cache snapshot")
	start := time.Now().UTC()
	if err := tgz.Archive([]string{path}, f.Name()); err != nil {
		return fmt.Errorf("error archiving build cache: %w", err)
	}
	cm.DL.AddEvent(ctx, b.ID, fmt.Sprintf("archived build cache (elapsed: %v)", time.Since(start)))
	f, err = os.Open(f.Name())
	if err != nil {
		return fmt.Errorf("error opening archive: %w", err)
	}
	var sz int64
	fi, err := f.Stat()
	if err == nil {
		sz = fi.Size()
	}
	defer f.Close()
	key := cm.keyForBuild(b)
	start = time.Now().UTC()
	cm.DL.AddEvent(ctx, b.ID, fmt.Sprintf("uploading cache: s3://%v/%v", cm.Bucket, key))
	if _, err := ulc.UploadWithContext(ctx, &s3manager.UploadInput{
		Body:   f,
		Bucket: &cm.Bucket,
		Key:    &key,
	}); err != nil {
		// only return the short error since this is probably going into a build event
		return fmt.Errorf("error uploading build cache: %w", awsError(err))
	}
	cm.DL.AddEvent(ctx, b.ID, fmt.Sprintf("successfully uploaded cache from S3 (size %v bytes; elapsed: %v)", sz, time.Since(start)))
	return nil
}


text:
<?php
use yii\widgets\Breadcrumbs;
use dmstr\widgets\Alert;

?>

        <?= Alert::widget() ?>
        <?= $content ?>

Copyright © <?= Yii::$app->name['name'] ?> 2016 - Version 2.0.3.0 - Theme by Almsaeed Studio

Recent Activity

Ranking

Chat of the game


text:
package meresti.linkviewer.core.entities;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import java.math.BigInteger;

@Document(collection = "ContentRoom")
public class ContentRoom {

    @Id
    private BigInteger id;

    private String name;

    public ContentRoom() {
    }

    public ContentRoom(final BigInteger id, final String name) {
        this.id = id;
        this.name = name;
    }

    public BigInteger getId() {
        return id;
    }

    public void setId(final BigInteger id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        this.name = name;
    }
}


text:
<?php

declare(strict_types=1);

namespace WebLoader;

use Nette\Neon\Neon;

class Compiler
{
    private const LOCK_FILE_NAME = 'webloader.lock';

    /**
     * @var bool
     */
    private $cacheEnabled = true;

    /**
     * @var string
     */
    private $documentRoot;

    /**
     * @var string|null
     */
    private $publicPathPrefix = null;

    /**
     * @var FilesCollection[][]
     */
    private $filesCollections = [
        Engine::CSS => [],
        Engine::JS => []
    ];

    /**
     * @var FilesCollectionsContainer[]
     */
    private $filesCollectionsContainers = [];

    /**
     * @var array
     */
    private $filters = [
        Engine::CSS => [],
        Engine::JS => []
    ];

    /**
     * @var string
     */
    private $outputDir;

    /**
     * @var string
     */
    private $pathPlaceholderDelimiter = '%';

    /**
     * @var array
     */
    private $pathsPlaceholders = [];

    /**
     * @var int
     */
    private $remoteFilesLoadingTimeout = 15;

    /**
     * @var string
     */
    private $version;

    public function addFilter(string $type, string $name, callable $filter, ?bool $forEachFile = null): Compiler
    {
        if ($this->filterExists($type, $name)) {
            throw new Exception(strtoupper($type) . ' filter "' . $name . '" already exists.');
        }

        $this->filters[$type][$name] = [
            'callback' => $filter,
            'forEachFile' => (bool) $forEachFile
        ];

        return $this;
    }

    public function addPathsPlaceholders(array $placeholders): Compiler
    {
        foreach ($placeholders as $placeholder => $path) {
            if ($this->pathPlaceholderExists($placeholder)) {
                throw new Exception('Placeholder "' . $placeholder . '" already exists.');
            }

            $this->pathsPlaceholders[$placeholder] = $path;
        }

        return $this;
    }

    public function compileAllFilesCollections(): void
    {
        foreach ($this->filesCollections as $filesCollectionsType => $filesCollections) {
            foreach ($filesCollections as $filesCollectionName => $filesCollection) {
                $this->compileSingleFilesCollection($filesCollection);
            }
        }
    }

    public function compileFilesCollectionByType(string $type, string $name): void
    {
        $collection = $this->getFilesCollection($type, $name);
        $this->compileSingleFilesCollection($collection);
    }

    public function createFilesCollection(string $type, string $name): FilesCollection
    {
        if ($this->filesCollectionExists($type, $name)) {
            throw new Exception(strtoupper($type) . ' files collection "' . $name . '" already exists.');
        }

        return $this->filesCollections[$type][$name] = new FilesCollection($name, $type);
    }

    public function createFilesCollectionsContainer(string $name): FilesCollectionsContainer
    {
        if ($this->filesCollectionsContainerExists($name)) {
            throw new Exception('Files collections container "' . $name . '" already exists.');
        }

        return $this->filesCollectionsContainers[$name] = new FilesCollectionsContainer();
    }

    public function createFilesCollectionsContainersFromArray(array $containers): Compiler
    {
        foreach ($containers as $containerName => $sections) {
            $containerName = (string) $containerName;
            $cssFilesCollections = null;
            $jsFilesCollections = null;

            foreach ($sections as $sectionName => $values) {
                if (!$values) {
                    continue;
                }

                if ($sectionName === FilesCollectionsContainer::CONFIG_SECTION_CSS_COLLECTIONS) {
                    $cssFilesCollections = $values;
                } elseif ($sectionName === FilesCollectionsContainer::CONFIG_SECTION_JS_COLLECTIONS) {
                    $jsFilesCollections = $values;
                } else {
                    throw new Exception(
                        'Unknown configuration section "' . $sectionName
                        . '" in files collections container "' . $containerName . '".'
                    );
                }
            }

            if (!$cssFilesCollections && !$jsFilesCollections) {
                continue;
            }

            $container = $this->createFilesCollectionsContainer($containerName);

            if ($cssFilesCollections) {
                $container->setCssCollections($cssFilesCollections);
            }

            if ($jsFilesCollections) {
                $container->setJsCollections($jsFilesCollections);
            }
        }

        return $this;
    }

    public function createFilesCollectionsContainersFromConfig(string $configPath): Compiler
    {
        $configPath = $this->replacePathsPlaceholders($configPath);

        if (!file_exists($configPath)) {
            throw new Exception('Files collections containers configuration file "' . $configPath . '" not found.');
        }

        $fileContent = file_get_contents($configPath);
        $containers = Neon::decode($fileContent);
        $this->createFilesCollectionsContainersFromArray($containers);

        return $this;
    }

    public function createFilesCollectionsFromArray(array $collections): Compiler
    {
        foreach ($collections as $collectionName => $sections) {
            $collectionName = (string) $collectionName;
            $cssContentLoadingEnabled = false;
            $cssFiles = [];
            $cssFilters = [];
            $cssOutputElementAttributes = [];
            $jsContentLoadingEnabled = false;
            $jsFiles = [];
            $jsFilters = [];
            $jsOutputElementAttributes = [];

            foreach ($sections as $sectionName => $values) {
                if (!$values) {
                    continue;
                }

                if ($sectionName === FilesCollection::CONFIG_SECTION_CSS_FILES) {
                    $cssFiles = $values;
                } elseif ($sectionName === FilesCollection::CONFIG_SECTION_CSS_FILTERS) {
                    $cssFilters = $values;
                } elseif ($sectionName === FilesCollection::CONFIG_SECTION_CSS_LOAD_CONTENT && $values === true) {
                    $cssContentLoadingEnabled = true;
                } elseif ($sectionName === FilesCollection::CONFIG_SECTION_CSS_OUTPUT_ELEMENT_ATTRIBUTES) {
                    $cssOutputElementAttributes = $values;
                } elseif ($sectionName === FilesCollection::CONFIG_SECTION_JS_FILES) {
                    $jsFiles = $values;
                } elseif ($sectionName === FilesCollection::CONFIG_SECTION_JS_FILTERS) {
                    $jsFilters = $values;
                } elseif ($sectionName === FilesCollection::CONFIG_SECTION_JS_LOAD_CONTENT && $values === true) {
                    $jsContentLoadingEnabled = true;
                } elseif ($sectionName === FilesCollection::CONFIG_SECTION_JS_OUTPUT_ELEMENT_ATTRIBUTES) {
                    $jsOutputElementAttributes = $values;
                } else {
                    throw new Exception(
                        'Unknown configuration section "'
                        . $sectionName . '" in files collection "' . $collectionName . '".'
                    );
                }
            }

            if ($cssFiles) {
                $cssCollection = $this->createFilesCollection(Engine::CSS, $collectionName)
                    ->setFiles($cssFiles)
                    ->setFilters($cssFilters)
                    ->setOutputElementAttributes($cssOutputElementAttributes);

                if ($cssContentLoadingEnabled) {
                    $cssCollection->enableContentLoading();
                }
            }

            if ($jsFiles) {
                $jsCollection = $this->createFilesCollection(Engine::JS, $collectionName)
                    ->setFiles($jsFiles)
                    ->setFilters($jsFilters)
                    ->setOutputElementAttributes($jsOutputElementAttributes);

                if ($jsContentLoadingEnabled) {
                    $jsCollection->enableContentLoading();
                }
            }
        }

        return $this;
    }

    public function createFilesCollectionsFromConfig(string $configPath): Compiler
    {
        $configPath = $this->replacePathsPlaceholders($configPath);

        if (!file_exists($configPath)) {
            throw new Exception('Files collections configuration file "' . $configPath . '" not found.');
        }

        $fileContent = file_get_contents($configPath);
        $collections = Neon::decode($fileContent);
        $this->createFilesCollectionsFromArray($collections);

        return $this;
    }

    public function disableCache(): Compiler
    {
        $this->cacheEnabled = false;
        return $this;
    }

    public function getDocumentRoot(): string
    {
        return $this->documentRoot;
    }

    public function getPublicPathPrefix(): ?string
    {
        return $this->publicPathPrefix;
    }

    public function getFilesCollection(string $type, string $name): FilesCollection
    {
        if (!$this->filesCollectionExists($type, $name)) {
            throw new Exception('Trying to get undefined ' . strtoupper($type) . ' files collection "' . $name . '".');
        }

        return $this->filesCollections[$type][$name];
    }

    public function getFilesCollectionsContainer(string $name): FilesCollectionsContainer
    {
        if (!$this->filesCollectionsContainerExists($name)) {
            throw new Exception('Trying to get undefined files collections container "' . $name . '".');
        }

        return $this->filesCollectionsContainers[$name];
    }

    public function getFilesCollections(): array
    {
        return $this->filesCollections;
    }

    public function getFilesCollectionsContainers(): array
    {
        return $this->filesCollectionsContainers;
    }

    public function getFilters(): array
    {
        return $this->filters;
    }

    public function getOutputDir(): string
    {
        return $this->outputDir;
    }

    public function getPathsPlaceholders(): array
    {
        return $this->pathsPlaceholders;
    }

    public function getVersion(): string
    {
        if (!$this->version) {
            $lock = $this->outputDir . '/' . self::LOCK_FILE_NAME;

            if (file_exists($lock)) {
                $time = file_get_contents($lock);
            } else {
                $time = time();

                if ($this->isCacheEnabled()) {
                    file_put_contents($lock, $time);
                }
            }

            $this->version = (string) $time;
        }

        return $this->version;
    }

    public function isCacheEnabled(): bool
    {
        return $this->cacheEnabled;
    }

    public function setDocumentRoot(string $path): Compiler
    {
        if (!is_dir($path)) {
            throw new Exception('Given document root "' . $path . '" doesn\'t exists or is not a directory.');
        }

        $this->documentRoot = rtrim($path, '/');
        return $this;
    }

    public function setOutputDir(string $path): Compiler
    {
        if (!is_dir($path)) {
            throw new Exception('Given output dir "' . $path . '" doesn\'t exists or is not a directory.');
        }

        if (!is_writable($path)) {
            throw new Exception('Given output dir "' . $path . '" is not writable.');
        }

        $this->outputDir = rtrim($path, '/');
        return $this;
    }

    public function setPathPlaceholderDelimiter(string $delimiter): Compiler
    {
        $this->pathPlaceholderDelimiter = $delimiter;
        return $this;
    }

    public function setPublicPathPrefix(?string $publicPathPrefix): Compiler
    {
        $this->publicPathPrefix = $publicPathPrefix === null ? null : rtrim($publicPathPrefix, '/');
        return $this;
    }

    public function filesCollectionExists(string $type, string $name): bool
    {
        if (!$this->isTypeCorrect($type)) {
            throw new Exception('Unknown files collection type "' . $type . '".');
        }

        return array_key_exists($name, $this->filesCollections[$type]);
    }

    public function filesCollectionsContainerExists(string $name): bool
    {
        return array_key_exists($name, $this->filesCollectionsContainers);
    }

    public function filterExists(string $type, string $name): bool
    {
        if (!$this->isTypeCorrect($type)) {
            throw new Exception('Unknown filter type "' . $type . '".');
        }

        return array_key_exists($name, $this->filters[$type]);
    }

    public function pathPlaceholderExists(string $placeholder): bool
    {
        return array_key_exists($placeholder, $this->pathsPlaceholders);
    }

    public function setRemoteFilesLoadingTimeout(int $time): Compiler
    {
        $this->remoteFilesLoadingTimeout = $time;
        return $this;
    }

    private function compileSingleFilesCollection(FilesCollection $collection): void
    {
        $filePath = $collection->getName() . '.' . $collection->getType();

        if ($this->outputDir) {
            $filePath = $this->outputDir . '/' . $filePath;
        }

        if (file_exists($filePath) && $this->isCacheEnabled()) {
            return;
        }

        $code = $this->loadFilesContent(
            $filePath,
            $collection->getType(),
            $collection->getFiles(),
            $collection->getFilters()
        );

        file_put_contents($filePath, $code);
    }

    private function isTypeCorrect(string $type): bool
    {
        return in_array($type, [Engine::CSS, Engine::JS]);
    }

    private function loadFilesContent(string $collectionPath, string $type, array $files, array $filters): string
    {
        $output = '';
        $filesCount = count($files);
        $oncePerCollectionFilters = [];

        for ($i = 0; $i < $filesCount; $i++) {
            $filePath = $this->replacePathsPlaceholders($files[$i]);
            $filePathIsUrl = filter_var($filePath, FILTER_VALIDATE_URL);

            if ($filePathIsUrl) {
                $context = stream_context_create(['http' => [
                    'timeout' => $this->remoteFilesLoadingTimeout
                ]]);
                $fileContent = @file_get_contents($filePath, false, $context);

                if ($fileContent === false) {
                    throw new Exception('Remote file "' . $filePath . '" could not be loaded.');
                }
            } else {
                if (file_exists($filePath)) {
                    $fileContent = file_get_contents($filePath);
                } else {
                    throw new Exception('File "' . $filePath . '" not found.');
                }
            }

            foreach ($filters as $filter) {
                if (!$this->filterExists($type, $filter)) {
                    throw new Exception('Undefined ' . strtoupper($type) . ' filter "' . $filter . '".');
                }

                $filter = $this->filters[$type][$filter];

                if ($filter['forEachFile']) {
                    $fileContent = $filter['callback']($fileContent, $filePath);
                } else {
                    $oncePerCollectionFilters[] = $filter;
                }
            }

            if (($i + 1) < $filesCount) {
                $fileContent .= "\n";
            }

            $output .= $fileContent;
        }

        foreach ($oncePerCollectionFilters as $filter) {
            $filterOutput = $filter['callback']($output, $collectionPath);

            if ($filterOutput !== null) {
                $output = $filterOutput;
            }
        }

        return $output;
    }

    private function replacePathsPlaceholders(string $filePath): string
    {
        foreach ($this->pathsPlaceholders as $placeholder => $path) {
            $filePath = str_replace(
                $this->pathPlaceholderDelimiter . $placeholder . $this->pathPlaceholderDelimiter,
                $path,
                $filePath
            );
        }

        return $filePath;
    }
}


text:
'use strict';

Object.defineProperty(exports, '__esModule', {
  value: true
});

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }

var _events = require('events');

var _objectAssign2 = require('object-assign');

var _objectAssign3 = _interopRequireDefault(_objectAssign2);

var _transportJs = require('./transport.js');

var Store = (function (_EventEmitter) {
  function Store(props) {
    _classCallCheck(this, Store);

    _get(Object.getPrototypeOf(Store.prototype), 'constructor', this).call(this, props);
    this.socket = new _transportJs.Transport(props); //identity & root
    this.startListening();
  }

  _inherits(Store, _EventEmitter);

  _createClass(Store, [{
    key: 'startListening',
    value: function startListening() {
      if (this.listening) return;
      this.listening = true;
      this.socket.on(this.onChange.bind(this));
    }
  }, {
    key: 'stopListening',
    value: function stopListening() {
      this.socket.off();
      this.listening = false;
    }
  }, {
    key: 'get',
    value: function get() {
      this.socket.get(this.update.bind(this));
    }
  }, {
    key: 'objectAssign',

    // put() {}
    // post(data) {}
    // delete(id) {}

    // add(data) {}
    // remove(id) {}
    // update(data) {}

    // onChange(msg) {}

    value: function objectAssign() {
      _objectAssign3['default'].apply(undefined, arguments);
    }
  }]);

  return Store;
})(_events.EventEmitter);

exports.Store = Store;


text:
@implementation LOTShapeStar

- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary {
  self = [super init];
  if (self) {
    [self _mapFromJSON:jsonDictionary];
  }
  return self;
}

- (void)_mapFromJSON:(NSDictionary *)jsonDictionary {

  if (jsonDictionary[@"nm"] ) {
    _keyname = [jsonDictionary[@"nm"] copy];
  }

  NSDictionary *outerRadius = jsonDictionary[@"or"];
  if (outerRadius) {
    _outerRadius = [[LOTKeyframeGroup alloc] initWithData:outerRadius];
  }

  NSDictionary *outerRoundness = jsonDictionary[@"os"];
  if (outerRoundness) {
    _outerRoundness = [[LOTKeyframeGroup alloc] initWithData:outerRoundness];
  }

  NSDictionary *innerRadius = jsonDictionary[@"ir"];
  if (innerRadius) {
    _innerRadius = [[LOTKeyframeGroup alloc] initWithData:innerRadius];
  }

  NSDictionary *innerRoundness = jsonDictionary[@"is"];
  if (innerRoundness) {
    _innerRoundness = [[LOTKeyframeGroup alloc] initWithData:innerRoundness];
  }

  NSDictionary *position = jsonDictionary[@"p"];
  if (position) {
    _position = [[LOTKeyframeGroup alloc] initWithData:position];
  }

  NSDictionary *numberOfPoints = jsonDictionary[@"pt"];
  if (numberOfPoints) {
    _numberOfPoints = [[LOTKeyframeGroup alloc] initWithData:numberOfPoints];
  }

  NSDictionary *rotation = jsonDictionary[@"r"];
  if (rotation) {
    _rotation = [[LOTKeyframeGroup alloc] initWithData:rotation];
  }

  NSNumber *type = jsonDictionary[@"sy"];
  _type = type.integerValue;
}

@end


text:
/**
 * @file
 */

#include <org/opensplice/core/EntityRegistry.hpp>
#include <dds/domain/DomainParticipant.hpp>
#include <dds/pub/Publisher.hpp>
#include <dds/sub/Subscriber.hpp>

namespace org
{
namespace opensplice
{
namespace core
{

/* DomainParticipant */

template <>
OSPL_ISOCPP_IMPL_API std::map<DDS::DomainParticipant_ptr, dds::core::WeakReference<dds::domain::DomainParticipant> >&
org::opensplice::core::EntityRegistry<DDS::DomainParticipant_ptr, dds::domain::DomainParticipant>::registry()
{
    static std::map<DDS::DomainParticipant_ptr, dds::core::WeakReference<dds::domain::DomainParticipant> > registry_;
    return registry_;
}

/* Publisher */

template <>
OSPL_ISOCPP_IMPL_API std::map<DDS::Publisher_ptr, dds::core::WeakReference<dds::pub::Publisher> >&
org::opensplice::core::EntityRegistry<DDS::Publisher_ptr, dds::pub::Publisher>::registry()
{
    static std::map<DDS::Publisher_ptr, dds::core::WeakReference<dds::pub::Publisher> > registry_;
    return registry_;
}

/* Subscriber */

template <>
OSPL_ISOCPP_IMPL_API std::map<DDS::Subscriber_ptr, dds::core::WeakReference<dds::sub::Subscriber> >&
org::opensplice::core::EntityRegistry<DDS::Subscriber_ptr, dds::sub::Subscriber>::registry()
{
    static std::map<DDS::Subscriber_ptr, dds::core::WeakReference<dds::sub::Subscriber> > registry_;
    return registry_;
}

}
}
}


text:
require "./config/initializer"

class App < Sinatra::Base
  register Sinatra::ActiveRecordExtension

  Dir.glob('./{app/*,api}/*.rb').each { |file| require file }

  configure :production, :staging do
    enable :logging
    set :show_exceptions, false
  end

  before do
    content_type :json
  end

  error ActiveRecord::UnknownAttributeError do |e|
    halt 422, { message: e.message }.to_json
  end

  error ActiveRecord::RecordNotFound do
    halt 404, { message: "resource not found" }.to_json
  end

  not_found do
    halt 404, { message: "endpoint not found" }.to_json
  end
end


text:
function Synth() {
    this.sy=null;
    this.worker=null;
    this.que=[];
    this.Load = function(url, name, size, elemId) {
        var elem=document.getElementById(elemId);
        if(elem==null) {
            this.sy = window.open(url, name, size);
        } else {
            var iframe=document.createElement("iframe");
            iframe.src=url;
            iframe.height=200;
            iframe.width=650;
            iframe.style.setProperty("border", "1px solid #ddd");
            iframe.style.setProperty("margin", "20px");
            iframe.style.setProperty("border-radius", "5px");
            iframe.id="sy01";
            elem.appendChild(iframe);
            this.sy=iframe.contentWindow;
        }
        this.worker=new Worker('js/msgSendWorker.js');
        var self=this;
        this.worker.addEventListener('message', function(event) {
            self.SendMessage(self.sy, event.data);
        }, false);
    };
    this.NoteOn = function(note, velo) {
        this.SendMessage(this.sy, "midi,90," + note.toString(16) + "," + velo.toString(16));
    };
    this.NoteOff = function(note) {
        this.SendMessage(this.sy, "midi,80," + note.toString(16) + ",0");
    };
    this.AllSoundOff = function() {
        this.SendMessage(this.sy, "midi,b0,78,0");
    };
    this.SendMessage = function(sy, s) {
        if(this.sy) {
            this.sy.postMessage(s, "*");
        }
    };
    this.send = function(msg, time, useWorker) {
        if(useWorker==false) {
            this.sy.postMessage(msg, "*");
        } else {
            this.worker.postMessage(msg+":"+time);
        }
    };
}
var synth = new Synth();


text:
export const ORIGIN = window.location.origin ||
  `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ''}`;


text:
.. _bind_dsl:

Explicit Binding with ``#bind[T]``
==================================

.. important::

  Please see the section on including test-jar dependencies in your project:
  `Test Dependencies <../..#test-dependencies>`_.

Embedded ``#bind[T]``
----------------------------

In the cases where we'd like to easily replace a bound instance with another instance in our tests
(e.g. with a mock or a simple stub implementation), we do not need to create a specific module
for testing to compose into our server as an override module. Instead we can use the `#bind[T]`
function on the embedded server.

This is especially useful if you want to replace a bound instance with a mock under control of the
test.

.. code:: scala

    import com.twitter.finatra.http.{EmbeddedHttpServer, HttpTest}
    import com.twitter.inject.server.FeatureTest
    import com.twitter.util.mock.Mockito

    class ExampleFeatureTest
      extends FeatureTest
      with Mockito
      with HttpTest {

      private val mockDownstreamServiceClient = mock[DownstreamServiceClient]
      private val mockIdService = mock[IdService]

      override val server =
        new EmbeddedHttpServer(new ExampleServer)
        .bind[DownstreamServiceClient].toInstance(mockDownstreamServiceClient)
        .bind[IdService].toInstance(mockIdService)

      test("service test") {
        /* Mock GET Request performed by DownstreamServiceClient */
        mockDownstreamServiceClient.get("/tweets/123.json")(manifest[FooResponse]) returns Future(None)
        ...
      }

For a complete example, see the
`TwitterCloneFeatureTest <https://github.com/twitter/finatra/blob/develop/examples/advanced/twitter-clone/src/test/scala/finatra/quickstart/TwitterCloneFeatureTest.scala>`__.

Note this is also available for `EmbeddedApp <https://github.com/twitter/finatra/blob/develop/inject/inject-app/src/test/scala/com/twitter/inject/app/EmbeddedApp.scala>`__
as well:

.. code:: scala

    import com.twitter.finagle.stats.InMemoryStatsReceiver
    import com.twitter.inject.Test
    import com.twitter.inject.app.EmbeddedApp
    import com.twitter.util.mock.Mockito

    class MyAppTest extends Test with Mockito {
      private val inMemoryStatsReceiver: InMemoryStatsReceiver = new InMemoryStatsReceiver
      private val mockIdService = mock[IdService]

      // build an EmbeddedApp
      def app(): EmbeddedApp = app(new MyApp)
      def app(underlying: MyApp): EmbeddedApp =
        new EmbeddedApp(underlying)
          .bind[IdService].toInstance(mockIdService)
          .bind[StatsReceiver].toInstance(inMemoryStatsReceiver)

      test("assert count") {
        val undertest = app()
        undertest.main("username" -> "jack")

        val statsReceiver = undertest.injector.instance[StatsReceiver].asInstanceOf[InMemoryStatsReceiver]
        statsReceiver.counter("my_counter")() shouldEqual 1
      }
    }

TestInjector ``#bind[T]``
-------------------------

As described in the `Integration Tests <./integration_tests.html>`__ section you can use the
|TestInjector|_ to construct a minimal object graph for testing. The `TestInjector` also supports a
`bind[T]` function to let you replace bound instances in the constructed object graph with another
instance, like a mock or stub.

E.g.,

.. code:: scala

    import com.twitter.inject.IntegrationTest

    class ExampleIntegrationTest extends IntegrationTest {
      val mockIdService = mock[IdService]

      override val injector =
        TestInjector(
          flags =
            Map("foo.flag" -> "meaningfulValue"),
          modules =
            Seq(ExampleModule, IdServiceModule))
          .bind[IdService].toInstance(mockIdService)
          .create

      test("MyTest#perform feature") {
        ...
      }
    }

In this example, the bound `IdService` would be replaced with the `mockIdService`. For a more complete
example, see the `DarkTrafficCanonicalResourceHeaderTest <https://github.com/twitter/finatra/blob/develop/http-server/src/test/scala/com/twitter/finatra/http/tests/integration/darktraffic/test/DarkTrafficCanonicalResourceHeaderTest.scala>`__.

|#bind[T]|_ DSL
---------------

The primary DSL can be expressed as such (and is similar to the Guice `Linked <https://github.com/google/guice/wiki/LinkedBindings>`__
and `Instance <https://github.com/google/guice/wiki/InstanceBindings>`__ bindings):

.. code:: scala

    bind[T].to[U <: T]
    bind[T].to[Class[U <: T]]
    bind[T].toInstance(T)

    bind[T].annotatedWith[Ann].to[U <: T]
    bind[T].annotatedWith[Ann].to[Class[U <: T]]
    bind[T].annotatedWith[Ann].toInstance(T)

    bind[T].annotatedWith[Class[Ann]].to[U <: T]
    bind[T].annotatedWith[Class[Ann]].to[Class[U <: T]]
    bind[T].annotatedWith[Class[Ann]].toInstance(T)

    bind[T].annotatedWith(Annotation).to[U <: T]
    bind[T].annotatedWith(Annotation).to[Class[U <: T]]
    bind[T].annotatedWith(Annotation).toInstance(T)

    bindClass(Class[T]).to[T]
    bindClass(Class[T]).to[Class[U <: T]]
    bindClass(Class[T]).toInstance(T)

    bindClass(Class[T]).annotatedWith[Class[Ann]].to[T]
    bindClass(Class[T]).annotatedWith[Class[Ann]].[Class[U <: T]]
    bindClass(Class[T]).annotatedWith[Class[Ann]].toInstance(T)

    bindClass(Class[T]).annotatedWith(Annotation).to[T]
    bindClass(Class[T]).annotatedWith(Annotation).[Class[U <: T]]
    bindClass(Class[T]).annotatedWith(Annotation).toInstance(T)

Usage from Java
---------------

The `#bind[T]` DSL also provides several Java-friendly methods for binding:

.. code:: scala

    bindClass(Class[T], T)
    bindClass(Class[T], Annotation, T)
    bindClass(Class[T], Class[Annotation], T)

    bindClass(Class[T], Class[U <: T])
    bindClass(Class[T], Annotation, Class[U <: T])
    bindClass(Class[T], Class[Annotation], Class[U <: T])

Example:

.. code:: java

    import java.util.Collections;

    import com.google.inject.Stage;

    import org.junit.AfterClass;
    import org.junit.Assert;
    import org.junit.BeforeClass;
    import org.junit.Test;

    import com.twitter.finagle.http.Request;
    import com.twitter.finagle.http.Response;
    import com.twitter.finagle.http.Status;
    import com.twitter.finatra.http.EmbeddedHttpServer;
    import com.twitter.finatra.http.request.RequestBuilder;
    import com.twitter.inject.annotations.Flags;

    public class HelloWorldServerFeatureTest extends Assert {

        private static final EmbeddedHttpServer SERVER = setup();

        private static EmbeddedHttpServer setup() {
            EmbeddedHttpServer server = new EmbeddedHttpServer(
                new HelloWorldServer(),
                Collections.emptyMap(),
                Stage.DEVELOPMENT);

            server.bindClass(Integer.class, Flags.named("magic.number"), 42);
            server.bindClass(Integer.class, Flags.named("module.magic.number"), 9999);
            return server;
        }

        ...

        /** test magicNum endpoint */
        @Test
        public void testMagicNumEndpoint() {
            Request request = RequestBuilder.get("/magicNum");
            Response response = SERVER.httpRequest(request);
            assertEquals(Status.Ok(), response.status());
            assertEquals("42", response.contentString());
        }
    }

See the `java-http-server <https://github.com/twitter/finatra/tree/develop/examples/http-server/java/src/main/java>`__
for a full example of using the `#bind[T]` DSL in test to override a binding in a server.

Injecting Members of a Test
---------------------------

.. warning::

    Do not inject members of a test class into the server, application or |TestInjector|_ object
    graph under test.

We strongly **discourage** injecting members of a test via your server, application or
|TestInjector|_. This includes using `@Inject` or `@Bind` (the `com.google.inject.testing.fieldbinder.Bind`
annotation with the `BoundFieldModule <https://github.com/google/guice/wiki/BoundFields>`__) on a
test member field then using the `c.t.inject.Injector <https://github.com/twitter/finatra/blob/develop/inject/inject-core/src/main/scala/com/twitter/inject/Injector.scala>`__
of the server, application or |TestInjector|_ under test to do `injector.underlying.injectMembers(this)`.

.. code:: scala

    class MyIntegrationTest extends IntegrationTest {

      // THIS IS NOT RECOMMENDED
      @Bind(to = classOf[StubBarImp]) private val bar: Bar
      // Foo depends on Bar.
      @Inject private val foo: Foo
      @Bind private val mockDatasource: Datasource = mock[DatasourceImplementation]

      override val injector =
        TestInjector(
          modules = Seq(new OurGreatModule(), BoundFieldModule.of(this)),
        ).create()

        injector.injectMembers(this)

        test("test something") {
          ...
        }
    }

Or you could choose to do the test class member injection in a `beforeAll`:

.. code:: scala

    class MyIntegrationTest extends IntegrationTest {

      // THIS IS NOT RECOMMENDED
      @Bind(to = classOf[StubBarImp]) private val bar: Bar
      // Foo depends on Bar.
      @Inject private val foo: Foo
      @Bind private val mockDatasource = mock[DatasourceImplementation]

      override val injector =
        TestInjector(
          modules = Seq(new OurGreatModule(), BoundFieldModule.of(this)),
        ).create()

      override protected def beforeAll(): Unit = {
        super.beforeAll()
        injector.injectMembers(this)
      }

        test("test something") {
          ...
        }
    }

Or with a `FeatureTest <./feature_tests.html>`__:

.. code:: scala

    class MyFeatureTest extends FeatureTest {
      // THIS IS NOT RECOMMENDED
      @Inject val fakeFilesystem: Filesystem
      @Inject val mockSubsystem: Subsystem

      override val server = new EmbeddedHttpServer(
        twitterServer = new OurHttpTwitterServerUnderTest {
          val modules: Seq[Module] = defaultModules ++ Seq(TestModuleWithTheSystemBindings)
        }
      )

      override protected def beforeAll(): Unit = {
        super.beforeAll()
        server.injector.underlying.injectMembers(this)
      }

      test("test something") {
        ...
      }

    }

Why?
~~~~

You can perhaps see from the above that there is an impedance mismatch from the creation of the
object graph under test via creation of the `Injector` and calling `injectMembers(this)`.

At the very least, this usage tends to violate the encapsulation of the system under test. As
mentioned previously, the object graph under test is created from a stateful `Injector` with a
lifecycle that is managed by the framework that is different from the lifecycle of the test class.
Mixing them in this manner is hard to reason about and can lead to possibly non-deterministic tests.
This usage also makes it harder to test `multiple servers or applications <./feature_tests.html#testing-multiple-applications-or-servers>`__
in a single test file.

If something accesses a value from the `Injector` before `beforeAll()` was called, e.g., another eager
`val` in the constructor of the test class, this could potentially fail, or worse, an incorrect value
could be returned (since the `Injector` will try to instantiate whatever is asked for, relying on
any default no-arg constructor). Moving the `injectMembers(this)` to also be in the test class
constructor can help, but then ordering of calls is important as the `injectMembers(this)` would need
to happen before any access of `Injector` values that are expected to be bound. As such, we have
generally found that in any sufficiently large or complex test suite, this usages tends towards
brittle tests.

Alternatives
~~~~~~~~~~~~

Replacing object graph bindings
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The framework provides ways to safely replace bindings in the object graph under test, properly
taking into account the lifecycle to handle parsing of flag values. Users should prefer to either
provide an `override module <./override_modules.html>`__ or use the `#bind[T]` DSL to replace a
binding **when instantiating** the object graph under test when it is necessary to *replace* a
binding in the object graph under test.

Managing test fixtures
^^^^^^^^^^^^^^^^^^^^^^

One reason for test member injection is to be able to easily create test fixtures. If it is
necessary to use an object graph for managing some set of test fixture instances that are separate
from the server or application, **do not use** the `Injector` from the server, application, nor the
|TestInjector|_ under test. Instead, create a separate `Injector` -- you can use a new
`c.t.inject.app.TestInjector <integration_tests.html#id2>`__ to aid in this.

Thus, we recommend that you explicitly create a separate object graph and obtain any necessary
instances from the appropriate object graph over using the indirection of injecting test members. In
this way, all object graphs are established at instantiation of the test member making it easier to
reason about the test lifecycle.

For example:

.. code:: scala

    class MyIntegrationTest extends IntegrationTest {

      private val mockDatasource = mock[DatasourceImplementation]

      // create an object graph for obtaining test fixtures. `OurIntegrationTestModule`
      // provides bindings for `Foo` and `Bar`
      private[this] val testFixturesInjector =
        TestInjector(
          modules = Seq(new OurIntegrationTestModule())
        )
        .bind[Datasource].toInstance(mockDatasource)
        .create()

      private val foo: Foo = testFixturesInjector.instance[Foo]
      private val bar: Bar = testFixturesInjector.instance[Bar]

      // the object graph under test
      override val injector =
        TestInjector(
          modules = Seq(new OurGreatModule())
        ).create()

      test("test something") {
        ...
      }
    }

Or with a `FeatureTest <./feature_tests.html>`__:

.. code:: scala

    class MyFeatureTest extends FeatureTest {

      // create an object graph for obtaining test fixtures, `OurIntegrationTestModule`
      // provides bindings for `Filesystem` and `Subsystem`
      private[this] val testFixturesInjector =
        TestInjector(
          modules = Seq(new OurIntegrationTestModule())
        ).create()

      private val fakeFilesystem: Filesystem = testFixturesInjector.instance[Filesystem]
      private val mockSubsystem: Subsystem = testFixturesInjector.instance[Subsystem]

      // the object graph under test is encapsulated in the embedded server
      override val server = new EmbeddedHttpServer(
        twitterServer = new OurHttpTwitterServerUnderTest
      )

      test("test something") {
        ...
      }
    }

This is the same tactic taken in testing `multiple servers or applications <./feature_tests.html#testing-multiple-applications-or-servers>`__
in a single test file. Each server or application encapsulates an `Injector` which is established at
instantiation of each server or application within the test. Any necessary instances are then explicitly
obtained from the appropriate object graph for use in testing.

Further Reading
---------------

More resources on `test doubles <http://xunitpatterns.com/Test%20Double.html>`__:

* `Mocks Aren't Stubs <https://martinfowler.com/articles/mocksArentStubs.html>`__

* `Test Doubles — Fakes, Mocks and Stubs. <https://blog.pragmatists.com/test-doubles-fakes-mocks-and-stubs-1a7491dfa3da>`__

More Information
----------------

- :doc:`index`
- :doc:`embedded`
- :doc:`feature_tests`
- :doc:`integration_tests`
- :doc:`startup_tests`
- :doc:`mocks`
- :doc:`mixins`
- :doc:`override_modules`

.. |#bind[T]| replace:: `#bind[T]`
.. _#bind[T]: https://github.com/twitter/finatra/tree/develop/inject/inject-app/src/test/scala/com/twitter/inject/app/BindDSL.scala

.. |TestInjector| replace:: `TestInjector`
.. _TestInjector: ./integration_tests.html#id2


text:
import React from 'react'
import { Embed } from 'semantic-ui-react'

const EmbedExampleAspectRatio = () => (
  <Embed
    aspectRatio='4:3'
    id='HTZudKi36bo'
    placeholder='/images/4by3.jpg'
    source='youtube'
  />
)

export default EmbedExampleAspectRatio


text:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;

namespace Xceed.Wpf.DataGrid
{
  internal class CurrentColumnChangedEventManager: WeakEventManager
  {
    private CurrentColumnChangedEventManager()
    {
    }

    public static void AddListener( DetailConfiguration source, IWeakEventListener listener )
    {
      CurrentManager.ProtectedAddListener( source, listener );
    }

    public static void RemoveListener( DetailConfiguration source, IWeakEventListener listener )
    {
      CurrentManager.ProtectedRemoveListener( source, listener );
    }

    protected override void StartListening( object source )
    {
      DetailConfiguration detailConfig = ( DetailConfiguration )source;
      detailConfig.CurrentColumnChanged += new EventHandler( this.OnCurrentColumnChanged );
    }

    protected override void StopListening( object source )
    {
      DetailConfiguration detailConfig = ( DetailConfiguration )source;
      detailConfig.CurrentColumnChanged -= new EventHandler( this.OnCurrentColumnChanged );
    }

    private static CurrentColumnChangedEventManager CurrentManager
    {
      get
      {
        Type managerType = typeof( CurrentColumnChangedEventManager );
        CurrentColumnChangedEventManager currentManager = ( CurrentColumnChangedEventManager )WeakEventManager.GetCurrentManager( managerType );

        if( currentManager == null )
        {
          currentManager = new CurrentColumnChangedEventManager();
          WeakEventManager.SetCurrentManager( managerType, currentManager );
        }

        return currentManager;
      }
    }

    private void OnCurrentColumnChanged( object sender, EventArgs args )
    {
      this.DeliverEvent( sender, args );
    }
  }
}


text:
author: enthudrives
comments: true
date: 2012-02-06 18:17:30+00:00
layout: post
link: https://tsuganthi.wordpress.com/2012/02/06/optimist/
slug: optimist
title: Optimist
wordpress_id: 328
categories:
- incident
- Incidents
tags:
- Optimist
- Philosophy
---

This is a poem from my wallpaper. Inspirational.

Say to yourself every morning:

Today is going to be a great day!

I can handle more things than I think I can!

Things don't get better by worrying about them!

I can be satisfied if I try to do my best!

There is always something to be happy about!

I'm going to make someone happy today!

It's not good to be down!

Life is great, make the most of it!

Be an Optimist!!


text:
package gitbucket.core.controller

import gitbucket.core.model.WebHook
import gitbucket.core.pulls.html
import gitbucket.core.service.CommitStatusService
import gitbucket.core.service.MergeService
import gitbucket.core.service.IssuesService._
import gitbucket.core.service.PullRequestService._
import gitbucket.core.service._
import gitbucket.core.util.ControlUtil._
import gitbucket.core.util.Directory._
import gitbucket.core.util.Implicits._
import gitbucket.core.util.JGitUtil._
import gitbucket.core.util._
import gitbucket.core.view
import gitbucket.core.view.helpers

import io.github.gitbucket.scalatra.forms._
import org.eclipse.jgit.api.Git
import org.eclipse.jgit.lib.PersonIdent
import org.slf4j.LoggerFactory

import scala.collection.JavaConverters._

class PullRequestsController extends PullRequestsControllerBase
  with RepositoryService with AccountService with IssuesService with PullRequestService with MilestonesService with LabelsService
  with CommitsService with ActivityService with WebHookPullRequestService with ReferrerAuthenticator with CollaboratorsAuthenticator
  with CommitStatusService with MergeService with ProtectedBranchService

trait PullRequestsControllerBase extends ControllerBase {
  self: RepositoryService with AccountService with IssuesService with MilestonesService with LabelsService
    with CommitsService with ActivityService with PullRequestService with WebHookPullRequestService with ReferrerAuthenticator with CollaboratorsAuthenticator
    with CommitStatusService with MergeService with ProtectedBranchService =>

  private val logger = LoggerFactory.getLogger(classOf[PullRequestsControllerBase])

  val pullRequestForm = mapping(
    "title"                 -> trim(label("Title"  , text(required, maxlength(100)))),
    "content"               -> trim(label("Content", optional(text()))),
    "targetUserName"        -> trim(text(required, maxlength(100))),
    "targetBranch"          -> trim(text(required, maxlength(100))),
    "requestUserName"       -> trim(text(required, maxlength(100))),
    "requestRepositoryName" -> trim(text(required, maxlength(100))),
    "requestBranch"         -> trim(text(required, maxlength(100))),
    "commitIdFrom"          -> trim(text(required, maxlength(40))),
    "commitIdTo"            -> trim(text(required, maxlength(40))),
    "assignedUserName"      -> trim(optional(text())),
    "milestoneId"           -> trim(optional(number())),
    "labelNames"            -> trim(optional(text()))
  )(PullRequestForm.apply)

  val mergeForm = mapping(
    "message" -> trim(label("Message", text(required)))
  )(MergeForm.apply)

  case class PullRequestForm(
    title: String,
    content: Option[String],
    targetUserName: String,
    targetBranch: String,
    requestUserName: String,
    requestRepositoryName: String,
    requestBranch: String,
    commitIdFrom: String,
    commitIdTo: String,
    assignedUserName: Option[String],
    milestoneId: Option[Int],
    labelNames: Option[String]
  )

  case class MergeForm(message: String)

  get("/:owner/:repository/pulls")(referrersOnly { repository =>
    val q = request.getParameter("q")
    if(Option(q).exists(_.contains("is:issue"))){
      redirect(s"/${repository.owner}/${repository.name}/issues?q=" + StringUtil.urlEncode(q))
    } else {
      searchPullRequests(None, repository)
    }
  })

  get("/:owner/:repository/pull/:id")(referrersOnly { repository =>
    params("id").toIntOpt.flatMap{ issueId =>
      val owner = repository.owner
      val name = repository.name
      getPullRequest(owner, name, issueId) map { case(issue, pullreq) =>
        using(Git.open(getRepositoryDir(owner, name))){ git =>
          val (commits, diffs) =
            getRequestCompareInfo(owner, name, pullreq.commitIdFrom, owner, name, pullreq.commitIdTo)
          html.pullreq(
            issue, pullreq,
            (commits.flatten.map(commit => getCommitComments(owner, name, commit.id, true)).flatten.toList ::: getComments(owner, name, issueId))
              .sortWith((a, b) => a.registeredDate before b.registeredDate),
            getIssueLabels(owner, name, issueId),
            (getCollaborators(owner, name) ::: (if(getAccountByUserName(owner).get.isGroupAccount) Nil else List(owner))).sorted,
            getMilestonesWithIssueCount(owner, name),
            getLabels(owner, name),
            commits,
            diffs,
            hasWritePermission(owner, name, context.loginAccount),
            repository,
            flash.toMap.map(f => f._1 -> f._2.toString))
        }
      }
    } getOrElse NotFound
  })

  ajaxGet("/:owner/:repository/pull/:id/mergeguide")(referrersOnly { repository =>
    params("id").toIntOpt.flatMap{ issueId =>
      val owner = repository.owner
      val name  = repository.name
      getPullRequest(owner, name, issueId) map { case(issue, pullreq) =>
        val hasConflict = LockUtil.lock(s"${owner}/${name}"){
          checkConflict(owner, name, pullreq.branch, issueId)
        }
        val hasMergePermission = hasWritePermission(owner, name, context.loginAccount)
        val branchProtection = getProtectedBranchInfo(owner, name, pullreq.branch)
        val mergeStatus = PullRequestService.MergeStatus(
           hasConflict         = hasConflict,
           commitStatues       = getCommitStatues(owner, name, pullreq.commitIdTo),
           branchProtection    = branchProtection,
           branchIsOutOfDate   = JGitUtil.getShaByRef(owner, name, pullreq.branch) != Some(pullreq.commitIdFrom),
           needStatusCheck     = context.loginAccount.map{ u =>
                                   branchProtection.needStatusCheck(u.userName)
                                 }.getOrElse(true),
           hasUpdatePermission = hasWritePermission(pullreq.requestUserName, pullreq.requestRepositoryName, context.loginAccount) &&
                                   context.loginAccount.map{ u =>
                                     !getProtectedBranchInfo(pullreq.requestUserName, pullreq.requestRepositoryName, pullreq.requestBranch).needStatusCheck(u.userName)
                                   }.getOrElse(false),
           hasMergePermission  = hasMergePermission,
           commitIdTo          = pullreq.commitIdTo)
        html.mergeguide(
          mergeStatus,
          issue,
          pullreq,
          repository,
          getRepository(pullreq.requestUserName, pullreq.requestRepositoryName).get)
      }
    } getOrElse NotFound
  })

  get("/:owner/:repository/pull/:id/delete/*")(collaboratorsOnly { repository =>
    params("id").toIntOpt.map { issueId =>
      val branchName = multiParams("splat").head
      val userName   = context.loginAccount.get.userName
      if(repository.repository.defaultBranch != branchName){
        using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
          git.branchDelete().setForce(true).setBranchNames(branchName).call()
          recordDeleteBranchActivity(repository.owner, repository.name, userName, branchName)
        }
      }
      createComment(repository.owner, repository.name, userName, issueId, branchName, "delete_branch")
      redirect(s"/${repository.owner}/${repository.name}/pull/${issueId}")
    } getOrElse NotFound
  })

  post("/:owner/:repository/pull/:id/update_branch")(referrersOnly { baseRepository =>
    (for {
      issueId <- params("id").toIntOpt
      loginAccount <- context.loginAccount
      (issue, pullreq) <- getPullRequest(baseRepository.owner, baseRepository.name, issueId)
      owner = pullreq.requestUserName
      name  = pullreq.requestRepositoryName
      if hasWritePermission(owner, name, context.loginAccount)
    } yield {
      val branchProtection = getProtectedBranchInfo(owner, name, pullreq.requestBranch)
      if(branchProtection.needStatusCheck(loginAccount.userName)){
        flash += "error" -> s"branch ${pullreq.requestBranch} is protected need status check."
      } else {
        val repository = getRepository(owner, name).get
        LockUtil.lock(s"${owner}/${name}"){
          val alias = if(pullreq.repositoryName == pullreq.requestRepositoryName && pullreq.userName == pullreq.requestUserName){
            pullreq.branch
          }else{
            s"${pullreq.userName}:${pullreq.branch}"
          }
          val existIds = using(Git.open(Directory.getRepositoryDir(owner, name))) { git => JGitUtil.getAllCommitIds(git) }.toSet
          pullRemote(owner, name, pullreq.requestBranch, pullreq.userName, pullreq.repositoryName, pullreq.branch, loginAccount,
                     s"Merge branch '${alias}' into ${pullreq.requestBranch}") match {
            case None => // conflict
              flash += "error" -> s"Can't automatic merging branch '${alias}' into ${pullreq.requestBranch}."
            case Some(oldId) =>
              // update pull request
              updatePullRequests(owner, name, pullreq.requestBranch)

              using(Git.open(Directory.getRepositoryDir(owner, name))) { git =>
                //  after update branch

                val newCommitId = git.getRepository.resolve(s"refs/heads/${pullreq.requestBranch}")
                val commits = git.log.addRange(oldId, newCommitId).call.iterator.asScala.map(c => new JGitUtil.CommitInfo(c)).toList

                commits.foreach{ commit =>
                  if(!existIds.contains(commit.id)){
                    createIssueComment(owner, name, commit)
                  }
                }

                // record activity
                recordPushActivity(owner, name, loginAccount.userName, pullreq.branch, commits)

                // close issue by commit message
                if(pullreq.requestBranch == repository.repository.defaultBranch){
                  commits.map { commit =>
                    closeIssuesFromMessage(commit.fullMessage, loginAccount.userName, owner, name)
                  }
                }

                // call web hook
                callPullRequestWebHookByRequestBranch("synchronize", repository, pullreq.requestBranch, baseUrl, loginAccount)
                callWebHookOf(owner, name, WebHook.Push) {
                  for {
                    ownerAccount <- getAccountByUserName(owner)
                  } yield {
                    WebHookService.WebHookPushPayload(git, loginAccount, pullreq.requestBranch, repository, commits, ownerAccount, oldId = oldId, newId = newCommitId)
                  }
                }
              }
              flash += "info" -> s"Merge branch '${alias}' into ${pullreq.requestBranch}"
          }
        }
        redirect(s"/${repository.owner}/${repository.name}/pull/${issueId}")
      }
    }) getOrElse NotFound
  })

  post("/:owner/:repository/pull/:id/merge", mergeForm)(collaboratorsOnly { (form, repository) =>
    params("id").toIntOpt.flatMap { issueId =>
      val owner = repository.owner
      val name  = repository.name
      LockUtil.lock(s"${owner}/${name}"){
        getPullRequest(owner, name, issueId).map { case (issue, pullreq) =>
          using(Git.open(getRepositoryDir(owner, name))) { git =>
            // mark issue as merged and close.
            val loginAccount = context.loginAccount.get
            createComment(owner, name, loginAccount.userName, issueId, form.message, "merge")
            createComment(owner, name, loginAccount.userName, issueId, "Close", "close")
            updateClosed(owner, name, issueId, true)

            // record activity
            recordMergeActivity(owner, name, loginAccount.userName, issueId, form.message)

            // merge git repository
            mergePullRequest(git, pullreq.branch, issueId,
              s"Merge pull request #${issueId} from ${pullreq.requestUserName}/${pullreq.requestBranch}\n\n" + form.message,
               new PersonIdent(loginAccount.fullName, loginAccount.mailAddress))

            val (commits, _) = getRequestCompareInfo(owner, name, pullreq.commitIdFrom,
              pullreq.requestUserName, pullreq.requestRepositoryName, pullreq.commitIdTo)

            // close issue by content of pull request
            val defaultBranch = getRepository(owner, name).get.repository.defaultBranch
            if(pullreq.branch == defaultBranch){
              commits.flatten.foreach { commit =>
                closeIssuesFromMessage(commit.fullMessage, loginAccount.userName, owner, name)
              }
              closeIssuesFromMessage(issue.title + " " + issue.content.getOrElse(""), loginAccount.userName, owner, name)
              closeIssuesFromMessage(form.message, loginAccount.userName, owner, name)
            }

            updatePullRequests(owner, name, pullreq.branch)

            // call web hook
            callPullRequestWebHook("closed", repository, issueId, context.baseUrl, context.loginAccount.get)

            // notifications
            Notifier().toNotify(repository, issue, "merge"){
              Notifier.msgStatus(s"${context.baseUrl}/${owner}/${name}/pull/${issueId}")
            }

            redirect(s"/${owner}/${name}/pull/${issueId}")
          }
        }
      }
    } getOrElse NotFound
  })

  get("/:owner/:repository/compare")(referrersOnly { forkedRepository =>
    val headBranch:Option[String] = params.get("head")
    (forkedRepository.repository.originUserName, forkedRepository.repository.originRepositoryName) match {
      case (Some(originUserName), Some(originRepositoryName)) => {
        getRepository(originUserName, originRepositoryName).map { originRepository =>
          using(
            Git.open(getRepositoryDir(originUserName, originRepositoryName)),
            Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))
          ){ (oldGit, newGit) =>
            val newBranch = headBranch.getOrElse(JGitUtil.getDefaultBranch(newGit, forkedRepository).get._2)
            val oldBranch = originRepository.branchList.find( _ == newBranch).getOrElse(JGitUtil.getDefaultBranch(oldGit, originRepository).get._2)

            redirect(s"/${forkedRepository.owner}/${forkedRepository.name}/compare/${originUserName}:${oldBranch}...${newBranch}")
          }
        } getOrElse NotFound
      }
      case _ => {
        using(Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))){ git =>
          JGitUtil.getDefaultBranch(git, forkedRepository).map { case (_, defaultBranch) =>
            redirect(s"/${forkedRepository.owner}/${forkedRepository.name}/compare/${defaultBranch}...${headBranch.getOrElse(defaultBranch)}")
          } getOrElse {
            redirect(s"/${forkedRepository.owner}/${forkedRepository.name}")
          }
        }
      }
    }
  })

  get("/:owner/:repository/compare/*...*")(referrersOnly { forkedRepository =>
    val Seq(origin, forked) = multiParams("splat")
    val (originOwner, originId) = parseCompareIdentifie(origin, forkedRepository.owner)
    val (forkedOwner, forkedId) = parseCompareIdentifie(forked, forkedRepository.owner)

    (for(
      originRepositoryName <- if(originOwner == forkedOwner) {
        // Self repository
        Some(forkedRepository.name)
      } else if(forkedRepository.repository.originUserName.isEmpty){
        // when ForkedRepository is the original repository
        getForkedRepositories(forkedRepository.owner, forkedRepository.name).find(_._1 == originOwner).map(_._2)
      } else if(Some(originOwner) == forkedRepository.repository.originUserName){
        // Original repository
        forkedRepository.repository.originRepositoryName
      } else {
        // Sibling repository
        getUserRepositories(originOwner).find { x =>
          x.repository.originUserName == forkedRepository.repository.originUserName &&
            x.repository.originRepositoryName == forkedRepository.repository.originRepositoryName
        }.map(_.repository.repositoryName)
      };
      originRepository <- getRepository(originOwner, originRepositoryName)
    ) yield {
      using(
        Git.open(getRepositoryDir(originRepository.owner, originRepository.name)),
        Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))
      ){ case (oldGit, newGit) =>
        val (oldId, newId) =
          if(originRepository.branchList.contains(originId) && forkedRepository.branchList.contains(forkedId)){
            // Branch name
            val rootId = JGitUtil.getForkedCommitId(oldGit, newGit,
              originRepository.owner, originRepository.name, originId,
              forkedRepository.owner, forkedRepository.name, forkedId)

            (Option(oldGit.getRepository.resolve(rootId)),  Option(newGit.getRepository.resolve(forkedId)))
          } else {
            // Commit id
            (Option(oldGit.getRepository.resolve(originId)), Option(newGit.getRepository.resolve(forkedId)))
          }

        (oldId, newId) match {
          case (Some(oldId), Some(newId)) => {
            val (commits, diffs) = getRequestCompareInfo(
              originRepository.owner, originRepository.name, oldId.getName,
              forkedRepository.owner, forkedRepository.name, newId.getName)

            val title = if(commits.flatten.length == 1){
              commits.flatten.head.shortMessage
            } else {
              val text = forkedId.replaceAll("[\\-_]", " ")
              text.substring(0, 1).toUpperCase + text.substring(1)
            }

            html.compare(
              title,
              commits,
              diffs,
              (forkedRepository.repository.originUserName, forkedRepository.repository.originRepositoryName) match {
                case (Some(userName), Some(repositoryName)) => (userName, repositoryName) :: getForkedRepositories(userName, repositoryName)
                case _ => (forkedRepository.owner, forkedRepository.name) :: getForkedRepositories(forkedRepository.owner, forkedRepository.name)
              },
              commits.flatten.map(commit => getCommitComments(forkedRepository.owner, forkedRepository.name, commit.id, false)).flatten.toList,
              originId,
              forkedId,
              oldId.getName,
              newId.getName,
              forkedRepository,
              originRepository,
              forkedRepository,
              hasWritePermission(originRepository.owner, originRepository.name, context.loginAccount),
              (getCollaborators(originRepository.owner, originRepository.name) ::: (if(getAccountByUserName(originRepository.owner).get.isGroupAccount) Nil else List(originRepository.owner))).sorted,
              getMilestones(originRepository.owner, originRepository.name),
              getLabels(originRepository.owner, originRepository.name)
            )
          }
          case (oldId, newId) =>
            redirect(s"/${forkedRepository.owner}/${forkedRepository.name}/compare/" +
                     s"${originOwner}:${oldId.map(_ => originId).getOrElse(originRepository.repository.defaultBranch)}..." +
                     s"${forkedOwner}:${newId.map(_ => forkedId).getOrElse(forkedRepository.repository.defaultBranch)}")
        }
      }
    }) getOrElse NotFound
  })

  ajaxGet("/:owner/:repository/compare/*...*/mergecheck")(collaboratorsOnly { forkedRepository =>
    val Seq(origin, forked) = multiParams("splat")
    val (originOwner, tmpOriginBranch) = parseCompareIdentifie(origin, forkedRepository.owner)
    val (forkedOwner, tmpForkedBranch) = parseCompareIdentifie(forked, forkedRepository.owner)

    (for(
      originRepositoryName <- if(originOwner == forkedOwner){
        Some(forkedRepository.name)
      } else {
        forkedRepository.repository.originRepositoryName.orElse {
          getForkedRepositories(forkedRepository.owner, forkedRepository.name).find(_._1 == originOwner).map(_._2)
        }
      };
      originRepository <- getRepository(originOwner, originRepositoryName)
    ) yield {
      using(
        Git.open(getRepositoryDir(originRepository.owner, originRepository.name)),
        Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))
      ){ case (oldGit, newGit) =>
        val originBranch = JGitUtil.getDefaultBranch(oldGit, originRepository, tmpOriginBranch).get._2
        val forkedBranch = JGitUtil.getDefaultBranch(newGit, forkedRepository, tmpForkedBranch).get._2
        val conflict = LockUtil.lock(s"${originRepository.owner}/${originRepository.name}"){
          checkConflict(originRepository.owner, originRepository.name, originBranch,
                        forkedRepository.owner, forkedRepository.name, forkedBranch)
        }
        html.mergecheck(conflict)
      }
    }) getOrElse NotFound
  })

  post("/:owner/:repository/pulls/new", pullRequestForm)(referrersOnly { (form, repository) =>
    defining(repository.owner, repository.name){ case (owner, name) =>
      val writable = hasWritePermission(owner, name, context.loginAccount)
      val loginUserName = context.loginAccount.get.userName

      val issueId = createIssue(
        owner            = repository.owner,
        repository       = repository.name,
        loginUser        = loginUserName,
        title            = form.title,
        content          = form.content,
        assignedUserName = if(writable) form.assignedUserName else None,
        milestoneId      = if(writable) form.milestoneId else None,
        isPullRequest    = true)

      createPullRequest(
        originUserName        = repository.owner,
        originRepositoryName  = repository.name,
        issueId               = issueId,
        originBranch          = form.targetBranch,
        requestUserName       = form.requestUserName,
        requestRepositoryName = form.requestRepositoryName,
        requestBranch         = form.requestBranch,
        commitIdFrom          = form.commitIdFrom,
        commitIdTo            = form.commitIdTo)

      // insert labels
      if(writable){
        form.labelNames.map { value =>
          val labels = getLabels(owner, name)
          value.split(",").foreach { labelName =>
            labels.find(_.labelName == labelName).map { label =>
              registerIssueLabel(repository.owner, repository.name, issueId, label.labelId)
            }
          }
        }
      }

      // fetch requested branch
      fetchAsPullRequest(owner, name, form.requestUserName, form.requestRepositoryName, form.requestBranch, issueId)

      // record activity
      recordPullRequestActivity(owner, name, loginUserName, issueId, form.title)

      // call web hook
      callPullRequestWebHook("opened", repository, issueId, context.baseUrl, context.loginAccount.get)

      getIssue(owner, name, issueId.toString) foreach { issue =>
        // extract references and create refer comment
        createReferComment(owner, name, issue, form.title + " " + form.content.getOrElse(""), context.loginAccount.get)

        // notifications
        Notifier().toNotify(repository, issue, form.content.getOrElse("")){
          Notifier.msgPullRequest(s"${context.baseUrl}/${owner}/${name}/pull/${issueId}")
        }
      }

      redirect(s"/${owner}/${name}/pull/${issueId}")
    }
  })

  /**
   * Parses branch identifier and extracts owner and branch name as tuple.
   *
   * - "owner:branch" to ("owner", "branch")
   * - "branch" to ("defaultOwner", "branch")
   */
  private def parseCompareIdentifie(value: String, defaultOwner: String): (String, String) =
    if(value.contains(':')){
      val array = value.split(":")
      (array(0), array(1))
    } else {
      (defaultOwner, value)
    }

  private def getRequestCompareInfo(userName: String, repositoryName: String, branch: String,
      requestUserName: String, requestRepositoryName: String, requestCommitId: String): (Seq[Seq[CommitInfo]], Seq[DiffInfo]) =
    using(
      Git.open(getRepositoryDir(userName, repositoryName)),
      Git.open(getRepositoryDir(requestUserName, requestRepositoryName))
    ){ (oldGit, newGit) =>
      val oldId = oldGit.getRepository.resolve(branch)
      val newId = newGit.getRepository.resolve(requestCommitId)

      val commits = newGit.log.addRange(oldId, newId).call.iterator.asScala.map { revCommit =>
        new CommitInfo(revCommit)
      }.toList.splitWith { (commit1, commit2) =>
        helpers.date(commit1.commitTime) == view.helpers.date(commit2.commitTime)
      }

      val diffs = JGitUtil.getDiffs(newGit, oldId.getName, newId.getName, true)

      (commits, diffs)
    }

  private def searchPullRequests(userName: Option[String], repository: RepositoryService.RepositoryInfo) =
    defining(repository.owner, repository.name){ case (owner, repoName) =>
      val page       = IssueSearchCondition.page(request)
      val sessionKey = Keys.Session.Pulls(owner, repoName)

      // retrieve search condition
      val condition = session.putAndGet(sessionKey,
        if(request.hasQueryString) IssueSearchCondition(request)
        else session.getAs[IssueSearchCondition](sessionKey).getOrElse(IssueSearchCondition())
      )

      gitbucket.core.issues.html.list(
        "pulls",
        searchIssue(condition, true, (page - 1) * PullRequestLimit, PullRequestLimit, owner -> repoName),
        page,
        if(!getAccountByUserName(owner).exists(_.isGroupAccount)){
          (getCollaborators(owner, repoName) :+ owner).sorted
        } else {
          getCollaborators(owner, repoName)
        },
        getMilestones(owner, repoName),
        getLabels(owner, repoName),
        countIssue(condition.copy(state = "open"  ), true, owner -> repoName),
        countIssue(condition.copy(state = "closed"), true, owner -> repoName),
        condition,
        repository,
        hasWritePermission(owner, repoName, context.loginAccount))
    }

}