text:
using cc::ActiveAnimation;
using cc::AnimationCurve;
using cc::EaseTimingFunction;
using cc::FloatKeyframe;
using cc::KeyframedFloatAnimationCurve;
using cc::KeyframedTransformAnimationCurve;
using cc::TimingFunction;
using cc::TransformKeyframe;

namespace {

static int nextAnimationId = 0;

template <class Target>
int addOpacityTransition(Target& target, double duration, float startOpacity, float endOpacity, bool useTimingFunction)
{
    scoped_ptr<KeyframedFloatAnimationCurve> curve(KeyframedFloatAnimationCurve::create());

    scoped_ptr<TimingFunction> func;
    if (!useTimingFunction)
        func = EaseTimingFunction::create();
    if (duration > 0)
        curve->addKeyframe(FloatKeyframe::create(0, startOpacity, func.Pass()));
    curve->addKeyframe(FloatKeyframe::create(duration, endOpacity, scoped_ptr<cc::TimingFunction>()));

    int id = nextAnimationId++;

    scoped_ptr<ActiveAnimation> animation(ActiveAnimation::create(curve.PassAs<AnimationCurve>(), id, 0, ActiveAnimation::Opacity));
    animation->setNeedsSynchronizedStartTime(true);

    target.addAnimation(animation.Pass());
    return id;
}

template <class Target>
int addAnimatedTransform(Target& target, double duration, int deltaX, int deltaY)
{
    scoped_ptr<KeyframedTransformAnimationCurve> curve(KeyframedTransformAnimationCurve::create());

    if (duration > 0) {
        WebKit::WebTransformOperations startOperations;
        startOperations.appendTranslate(deltaX, deltaY, 0);
        curve->addKeyframe(TransformKeyframe::create(0, startOperations, scoped_ptr<cc::TimingFunction>()));
    }

    WebKit::WebTransformOperations operations;
    operations.appendTranslate(deltaX, deltaY, 0);
    curve->addKeyframe(TransformKeyframe::create(duration, operations, scoped_ptr<cc::TimingFunction>()));

    int id = nextAnimationId++;

    scoped_ptr<ActiveAnimation> animation(ActiveAnimation::create(curve.PassAs<AnimationCurve>(), id, 0, ActiveAnimation::Transform));
    animation->setNeedsSynchronizedStartTime(true);

    target.addAnimation(animation.Pass());
    return id;
}

} // namespace

namespace WebKitTests {

FakeFloatAnimationCurve::FakeFloatAnimationCurve()
    : m_duration(1)
{
}

FakeFloatAnimationCurve::FakeFloatAnimationCurve(double duration)
    : m_duration(duration)
{
}

FakeFloatAnimationCurve::~FakeFloatAnimationCurve()
{
}

double FakeFloatAnimationCurve::duration() const
{
    return m_duration;
}

float FakeFloatAnimationCurve::getValue(double now) const
{
    return 0;
}

scoped_ptr<cc::AnimationCurve> FakeFloatAnimationCurve::clone() const
{
    return make_scoped_ptr(new FakeFloatAnimationCurve).PassAs<cc::AnimationCurve>();
}

FakeTransformTransition::FakeTransformTransition(double duration)
    : m_duration(duration)
{
}

FakeTransformTransition::~FakeTransformTransition()
{
}

double FakeTransformTransition::duration() const
{
    return m_duration;
}

WebKit::WebTransformationMatrix FakeTransformTransition::getValue(double time) const
{
    return WebKit::WebTransformationMatrix();
}

scoped_ptr<cc::AnimationCurve> FakeTransformTransition::clone() const
{
    return make_scoped_ptr(new FakeTransformTransition(*this)).PassAs<cc::AnimationCurve>();
}

FakeFloatTransition::FakeFloatTransition(double duration, float from, float to)
    : m_duration(duration)
    , m_from(from)
    , m_to(to)
{
}

FakeFloatTransition::~FakeFloatTransition()
{
}

double FakeFloatTransition::duration() const
{
    return m_duration;
}

float FakeFloatTransition::getValue(double time) const
{
    time /= m_duration;
    if (time >= 1)
        time = 1;
    return (1 - time) * m_from + time * m_to;
}

FakeLayerAnimationControllerClient::FakeLayerAnimationControllerClient()
    : m_opacity(0)
{
}

FakeLayerAnimationControllerClient::~FakeLayerAnimationControllerClient()
{
}

int FakeLayerAnimationControllerClient::id() const
{
    return 0;
}

void FakeLayerAnimationControllerClient::setOpacityFromAnimation(float opacity)
{
    m_opacity = opacity;
}

float FakeLayerAnimationControllerClient::opacity() const
{
    return m_opacity;
}

void FakeLayerAnimationControllerClient::setTransformFromAnimation(const WebKit::WebTransformationMatrix& transform)
{
    m_transform = transform;
}

const WebKit::WebTransformationMatrix& FakeLayerAnimationControllerClient::transform() const
{
    return m_transform;
}

scoped_ptr<cc::AnimationCurve> FakeFloatTransition::clone() const
{
    return make_scoped_ptr(new FakeFloatTransition(*this)).PassAs<cc::AnimationCurve>();
}

int addOpacityTransitionToController(cc::LayerAnimationController& controller, double duration, float startOpacity, float endOpacity, bool useTimingFunction)
{
    return addOpacityTransition(controller, duration, startOpacity, endOpacity, useTimingFunction);
}

int addAnimatedTransformToController(cc::LayerAnimationController& controller, double duration, int deltaX, int deltaY)
{
    return addAnimatedTransform(controller, duration, deltaX, deltaY);
}

int addOpacityTransitionToLayer(cc::Layer& layer, double duration, float startOpacity, float endOpacity, bool useTimingFunction)
{
    return addOpacityTransition(layer, duration, startOpacity, endOpacity, useTimingFunction);
}

int addOpacityTransitionToLayer(cc::LayerImpl& layer, double duration, float startOpacity, float endOpacity, bool useTimingFunction)
{
    return addOpacityTransition(*layer.layerAnimationController(), duration, startOpacity, endOpacity, useTimingFunction);
}

int addAnimatedTransformToLayer(cc::Layer& layer, double duration, int deltaX, int deltaY)
{
    return addAnimatedTransform(layer, duration, deltaX, deltaY);
}

int addAnimatedTransformToLayer(cc::LayerImpl& layer, double duration, int deltaX, int deltaY)
{
    return addAnimatedTransform(*layer.layerAnimationController(), duration, deltaX, deltaY);
}

} // namespace WebKitTests


text:
<?php

namespace Extia\Bundle\DocumentBundle\Model;

use Extia\Bundle\DocumentBundle\Model\om\BaseDocumentQuery;

class DocumentQuery extends BaseDocumentQuery
{
}

redpajama_set_name: RedPajamaGithub


text:
// Copyright (c) 2002-2013, Boyce Griffith
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//    * Redistributions of source code must retain the above copyright notice,
//      this list of conditions and the following disclaimer.
//
//    * Redistributions in binary form must reproduce the above copyright
//      notice, this list of conditions and the following disclaimer in the
//      documentation and/or other materials provided with the distribution.
//
//    * Neither the name of New York University nor the names of its
//      contributors may be used to endorse or promote products derived from
//      this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

// Config files
#include <IBAMR_prefix_config.h>
#include <IBTK_prefix_config.h>
#include <SAMRAI_config.h>

// Headers for basic PETSc functions
#include <petscsys.h>

// Headers for basic SAMRAI objects
#include <BergerRigoutsos.h>
#include <CartesianGridGeometry.h>
#include <LoadBalancer.h>
#include <StandardTagAndInitialize.h>

// Headers for application-specific algorithm/data structure objects
#include <ibamr/AdvDiffPredictorCorrectorHierarchyIntegrator.h>
#include <ibamr/AdvDiffSemiImplicitHierarchyIntegrator.h>
#include <ibamr/INSCollocatedHierarchyIntegrator.h>
#include <ibamr/INSStaggeredHierarchyIntegrator.h>
#include <ibamr/app_namespaces.h>
#include <ibtk/AppInitializer.h>
#include <ibtk/muParserCartGridFunction.h>
#include <ibtk/muParserRobinBcCoefs.h>

#include "BoussinesqForcing.h"

/*******************************************************************************
 * For each run, the input filename and restart information (if needed) must   *
 * be given on the command line.  For non-restarted case, command line is:     *
 *                                                                             *
 *    executable <input file name>                                             *
 *                                                                             *
 * For restarted run, command line is:                                         *
 *                                                                             *
 *    executable <input file name> <restart directory> <restart number>        *
 *                                                                             *
 *******************************************************************************/
int
main(
    int argc,
    char* argv[])
{
    // Initialize PETSc, MPI, and SAMRAI.
    PetscInitialize(&argc,&argv,NULL,NULL);
    SAMRAI_MPI::setCommunicator(PETSC_COMM_WORLD);
    SAMRAI_MPI::setCallAbortInSerialInsteadOfExit();
    SAMRAIManager::startup();

    {// cleanup dynamically allocated objects prior to shutdown

        // Parse command line options, set some standard options from the input
        // file, initialize the restart database (if this is a restarted run),
        // and enable file logging.
        Pointer<AppInitializer> app_initializer = new AppInitializer(argc, argv, "INS.log");
        Pointer<Database> input_db = app_initializer->getInputDatabase();

        // Get various standard options set in the input file.
        const bool dump_viz_data = app_initializer->dumpVizData();
        const int viz_dump_interval = app_initializer->getVizDumpInterval();
        const bool uses_visit = dump_viz_data && app_initializer->getVisItDataWriter();

        const bool dump_restart_data = app_initializer->dumpRestartData();
        const int restart_dump_interval = app_initializer->getRestartDumpInterval();
        const string restart_dump_dirname = app_initializer->getRestartDumpDirectory();

        const bool dump_timer_data = app_initializer->dumpTimerData();
        const int timer_dump_interval = app_initializer->getTimerDumpInterval();

        Pointer<Database> main_db = app_initializer->getComponentDatabase("Main");

        // Create major algorithm and data objects that comprise the
        // application.  These objects are configured from the input database
        // and, if this is a restarted run, from the restart database.
        Pointer<INSHierarchyIntegrator> time_integrator;
        const string ins_solver_type = main_db->getStringWithDefault("ins_solver_type", "STAGGERED");
        if (ins_solver_type == "STAGGERED")
        {
            time_integrator = new INSStaggeredHierarchyIntegrator("INSStaggeredHierarchyIntegrator", app_initializer->getComponentDatabase("INSStaggeredHierarchyIntegrator"));
        }
        else if (ins_solver_type == "COLLOCATED")
        {
            time_integrator = new INSCollocatedHierarchyIntegrator("INSCollocatedHierarchyIntegrator", app_initializer->getComponentDatabase("INSCollocatedHierarchyIntegrator"));
        }
        else
        {
            TBOX_ERROR("Unsupported solver type: " << ins_solver_type << "\n" <<
                       "Valid options are: COLLOCATED, STAGGERED");
        }
        Pointer<AdvDiffHierarchyIntegrator> adv_diff_integrator;
        const string adv_diff_solver_type = main_db->getStringWithDefault("adv_diff_solver_type", "PREDICTOR_CORRECTOR");
        if (adv_diff_solver_type == "PREDICTOR_CORRECTOR")
        {
            Pointer<AdvectorExplicitPredictorStrategy> predictor = new AdvectorExplicitPredictorStrategy("AdvectorExplicitPredictorStrategy", app_initializer->getComponentDatabase("AdvectorExplicitPredictorStrategy"));
            adv_diff_integrator = new AdvDiffPredictorCorrectorHierarchyIntegrator("AdvDiffPredictorCorrectorHierarchyIntegrator", app_initializer->getComponentDatabase("AdvDiffPredictorCorrectorHierarchyIntegrator"), predictor);
        }
        else if (adv_diff_solver_type == "SEMI_IMPLICIT")
        {
            adv_diff_integrator = new AdvDiffSemiImplicitHierarchyIntegrator("AdvDiffSemiImplicitHierarchyIntegrator", app_initializer->getComponentDatabase("AdvDiffSemiImplicitHierarchyIntegrator"));
        }
        else
        {
            TBOX_ERROR("Unsupported solver type: " << adv_diff_solver_type << "\n" <<
                       "Valid options are: PREDICTOR_CORRECTOR, SEMI_IMPLICIT");
        }
        time_integrator->registerAdvDiffHierarchyIntegrator(adv_diff_integrator);
        Pointer<CartesianGridGeometry<NDIM> > grid_geometry = new CartesianGridGeometry<NDIM>("CartesianGeometry", app_initializer->getComponentDatabase("CartesianGeometry"));
        const bool periodic_domain = grid_geometry->getPeriodicShift().min() > 0;
        Pointer<PatchHierarchy<NDIM> > patch_hierarchy = new PatchHierarchy<NDIM>("PatchHierarchy", grid_geometry);
        Pointer<StandardTagAndInitialize<NDIM> > error_detector = new StandardTagAndInitialize<NDIM>("StandardTagAndInitialize", time_integrator, app_initializer->getComponentDatabase("StandardTagAndInitialize"));
        Pointer<BergerRigoutsos<NDIM> > box_generator = new BergerRigoutsos<NDIM>();
        Pointer<LoadBalancer<NDIM> > load_balancer = new LoadBalancer<NDIM>("LoadBalancer", app_initializer->getComponentDatabase("LoadBalancer"));
        Pointer<GriddingAlgorithm<NDIM> > gridding_algorithm = new GriddingAlgorithm<NDIM>("GriddingAlgorithm", app_initializer->getComponentDatabase("GriddingAlgorithm"), error_detector, box_generator, load_balancer);

        // Setup the advected and diffused quantity.
        Pointer<CellVariable<NDIM,double> > T_var = new CellVariable<NDIM,double>("T");
        adv_diff_integrator->registerTransportedQuantity(T_var);
        adv_diff_integrator->setDiffusionCoefficient(T_var, input_db->getDouble("KAPPA"));
        adv_diff_integrator->setInitialConditions(T_var, new muParserCartGridFunction("T_init", app_initializer->getComponentDatabase("TemperatureInitialConditions"), grid_geometry));
        RobinBcCoefStrategy<NDIM>* T_bc_coef = NULL;
        if (!periodic_domain)
        {
            T_bc_coef = new muParserRobinBcCoefs("T_bc_coef", app_initializer->getComponentDatabase("TemperatureBcCoefs"), grid_geometry);
            adv_diff_integrator->setPhysicalBcCoef(T_var, T_bc_coef);
        }
        adv_diff_integrator->setAdvectionVelocity(T_var, time_integrator->getAdvectionVelocityVariable());

        // Set up the fluid solver.
        time_integrator->registerBodyForceFunction(new BoussinesqForcing(T_var, adv_diff_integrator, input_db->getDouble("GAMMA")));
        vector<RobinBcCoefStrategy<NDIM>*> u_bc_coefs(NDIM); for (unsigned int d = 0; d < NDIM; ++d) u_bc_coefs[d] = NULL;
        if (!periodic_domain)
        {
            for (unsigned int d = 0; d < NDIM; ++d)
            {
                ostringstream bc_coefs_name_stream;
                bc_coefs_name_stream << "u_bc_coefs_" << d;
                const string bc_coefs_name = bc_coefs_name_stream.str();
                ostringstream bc_coefs_db_name_stream;
                bc_coefs_db_name_stream << "VelocityBcCoefs_" << d;
                const string bc_coefs_db_name = bc_coefs_db_name_stream.str();
                u_bc_coefs[d] = new muParserRobinBcCoefs(bc_coefs_name, app_initializer->getComponentDatabase(bc_coefs_db_name), grid_geometry);
            }
            time_integrator->registerPhysicalBoundaryConditions(u_bc_coefs);
        }

        // Set up visualization plot file writers.
        Pointer<VisItDataWriter<NDIM> > visit_data_writer = app_initializer->getVisItDataWriter();
        if (uses_visit)
        {
            time_integrator->registerVisItDataWriter(visit_data_writer);
        }

        // Initialize hierarchy configuration and data on all patches.
        time_integrator->initializePatchHierarchy(patch_hierarchy, gridding_algorithm);

        // Deallocate initialization objects.
        app_initializer.setNull();

        // Print the input database contents to the log file.
        plog << "Input database:\n";
        input_db->printClassData(plog);

        // Write out initial visualization data.
        int iteration_num = time_integrator->getIntegratorStep();
        double loop_time = time_integrator->getIntegratorTime();
        if (dump_viz_data && uses_visit)
        {
            pout << "\n\nWriting visualization files...\n\n";
            time_integrator->setupPlotData();
            visit_data_writer->writePlotData(patch_hierarchy, iteration_num, loop_time);
        }

        // Main time step loop.
        double loop_time_end = time_integrator->getEndTime();
        double dt = 0.0;
        while (!MathUtilities<double>::equalEps(loop_time,loop_time_end) && time_integrator->stepsRemaining())
        {
            iteration_num = time_integrator->getIntegratorStep();
            loop_time = time_integrator->getIntegratorTime();

            pout <<                                                    "\n";
            pout << "+++++++++++++++++++++++++++++++++++++++++++++++++++\n";
            pout << "At beginning of timestep # " <<  iteration_num << "\n";
            pout << "Simulation time is " << loop_time              << "\n";

            dt = time_integrator->getMaximumTimeStepSize();
            time_integrator->advanceHierarchy(dt);
            loop_time += dt;

            pout <<                                                    "\n";
            pout << "At end       of timestep # " <<  iteration_num << "\n";
            pout << "Simulation time is " << loop_time              << "\n";
            pout << "+++++++++++++++++++++++++++++++++++++++++++++++++++\n";
            pout <<                                                    "\n";

            // At specified intervals, write visualization and restart files,
            // print out timer data, and store hierarchy data for post
            // processing.
            iteration_num += 1;
            const bool last_step = !time_integrator->stepsRemaining();
            if (dump_viz_data && uses_visit && (iteration_num%viz_dump_interval == 0 || last_step))
            {
                pout << "\nWriting visualization files...\n\n";
                time_integrator->setupPlotData();
                visit_data_writer->writePlotData(patch_hierarchy, iteration_num, loop_time);
            }
            if (dump_restart_data && (iteration_num%restart_dump_interval == 0 || last_step))
            {
                pout << "\nWriting restart files...\n\n";
                RestartManager::getManager()->writeRestartFile(restart_dump_dirname, iteration_num);
            }
            if (dump_timer_data && (iteration_num%timer_dump_interval == 0 || last_step))
            {
                pout << "\nWriting timer data...\n\n";
                TimerManager::getManager()->print(plog);
            }
        }

        // Cleanup boundary condition specification objects (when necessary).
        for (unsigned int d = 0; d < NDIM; ++d) delete u_bc_coefs[d];
        delete T_bc_coef;

    }// cleanup dynamically allocated objects prior to shutdown

    SAMRAIManager::shutdown();
    PetscFinalize();
    return 0;
}// main


text:
redditp
=======

A full screen reddit presentation or slide show.

http://github.com/utopiabound/redditp

Useable Links:
https://utopiabound.github.io/redditp/?/r/popular
https://redditp.utopiabound.net/

Fork from Ubershmekel's

http://redditp.com

Hotkeys
-------

* space - toggles auto-next (play/pause)
* t - collapse/uncollapse title
* c - collapse/uncollapse controls
* i - open image in a new tab
* o - open comments in a new tab
* d - open duplicates in a new tab
* u - hide/show duplciates box
* f - toggle full screen mode
* m - unmute/mute videos
* n - toggle nsfw
* s - load images from comments
* Arrow keys, pgup/pgdown change slides
    * Up/Down, page-up / page-down - switch Albums
    * left/right - switch pictures within albums (and also to next/previous album)
* Swipe gestures on phones
* enter - play embeded

Features
--------

* All /r/ subreddits, including different ?sort stuff.
* /user/ , /domain/ , /me/ url's work.
* Url's ending with ['.jpg', '.jpeg', '.gif', '.bmp', '.png'], or URLs from parsable domains
* Video support (either direct or embeded)
* Autonext waits for the end of a video (does not work for gif, but does work for gifv)
* Parsing for a collection of domains including: (see createDiv() and processPhoto() for complete list)
* Special User / Album browsing in addition to reddit.com:
	* Imgur		(User/Tag/Trending support)  /imgur/[u/*USER*|t/*TAG*]
	* Tumblr	(Album support) /tumblr/*HOSTNAME*
	* WordPress	(Album support) /wp/*HOSTNAME* (both self, and wp hosted)
	* Gfycat	(User/Tag/Trending support) /gfycat/[u/*USER*|t/*TAG*]
	* Blogger	(Album support) /blogger/*HOSTNAME*
	* Flickr	(User/Tag/Search/Trending support) /flickr/[u/*USER*[/*ALBUM*]|t/*TAG*[,*tag2*...]|s/*SEARCH*]
* Deduplication support when browsing mulitple reddits (e.g. a multireddit /user/NAME/m/MULTIREDDIT or /r/funny+pics)
* Albums will display inline for subreddits
* You can save the html file locally and use it, just make sure you add a separator e.g. the question mark in file:///path/to/redditp/index.html?/r/gifs so the browser knows to pick up the right file and go to the right subreddit.
* Support for /r/random, /r/randnsfw, /r/popular virtual subreddits
* Albums/Video/More in comments will be detected in title and automatically found
* For subreddits that have "requests", responses will be shown as albums, also 'PsBattles:' is similarly special cased
* Works on iOS 9+ and modern browsers

Possible future features, depending on feedback:
* Zoom/Pan for comics

URLs
----

## Reddit Specific:
* /r/*SUBREDDIT*
* /r/*SUB1*+*SUB2...*
* /r/randnsfw
* /r/random
* /r/all
* /r/popular
* /  - will be /r/popular, or homepage if logged in
* /domain/DOMAIN

### Reddit URL Suffixes:
These are available from the popup menu
* /.../new
* /.../top
* /.../rising
* /.../controversial

### Reddit Users
* /user/USER/submitted (also /u/USER/submitted)
* /user/USER/m/MULTIREDDIT

## Other Services:
* /imgur/			Popular Imgur Items
* /imgur/u/USER			Images from that USER
* /imgur/t/TAG			Items with that TAG
* /gfycat				Trending gfycat items
* /gfycat/u/USER		Gfycat items from that USER
* /gfycat/t/TAG		Gfycat items with that TAG
* /wp/HOSTNAME		(with or without .wordpress.com)
* /wp2/HOSTNAME		(fqdn of Self-hosted wordpress site aka API version 2)
* /tumblr/HOSTNAME	(with or without .tumblr.com)
* /blogger/HOSTNAME	(fqdn of blogger hosted site)
* /flickr/USER[/ALBUM] (username of flickr user)
* /iloopit/[u/USER|t/TAG]

### Blog Order (Tumblr, WordPress, WordPress (v2)):
These are available from the popup menu
* /.../new
* /.../old

Installation
------------
* Can be setup to use base url:

Just git checkout in /PATH/TO/, and then setup an apache .conf file as below:

        <VirtualHost *:80>
        	ServerName redditp.example.com
        	DocumentRoot "/PATH/TO/redditp"
        	ServerAdmin hostmaster@example.com
        	<Location />
        		Order allow,deny
        		Allow from all
        		Deny from none
        	</Location>
        </VirtualHost>

Access via:

http://redditp.example.com/r/popular

* Can be setup in subdirectory without rewriting

Checkout in a directory available via the web, or have an Alias added to apache:

        Alias /redditp /PATH/TO/redditp

Access via standard CGI format:

https://utopiabound.github.io/redditp/?/r/popular or
https://utopiabound.github.io/redditp/index.html?/r/popular

Known Issues
------------

* access via http://HOST/redditp/r/aww fails due to the rewrite rules

Credits
----------

* Ubershmekel http://yuvalg.com/
* [js-cookie](https://github.com/js-cookie/js-cookie) for managing cookies
* Favicon by Double-J designs http://www.iconfinder.com/icondetails/68600/64/_icon
* Slideshow based on http://demo.marcofolio.net/fullscreen_image_slider/
* Author of slideshow base: Marco Kuiper (http://www.marcofolio.net/)
* Touch screen swipe code: Andreas Waltl, netCU Internetagentur (http://www.netcu.de)
* Loglevel v1.5.1: Tim Perry https://github.com/pimterry/loglevel


text:
angular.module( 'esri-geocoder', [] )

// ESRI geocoder API
// https://developers.arcgis.com/rest/geocode/api-reference/overview-world-geocoding-service.htm
.factory( 'geocoder', [ '$http', '$q',
function(                $http ,  $q ) {

	return ({
		// https://developers.arcgis.com/rest/geocode/api-reference/geocoding-find-address-candidates.htm
		'findAddressCandidates': function findAddressCandidates( params ) {
			angular.extend( params, {
				forStorage: false,
				f: 'json'
			});

			var defer = $q.defer();

			$http.get( '//geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates', {
				params: params,
				cache: true
			})
			.success(function( data ) {
				defer.resolve( data );
			})
			.error(function( data, status ) {
				defer.reject( status );
			});

			return defer.promise;
		}
	});
}])
;


text:
<?php

/**
 * Collection Class
 *
 * @package ValidForm
 * @author Robin van Baalen\
 */
class VF_Collection implements Iterator {
	protected $collection = array();
	private $isSeek = FALSE;

	/**
	 * Constructor method
	 *
	 * @param array $initArray
	 */
	public function __construct($initArray = array()) {
	   if (is_array($initArray)) {
		   $this->collection = $initArray;
	   }
	}

    /**
     * Add object to the collection
     *
     * @param object The object
     * @param boolean Add object to beginning of array or not
     */
    public function addObject($value, $blnAddToBeginning = FALSE) {
        if ($blnAddToBeginning) {
            array_unshift($this->collection, $value);
        } else {
            array_push($this->collection, $value);
        }
    }

    /**
     * Add object to the collection at a specified position
     *
     * @param object $value The object
     * @param integer $intPosition The position the object should be placed at.
     */
    public function addObjectAtPosition($value, $intPosition) {
    	$arrTempCollection = array();
    	$intCount = 0;

    	if ($intPosition >= $this->count()) {
    		//*** Position is greater than the collection count. Just add at the end.
    		$this->addObject($value);
    	} else {
	    	foreach ($this->collection as $varObject) {
	    		if ($intCount == $intPosition) {
	    			//*** Insert the new object.
	    			array_push($arrTempCollection, $value);
	    		}

	    		//*** Insert the existing object.
	    		array_push($arrTempCollection, $varObject);
	    		$intCount++;
	    	}

	    	//*** Replace the collection.
	    	$this->collection = $arrTempCollection;
    	}
    }

    /**
     * Add objects to the collection
     *
     * @param array An array of items / collection of objects to be added
     * @param boolean Add objects to beginning of array or not
     */
    public function addObjects($arrObjects, $blnAddToBeginning = FALSE) {
        foreach ($arrObjects as $varObject) {
            $this->addObject($varObject, $blnAddToBeginning);
        }
    }

	/**
	 * Advance internal pointer to a specific index
	 *
	 * @param integer $intPosition
	 */
	public function seek($intPosition) {
        if (is_numeric($intPosition) && $intPosition < count($this->collection)) {
        	reset($this->collection);
			while($intPosition < key($this->collection)) {
				next($this->collection);
			}
        }

		$this->isSeek = TRUE;
	}

	/**
	 * Pick a random child element
	 */
    public function random() {
    	$objReturn = null;

    	$intIndex = rand(0, (count($this->collection) - 1));
    	if (isset($this->collection[$intIndex])) {
			$objReturn = $this->collection[$intIndex];
    	}

    	return $objReturn;
    }

    /**
     * Randomize the collection
     */
    public function randomize() {
		shuffle($this->collection);
    }

	/**
	 * Get the item count.
	 */
	public function count() {
		return count($this->collection);
	}

	/**
	 * Get the current item from the collection.
	 */
    public function current() {
        return current($this->collection);
    }

	/**
	 * Place the pointer one item forward and return the item.
	 */
    public function next() {
        return next($this->collection);
    }

	/**
	 * Place the pointer one item back and return the item.
	 */
    public function previous() {
        return prev($this->collection);
    }

	/**
	 * Get the current position of the pointer.
	 */
    public function key() {
        return key($this->collection);
    }

	/**
	 * Check if the pointer is at the first record.
	 */
    public function isFirst() {
        return key($this->collection) == 0;
    }

	/**
	 * Check if the pointer is at the last record.
	 */
    public function isLast() {
        return key($this->collection) == (count($this->collection) - 1);
    }

    /**
     * Get first element in collection
     * @return mixed Returns first element in collection, null if collection is empty
     */
    public function getFirst() {
        $varReturn = null;
        if (count($this->collection) > 0) {
            $varReturn = $this->collection[0];
        }

        return $varReturn;
    }

    /**
     * Get last element in collection
     * @param string $strType Optional type to search for
     * @return mixed Returns last element in collection, null if collection is empty
     */
    public function getLast($strType = "") {
        $varReturn = null;

        if (count($this->collection) > 0) {
        	if (!empty($strType)) {
        		$arrTemp = array_reverse($this->collection);
        		foreach ($arrTemp as $object) {
        			if (get_class($object) == $strType) {
        				$varReturn = $object;
        				break;
        			}
        		}
        	} else {
            	$varReturn = $this->collection[$this->count() - 1];
        	}
        }

        return $varReturn;
    }

	/**
	 * Merge a collection with this collection.
	 */
    public function merge($collection) {
		if (is_object($collection) && $collection->count() > 0) {
        	$this->collection = array_merge($this->collection, $collection->collection);
		}
    }

	/**
	 * Test if the requested item is valid.
	 */
    public function valid() {
		return $this->current() !== FALSE;
    }

	/**
	 * Reset the internal pointer of the collection to the first item.
	 */
    public function rewind() {
		if (!$this->isSeek) {
			reset($this->collection);
		}

    	return $this;
    }

	/**
	 * Reverse the order of the collection and return it.
	 */
    public function reverse() {
		$this->collection = array_reverse($this->collection);
        return $this;
    }

	/**
	 * Set the internal pointer of the collection to the last item and return it.
	 */
    public function end() {
        return end($this->collection);
    }

    /**
     * Rebuild the collection index.
     */
    public function rebuild() {
        $this->collection = array_values($this->collection);
    }

    /**
     * Check if an object is in the collection
     *
     * @param variable $varValue
     */
    public function inCollection($varValue, $blnReturnKey = false) {
		$varReturn = FALSE;
    	foreach ($this->collection as $object) {
    		if ($object == $varValue || $varValue === get_class($object)) {
    			$varReturn = ($blnReturnKey) ? $this->key() : true;
				break;
    		}
    	}

		//*** Reset the internal pointer.
		self::rewind();

    	return $varReturn;
    }

    /**
     * Remove an element from the collection
     * @param  object $objElement The element that will be removed
     * @return boolean             Always returns true. If it couldn't be found, its gone. If the element is found, it will be removed.
     */
    public function remove($objElement) {
        $varKey = $this->inCollection($objElement, true);

        if ($varKey !== false) {
            // Element found. Now remove it.
            unset($this->collection[$varKey]);
        }

        $this->rebuild(); // Rebuild collection index.

        return true;
    }

    public function removeRecursive($objElement) {
        foreach ($this->collection as $intKey => $objValue) {
            if ($objValue->hasFields()) {
                $objValue->getFields()->removeRecursive($objElement);
            } else {
                if ($objValue->getName() == $objElement->getName()) {
                    unset($this->collection[$intKey]);
                }
            }
        }
    }
}

?>


text:
import { Component, OnInit } from '@angular/core';

import { DevicesService } from "../../services/devices.service";
import { BrowserNotificationService } from "../../services/browser-notification.service";

declare var require: any

@Component({
  selector: 'devices',
  template: require('./devices.component.html'),
  styles: [require('./devices.component.less')]
})
export class DevicesComponent implements OnInit  {

    private devices: DevicesService;
    private browserNotification: BrowserNotificationService;

    constructor(private devicesService: DevicesService, private browserNotificationService:BrowserNotificationService ) {
        this.devices = devicesService;
        this.browserNotification = browserNotificationService;
    }

    ngOnInit(): void {

    }

}


text:
package build

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"reflect"
	"testing"
	"time"

	"github.com/google/uuid"

	"github.com/openshift/origin/pkg/build/buildscheme"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/apimachinery/pkg/types"
	"k8s.io/apimachinery/pkg/util/strategicpatch"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/client-go/informers"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/kubernetes/fake"
	clientgotesting "k8s.io/client-go/testing"
	"k8s.io/client-go/tools/cache"
	"k8s.io/client-go/tools/record"

	buildv1 "github.com/openshift/api/build/v1"
	imagev1 "github.com/openshift/api/image/v1"
	buildv1client "github.com/openshift/client-go/build/clientset/versioned"
	fakebuildv1client "github.com/openshift/client-go/build/clientset/versioned/fake"
	buildv1informer "github.com/openshift/client-go/build/informers/externalversions"
	imagev1client "github.com/openshift/client-go/image/clientset/versioned"
	fakeimagev1client "github.com/openshift/client-go/image/clientset/versioned/fake"
	imagev1informer "github.com/openshift/client-go/image/informers/externalversions"

	"github.com/openshift/origin/pkg/build/buildapihelpers"
	builddefaults "github.com/openshift/origin/pkg/build/controller/build/defaults"
	buildoverrides "github.com/openshift/origin/pkg/build/controller/build/overrides"
	"github.com/openshift/origin/pkg/build/controller/common"
	"github.com/openshift/origin/pkg/build/controller/policy"
	"github.com/openshift/origin/pkg/build/controller/strategy"
	buildutil "github.com/openshift/origin/pkg/build/util"
)

const (
	dummyCA = `
	---- BEGIN CERTIFICATE ----
	VEhJUyBJUyBBIEJBRCBDRVJUSUZJQ0FURQo=
	---- END CERTIFICATE ----
	`
)

// TestHandleBuild is the main test for build updates through the controller
func TestHandleBuild(t *testing.T) {

	// patch appears to drop sub-second accuracy from times, which causes problems
	// during equality testing later, so start with a rounded number of seconds for a time.
	now := metav1.NewTime(time.Now().Round(time.Second))

	build := func(phase buildv1.BuildPhase) *buildv1.Build {
		b := dockerStrategy(mockBuild(phase, buildv1.BuildOutput{}))
		if phase != buildv1.BuildPhaseNew {
			podName := buildapihelpers.GetBuildPodName(b)
			common.SetBuildPodNameAnnotation(b, podName)
		}
		return b
	}
	pod := func(phase corev1.PodPhase) *corev1.Pod {
		p := mockBuildPod(build(buildv1.BuildPhaseNew))
		p.Status.Phase = phase
		switch phase {
		case corev1.PodRunning:
			p.Status.StartTime = &now
		case corev1.PodFailed:
			p.Status.StartTime = &now
			p.Status.ContainerStatuses = []corev1.ContainerStatus{
				{
					Name: "container",
					State: corev1.ContainerState{
						Terminated: &corev1.ContainerStateTerminated{
							ExitCode: 1,
						},
					},
				},
			}
		case corev1.PodSucceeded:
			p.Status.StartTime = &now
			p.Status.ContainerStatuses = []corev1.ContainerStatus{
				{
					Name: "container",
					State: corev1.ContainerState{
						Terminated: &corev1.ContainerStateTerminated{
							ExitCode: 0,
						},
					},
				},
			}
		}
		return p
	}
	withTerminationMessage := func(pod *corev1.Pod) *corev1.Pod {
		pod.Status.ContainerStatuses[0].State.Terminated.Message = "termination message"
		return pod
	}
	withOwnerReference := func(pod *corev1.Pod, build *buildv1.Build) *corev1.Pod {
		t := true
		pod.OwnerReferences = []metav1.OwnerReference{{
			APIVersion: buildv1.SchemeGroupVersion.String(),
			Kind:       "Build",
			Name:       build.Name,
			Controller: &t,
		}}
		return pod
	}

	cancelled := func(build *buildv1.Build) *buildv1.Build {
		build.Status.Cancelled = true
		return build
	}
	withCompletionTS := func(build *buildv1.Build) *buildv1.Build {
		build.Status.CompletionTimestamp = &now
		return build
	}
	withLogSnippet := func(build *buildv1.Build) *buildv1.Build {
		build.Status.LogSnippet = "termination message"
		return build
	}

	tests := []struct {
		name string

		// Conditions
		build                  *buildv1.Build
		pod                    *corev1.Pod
		runPolicy              *fakeRunPolicy
		errorOnPodDelete       bool
		errorOnPodCreate       bool
		errorOnBuildUpdate     bool
		errorOnConfigMapCreate bool

		// Expected Result
		expectUpdate           *buildUpdate
		expectPodCreated       bool
		expectPodDeleted       bool
		expectError            bool
		expectConfigMapCreated bool
	}{
		{
			name:  "cancel running build",
			build: cancelled(build(buildv1.BuildPhaseRunning)),
			pod:   pod(corev1.PodRunning),
			expectUpdate: newUpdate().phase(buildv1.BuildPhaseCancelled).
				reason(buildv1.StatusReasonCancelledBuild).
				message(buildutil.StatusMessageCancelledBuild).
				completionTime(now).
				startTime(now).update,
			expectPodDeleted: true,
		},
		{
			name:         "cancel build in terminal state",
			build:        cancelled(withCompletionTS(build(buildv1.BuildPhaseComplete))),
			pod:          pod(corev1.PodRunning),
			expectUpdate: nil,
		},
		{
			name:             "cancel build with delete pod error",
			build:            cancelled(build(buildv1.BuildPhaseRunning)),
			errorOnPodDelete: true,
			expectUpdate:     nil,
			expectError:      true,
		},
		{
			name:  "new -> pending",
			build: build(buildv1.BuildPhaseNew),
			expectUpdate: newUpdate().
				phase(buildv1.BuildPhasePending).
				reason("").
				message("").
				podNameAnnotation(pod(corev1.PodPending).Name).
				update,
			expectPodCreated:       true,
			expectConfigMapCreated: true,
		},
		{
			name:  "new with existing related pod",
			build: build(buildv1.BuildPhaseNew),
			pod:   withOwnerReference(pod(corev1.PodRunning), build(buildv1.BuildPhaseNew)),
			expectUpdate: newUpdate().
				phase(buildv1.BuildPhaseRunning).
				reason("").
				message("").
				startTime(now).
				podNameAnnotation(pod(corev1.PodRunning).Name).
				update,
		},
		{
			name:  "new with existing unrelated pod",
			build: build(buildv1.BuildPhaseNew),
			pod:   pod(corev1.PodRunning),
			expectUpdate: newUpdate().
				phase(buildv1.BuildPhaseError).
				reason(buildv1.StatusReasonBuildPodExists).
				message(buildutil.StatusMessageBuildPodExists).
				podNameAnnotation(pod(corev1.PodRunning).Name).
				startTime(now).
				completionTime(now).
				update,
		},
		{
			name:         "new not runnable by policy",
			build:        build(buildv1.BuildPhaseNew),
			runPolicy:    &fakeRunPolicy{notRunnable: true},
			expectUpdate: nil,
		},
		{
			name:                   "new -> pending with update error",
			build:                  build(buildv1.BuildPhaseNew),
			errorOnBuildUpdate:     true,
			expectUpdate:           nil,
			expectPodCreated:       true,
			expectConfigMapCreated: true,
			expectError:            true,
		},
		{
			name:  "pending -> running",
			build: build(buildv1.BuildPhasePending),
			pod:   pod(corev1.PodRunning),
			expectUpdate: newUpdate().
				phase(buildv1.BuildPhaseRunning).
				reason("").
				message("").
				startTime(now).
				update,
		},
		{
			name:               "pending -> running with update error",
			build:              build(buildv1.BuildPhasePending),
			pod:                pod(corev1.PodRunning),
			errorOnBuildUpdate: true,
			expectUpdate:       nil,
			expectError:        true,
		},
		{
			name:  "pending -> failed",
			build: build(buildv1.BuildPhasePending),
			pod:   pod(corev1.PodFailed),
			expectUpdate: newUpdate().
				phase(buildv1.BuildPhaseFailed).
				reason(buildv1.StatusReasonGenericBuildFailed).
				message(buildutil.StatusMessageGenericBuildFailed).
				startTime(now).
				completionTime(now).
				update,
		},
		{
			name:         "pending -> pending",
			build:        build(buildv1.BuildPhasePending),
			pod:          pod(corev1.PodPending),
			expectUpdate: nil,
		},
		{
			name:  "running -> complete",
			build: build(buildv1.BuildPhaseRunning),
			pod:   pod(corev1.PodSucceeded),
			expectUpdate: newUpdate().
				phase(buildv1.BuildPhaseComplete).
				reason("").
				message("").
				startTime(now).
				completionTime(now).
				update,
		},
		{
			name:         "running -> running",
			build:        build(buildv1.BuildPhaseRunning),
			pod:          pod(corev1.PodRunning),
			expectUpdate: nil,
		},
		{
			name:  "running with missing pod",
			build: build(buildv1.BuildPhaseRunning),
			expectUpdate: newUpdate().
				phase(buildv1.BuildPhaseError).
				reason(buildv1.StatusReasonBuildPodDeleted).
				message(buildutil.StatusMessageBuildPodDeleted).
				startTime(now).
				completionTime(now).
				update,
		},
		{
			name:  "failed -> failed with no completion timestamp",
			build: build(buildv1.BuildPhaseFailed),
			pod:   pod(corev1.PodFailed),
			expectUpdate: newUpdate().
				startTime(now).
				completionTime(now).
				update,
		},
		{
			name:  "failed -> failed with completion timestamp+message and no logsnippet",
			build: withCompletionTS(build(buildv1.BuildPhaseFailed)),
			pod:   withTerminationMessage(pod(corev1.PodFailed)),
			expectUpdate: newUpdate().
				startTime(now).
				logSnippet("termination message").
				update,
		},
		{
			name:  "failed -> failed with completion timestamp+message and logsnippet",
			build: withLogSnippet(withCompletionTS(build(buildv1.BuildPhaseFailed))),
			pod:   withTerminationMessage(pod(corev1.PodFailed)),
		},
	}

	for _, tc := range tests {
		func() {
			var patchedBuild *buildv1.Build
			var appliedPatch string
			buildClient := fakeBuildClient(tc.build)
			buildClient.(*fakebuildv1client.Clientset).PrependReactor("patch", "builds",
				func(action clientgotesting.Action) (bool, runtime.Object, error) {
					if tc.errorOnBuildUpdate {
						return true, nil, fmt.Errorf("error")
					}
					var err error
					patchAction := action.(clientgotesting.PatchActionImpl)
					appliedPatch = string(patchAction.Patch)
					patchedBuild, err = applyBuildPatch(tc.build, patchAction.Patch)
					if err != nil {
						panic(fmt.Sprintf("unexpected error: %v", err))
					}
					return true, patchedBuild, nil
				})
			var kubeClient kubernetes.Interface
			if tc.pod != nil {
				kubeClient = fakeKubeExternalClientSet(tc.pod)
			} else {
				kubeClient = fakeKubeExternalClientSet()
			}
			podCreated := false
			var newPod *corev1.Pod
			kubeClient.(*fake.Clientset).PrependReactor("delete", "pods",
				func(action clientgotesting.Action) (bool, runtime.Object, error) {
					if tc.errorOnPodDelete {
						return true, nil, fmt.Errorf("error")
					}
					return true, nil, nil
				})
			kubeClient.(*fake.Clientset).PrependReactor("create", "pods",
				func(action clientgotesting.Action) (bool, runtime.Object, error) {
					if tc.errorOnPodCreate {
						return true, nil, fmt.Errorf("error")
					}
					podCreated = true
					newPod = mockBuildPod(tc.build)
					newPod.UID = types.UID(uuid.New().String())
					return true, newPod, nil
				})
			configMapCreated := false
			kubeClient.(*fake.Clientset).PrependReactor("create", "configmaps",
				func(action clientgotesting.Action) (bool, runtime.Object, error) {
					configMapCreated = true
					newConfigMap := mockBuildCAConfigMap(tc.build, newPod)
					return true, newConfigMap, nil
				})
			bc := newFakeBuildController(buildClient, nil, kubeClient, nil)
			defer bc.stop()

			runPolicy := tc.runPolicy
			if runPolicy == nil {
				runPolicy = &fakeRunPolicy{}
			}
			bc.runPolicies = []policy.RunPolicy{runPolicy}

			err := bc.handleBuild(tc.build)
			if err != nil {
				if !tc.expectError {
					t.Errorf("%s: unexpected error: %v", tc.name, err)
				}
			}
			if err == nil && tc.expectError {
				t.Errorf("%s: expected error, got none", tc.name)
			}
			if tc.expectUpdate == nil && patchedBuild != nil {
				t.Errorf("%s: did not expect a build update, got patch %s", tc.name, appliedPatch)
			}
			if tc.expectPodCreated != podCreated {
				t.Errorf("%s: pod created. expected: %v, actual: %v", tc.name, tc.expectPodCreated, podCreated)
			}
			if tc.expectConfigMapCreated != configMapCreated {
				t.Errorf("%s: configMap created. expected: %v, actual:%v", tc.name, tc.expectConfigMapCreated, configMapCreated)
			}
			if tc.expectUpdate != nil {
				if patchedBuild == nil {
					t.Errorf("%s: did not get an update. Expected: %v", tc.name, tc.expectUpdate)
					return
				}
				expectedBuild := tc.build.DeepCopy()
				tc.expectUpdate.apply(expectedBuild)

				// For start/completion/duration fields, simply validate that they are set/not set
				if tc.expectUpdate.startTime != nil && patchedBuild.Status.StartTimestamp != nil {
					expectedBuild.Status.StartTimestamp = patchedBuild.Status.StartTimestamp
				}
				if tc.expectUpdate.completionTime != nil && patchedBuild.Status.CompletionTimestamp != nil {
					expectedBuild.Status.CompletionTimestamp = patchedBuild.Status.CompletionTimestamp
					expectedBuild.Status.Duration = patchedBuild.Status.Duration
				}
				expectedBuild.CreationTimestamp = patchedBuild.CreationTimestamp

				// TODO: For some reason the external builds does not with with this check. The output is correct, we should investigate later.
				/*
					if !apiequality.Semantic.DeepEqual(*expectedBuild, *patchedBuild) {
						t.Errorf("%s: did not get expected update on build. \nUpdate: %v\nPatch: %s\n", tc.name, tc.expectUpdate, appliedPatch)
					}
				*/
			}
		}()
	}

}

// TestWork - High-level test of the work function to ensure that a build
// in the queue will be handled by updating the build status to pending
func TestWorkWithNewBuild(t *testing.T) {
	build := dockerStrategy(mockBuild(buildv1.BuildPhaseNew, buildv1.BuildOutput{}))
	var patchedBuild *buildv1.Build
	buildClient := fakeBuildClient(build)
	buildClient.(*fakebuildv1client.Clientset).PrependReactor("patch", "builds", applyBuildPatchReaction(t, build, &patchedBuild))

	bc := newFakeBuildController(buildClient, nil, nil, nil)
	defer bc.stop()
	bc.enqueueBuild(build)

	bc.buildWork()

	if bc.buildQueue.Len() > 0 {
		t.Errorf("Expected queue to be empty")
	}
	if patchedBuild == nil {
		t.Errorf("Expected patched build not to be nil")
	}

	if patchedBuild != nil && patchedBuild.Status.Phase != buildv1.BuildPhasePending {
		t.Errorf("Expected patched build status set to Pending. It is %s", patchedBuild.Status.Phase)
	}
}

func TestCreateBuildPod(t *testing.T) {
	kubeClient := fakeKubeExternalClientSet()
	bc := newFakeBuildController(nil, nil, kubeClient, nil)
	defer bc.stop()
	build := dockerStrategy(mockBuild(buildv1.BuildPhaseNew, buildv1.BuildOutput{}))

	update, err := bc.createBuildPod(build)

	if err != nil {
		t.Errorf("unexpected error: %v", err)
		return
	}
	podName := buildapihelpers.GetBuildPodName(build)
	// Validate update
	expected := &buildUpdate{}
	expected.setPodNameAnnotation(podName)
	expected.setPhase(buildv1.BuildPhasePending)
	expected.setReason("")
	expected.setMessage("")
	validateUpdate(t, "create build pod", expected, update)
	// Make sure that a pod was created
	pod, err := kubeClient.Core().Pods("namespace").Get(podName, metav1.GetOptions{})
	if err != nil {
		t.Errorf("unexpected error: %v", err)
	}
	// Make sure that a configMap was created, with an ownerRef
	configMapName := buildapihelpers.GetBuildCAConfigMapName(build)
	configMap, err := kubeClient.Core().ConfigMaps("namespace").Get(configMapName, metav1.GetOptions{})
	if err != nil {
		t.Errorf("unexpected error: %v", err)
	}
	if configMap == nil {
		// ConfigMap was not found
		return
	}
	if len(configMap.ObjectMeta.OwnerReferences) == 0 {
		t.Errorf("expected configMap %s to have an owner reference", configMapName)
	}
	foundOwner := false
	for _, o := range configMap.OwnerReferences {
		if o.Name == pod.Name {
			foundOwner = true
			break
		}
	}
	if !foundOwner {
		t.Errorf("expected configMap %s to reference owner %s", configMapName, podName)
	}
	// Make sure that the pod references the configMap
	foundVolume := false
	for _, v := range pod.Spec.Volumes {
		if v.ConfigMap != nil && v.ConfigMap.Name == configMapName {
			foundVolume = true
			break
		}
	}
	if !foundVolume {
		t.Errorf("configMap %s should exist exist as a volume in the build pod, but was not found.", configMapName)
	}
}

func TestCreateBuildPodWithImageStreamOutput(t *testing.T) {
	imageStream := &imagev1.ImageStream{}
	imageStream.Namespace = "isnamespace"
	imageStream.Name = "isname"
	imageStream.Status.DockerImageRepository = "namespace/image-name"
	imageClient := fakeImageClient(imageStream)
	imageStreamRef := &corev1.ObjectReference{Name: "isname:latest", Namespace: "isnamespace", Kind: "ImageStreamTag"}
	bc := newFakeBuildController(nil, imageClient, nil, nil)
	defer bc.stop()
	build := dockerStrategy(mockBuild(buildv1.BuildPhaseNew, buildv1.BuildOutput{To: imageStreamRef, PushSecret: &corev1.LocalObjectReference{}}))
	podName := buildapihelpers.GetBuildPodName(build)

	update, err := bc.createBuildPod(build)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	expected := &buildUpdate{}
	expected.setPodNameAnnotation(podName)
	expected.setPhase(buildv1.BuildPhasePending)
	expected.setReason("")
	expected.setMessage("")
	expected.setOutputRef("namespace/image-name:latest")
	validateUpdate(t, "create build pod with imagestream output", expected, update)
	if len(bc.imageStreamQueue.Pop("isnamespace/isname")) > 0 {
		t.Errorf("should not have queued build update")
	}
}

func TestCreateBuildPodWithOutputImageStreamMissing(t *testing.T) {
	imageStreamRef := &corev1.ObjectReference{Name: "isname:latest", Namespace: "isnamespace", Kind: "ImageStreamTag"}
	bc := newFakeBuildController(nil, nil, nil, nil)
	defer bc.stop()
	build := dockerStrategy(mockBuild(buildv1.BuildPhaseNew, buildv1.BuildOutput{To: imageStreamRef, PushSecret: &corev1.LocalObjectReference{}}))

	update, err := bc.createBuildPod(build)

	if err != nil {
		t.Fatalf("Expected no error")
	}
	expected := &buildUpdate{}
	expected.setReason(buildv1.StatusReasonInvalidOutputReference)
	expected.setMessage(buildutil.StatusMessageInvalidOutputRef)
	validateUpdate(t, "create build pod with image stream error", expected, update)
	if !reflect.DeepEqual(bc.imageStreamQueue.Pop("isnamespace/isname"), []string{"namespace/data-build"}) {
		t.Errorf("should have queued build update: %#v", bc.imageStreamQueue)
	}
}

func TestCreateBuildPodWithImageStreamMissing(t *testing.T) {
	imageStreamRef := &corev1.ObjectReference{Name: "isname:latest", Kind: "DockerImage"}
	bc := newFakeBuildController(nil, nil, nil, nil)
	defer bc.stop()
	build := dockerStrategy(mockBuild(buildv1.BuildPhaseNew, buildv1.BuildOutput{To: imageStreamRef, PushSecret: &corev1.LocalObjectReference{}}))
	build.Spec.Strategy.DockerStrategy.From = &corev1.ObjectReference{Kind: "ImageStreamTag", Name: "isname:latest"}

	update, err := bc.createBuildPod(build)
	if err != nil {
		t.Fatalf("Expected no error: %v", err)
	}
	expected := &buildUpdate{}
	expected.setReason(buildv1.StatusReasonInvalidImageReference)
	expected.setMessage(buildutil.StatusMessageInvalidImageRef)
	validateUpdate(t, "create build pod with image stream error", expected, update)
	if !reflect.DeepEqual(bc.imageStreamQueue.Pop("namespace/isname"), []string{"namespace/data-build"}) {
		t.Errorf("should have queued build update: %#v", bc.imageStreamQueue)
	}
}

func TestCreateBuildPodWithImageStreamUnresolved(t *testing.T) {
	imageStream := &imagev1.ImageStream{}
	imageStream.Namespace = "isnamespace"
	imageStream.Name = "isname"
	imageStream.Status.DockerImageRepository = ""
	imageClient := fakeImageClient(imageStream)
	imageStreamRef := &corev1.ObjectReference{Name: "isname:latest", Namespace: "isnamespace", Kind: "ImageStreamTag"}
	bc := newFakeBuildController(nil, imageClient, nil, nil)
	defer bc.stop()
	build := dockerStrategy(mockBuild(buildv1.BuildPhaseNew, buildv1.BuildOutput{To: imageStreamRef, PushSecret: &corev1.LocalObjectReference{}}))

	update, err := bc.createBuildPod(build)

	if err == nil {
		t.Fatalf("Expected error")
	}
	expected := &buildUpdate{}
	expected.setReason(buildv1.StatusReasonInvalidOutputReference)
	expected.setMessage(buildutil.StatusMessageInvalidOutputRef)
	validateUpdate(t, "create build pod with image stream error", expected, update)
	if !reflect.DeepEqual(bc.imageStreamQueue.Pop("isnamespace/isname"), []string{"namespace/data-build"}) {
		t.Errorf("should have queued build update")
	}
}

type errorStrategy struct{}

func (*errorStrategy) CreateBuildPod(build *buildv1.Build, includeCA bool) (*corev1.Pod, error) {
	return nil, fmt.Errorf("error")
}

func TestCreateBuildPodWithPodSpecCreationError(t *testing.T) {
	bc := newFakeBuildController(nil, nil, nil, nil)
	defer bc.stop()
	bc.createStrategy = &errorStrategy{}
	build := dockerStrategy(mockBuild(buildv1.BuildPhaseNew, buildv1.BuildOutput{}))

	update, err := bc.createBuildPod(build)

	if err != nil {
		t.Errorf("unexpected error: %v", err)
	}
	expected := &buildUpdate{}
	expected.setReason(buildv1.StatusReasonCannotCreateBuildPodSpec)
	expected.setMessage(buildutil.StatusMessageCannotCreateBuildPodSpec)
	validateUpdate(t, "create build pod with pod spec creation error", expected, update)
}

func TestCreateBuildPodWithExistingRelatedPod(t *testing.T) {
	tru := true
	build := dockerStrategy(mockBuild(buildv1.BuildPhaseNew, buildv1.BuildOutput{}))

	existingPod := &corev1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Name:      buildapihelpers.GetBuildPodName(build),
			Namespace: build.Namespace,
			UID:       types.UID(uuid.New().String()),
			OwnerReferences: []metav1.OwnerReference{
				{
					APIVersion: buildv1.SchemeGroupVersion.String(),
					Kind:       "Build",
					Name:       build.Name,
					Controller: &tru,
				},
			},
		},
	}

	kubeClient := fakeKubeExternalClientSet(existingPod)
	errorReaction := func(action clientgotesting.Action) (bool, runtime.Object, error) {
		return true, nil, errors.NewAlreadyExists(schema.GroupResource{Group: "", Resource: "pods"}, existingPod.Name)
	}
	kubeClient.(*fake.Clientset).PrependReactor("create", "pods", errorReaction)
	bc := newFakeBuildController(nil, nil, kubeClient, nil)
	bc.start()
	defer bc.stop()

	update, err := bc.createBuildPod(build)

	if err != nil {
		t.Errorf("unexpected error: %v", err)
	}

	expected := &buildUpdate{}
	expected.setPhase(buildv1.BuildPhasePending)
	expected.setReason("")
	expected.setMessage("")
	expected.setPodNameAnnotation(buildapihelpers.GetBuildPodName(build))
	validateUpdate(t, "create build pod with existing related pod error", expected, update)
}

func TestCreateBuildPodWithExistingRelatedPodMissingCA(t *testing.T) {
	tru := true
	build := dockerStrategy(mockBuild(buildv1.BuildPhaseNew, buildv1.BuildOutput{}))

	existingPod := &corev1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Name:      buildapihelpers.GetBuildPodName(build),
			Namespace: build.Namespace,
			UID:       types.UID(uuid.New().String()),
			OwnerReferences: []metav1.OwnerReference{
				{
					APIVersion: buildv1.SchemeGroupVersion.String(),
					Kind:       "Build",
					Name:       build.Name,
					Controller: &tru,
				},
			},
		},
	}
	caMapName := buildapihelpers.GetBuildCAConfigMapName(build)
	kubeClient := fakeKubeExternalClientSet(existingPod)
	errorReaction := func(action clientgotesting.Action) (bool, runtime.Object, error) {
		return true, nil, errors.NewAlreadyExists(schema.GroupResource{Group: "", Resource: "pods"}, existingPod.Name)
	}
	notFoundReaction := func(action clientgotesting.Action) (bool, runtime.Object, error) {
		return true, nil, errors.NewNotFound(schema.GroupResource{Group: "", Resource: "configmaps"}, caMapName)
	}
	kubeClient.(*fake.Clientset).PrependReactor("create", "pods", errorReaction)
	kubeClient.(*fake.Clientset).PrependReactor("get", "configmaps", notFoundReaction)

	bc := newFakeBuildController(nil, nil, kubeClient, nil)
	bc.start()
	defer bc.stop()

	update, err := bc.createBuildPod(build)

	if err != nil {
		t.Errorf("unexpected error: %v", err)
	}

	expected := &buildUpdate{}
	expected.setPhase(buildv1.BuildPhasePending)
	expected.setReason("")
	expected.setMessage("")
	expected.setPodNameAnnotation(buildapihelpers.GetBuildPodName(build))
	validateUpdate(t, "create build pod with existing related pod and missing CA configMap error", expected, update)
}

func TestCreateBuildPodWithExistingRelatedPodBadCA(t *testing.T) {
	tru := true
	build := dockerStrategy(mockBuild(buildv1.BuildPhaseNew, buildv1.BuildOutput{}))

	existingPod := &corev1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Name:      buildapihelpers.GetBuildPodName(build),
			Namespace: build.Namespace,
			UID:       types.UID(uuid.New().String()),
			OwnerReferences: []metav1.OwnerReference{
				{
					APIVersion: buildv1.SchemeGroupVersion.String(),
					Kind:       "Build",
					Name:       build.Name,
					Controller: &tru,
				},
			},
		},
	}
	badPod := mockBuildPod(build)
	existingCA := &corev1.ConfigMap{
		ObjectMeta: metav1.ObjectMeta{
			Name:      buildapihelpers.GetBuildCAConfigMapName(build),
			Namespace: build.Namespace,
			OwnerReferences: []metav1.OwnerReference{
				{
					APIVersion: "v1",
					Kind:       "Pod",
					Name:       badPod.Name,
					UID:        badPod.UID,
				},
			},
		},
	}
	kubeClient := fakeKubeExternalClientSet(existingPod)
	errorReaction := func(action clientgotesting.Action) (bool, runtime.Object, error) {
		return true, nil, errors.NewAlreadyExists(schema.GroupResource{Group: "", Resource: "pods"}, existingPod.Name)
	}
	getCAReaction := func(action clientgotesting.Action) (bool, runtime.Object, error) {
		return true, existingCA, nil
	}
	kubeClient.(*fake.Clientset).PrependReactor("create", "pods", errorReaction)
	kubeClient.(*fake.Clientset).PrependReactor("get", "configmaps", getCAReaction)

	bc := newFakeBuildController(nil, nil, kubeClient, nil)
	bc.start()
	defer bc.stop()

	update, err := bc.createBuildPod(build)

	if err == nil {
		t.Error("expected error")
	}

	expected := &buildUpdate{}
	validateUpdate(t, "create build pod with existing related pod and bad CA configMap error", expected, update)
}

func TestCreateBuildPodWithExistingUnrelatedPod(t *testing.T) {
	build := dockerStrategy(mockBuild(buildv1.BuildPhaseNew, buildv1.BuildOutput{}))

	existingPod := &corev1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Name:      buildapihelpers.GetBuildPodName(build),
			Namespace: build.Namespace,
		},
	}

	kubeClient := fakeKubeExternalClientSet(existingPod)
	errorReaction := func(action clientgotesting.Action) (bool, runtime.Object, error) {
		return true, nil, errors.NewAlreadyExists(schema.GroupResource{Group: "", Resource: "pods"}, existingPod.Name)
	}
	kubeClient.(*fake.Clientset).PrependReactor("create", "pods", errorReaction)
	bc := newFakeBuildController(nil, nil, kubeClient, nil)
	defer bc.stop()

	update, err := bc.createBuildPod(build)

	if err != nil {
		t.Errorf("unexpected error: %v", err)
	}

	expected := &buildUpdate{}
	expected.setPhase(buildv1.BuildPhaseError)
	expected.setReason(buildv1.StatusReasonBuildPodExists)
	expected.setMessage(buildutil.StatusMessageBuildPodExists)
	validateUpdate(t, "create build pod with pod with older existing pod", expected, update)
}

func TestCreateBuildPodWithPodCreationError(t *testing.T) {
	kubeClient := fakeKubeExternalClientSet()
	errorReaction := func(action clientgotesting.Action) (bool, runtime.Object, error) {
		return true, nil, fmt.Errorf("error")
	}
	kubeClient.(*fake.Clientset).PrependReactor("create", "pods", errorReaction)
	bc := newFakeBuildController(nil, nil, kubeClient, nil)
	defer bc.stop()
	build := dockerStrategy(mockBuild(buildv1.BuildPhaseNew, buildv1.BuildOutput{}))

	update, err := bc.createBuildPod(build)

	if err == nil {
		t.Errorf("expected error")
	}

	expected := &buildUpdate{}
	expected.setReason(buildv1.StatusReasonCannotCreateBuildPod)
	expected.setMessage(buildutil.StatusMessageCannotCreateBuildPod)
	validateUpdate(t, "create build pod with pod creation error", expected, update)
}

func TestCreateBuildPodWithCACreationError(t *testing.T) {
	kubeClient := fakeKubeExternalClientSet()
	errorReaction := func(action clientgotesting.Action) (bool, runtime.Object, error) {
		return true, nil, fmt.Errorf("error")
	}
	kubeClient.(*fake.Clientset).PrependReactor("create", "configmaps", errorReaction)
	bc := newFakeBuildController(nil, nil, kubeClient, nil)
	defer bc.stop()
	build := dockerStrategy(mockBuild(buildv1.BuildPhaseNew, buildv1.BuildOutput{}))

	update, err := bc.createBuildPod(build)

	if err == nil {
		t.Errorf("expected error")
	}

	expected := &buildUpdate{}
	expected.setReason("CannotCreateCAConfigMap")
	expected.setMessage(buildutil.StatusMessageCannotCreateCAConfigMap)
	validateUpdate(t, "create build pod with CA ConfigMap creation error", expected, update)
}

func TestCancelBuild(t *testing.T) {
	build := mockBuild(buildv1.BuildPhaseRunning, buildv1.BuildOutput{})
	build.Name = "canceltest"
	build.Namespace = "testns"
	pod := &corev1.Pod{}
	pod.Name = "canceltest-build"
	pod.Namespace = "testns"
	client := fake.NewSimpleClientset(pod).Core()
	bc := BuildController{
		podClient: client,
	}
	update, err := bc.cancelBuild(build)
	if err != nil {
		t.Errorf("unexpected error: %v", err)
	}
	if _, err := client.Pods("testns").Get("canceltest-build", metav1.GetOptions{}); err == nil {
		t.Errorf("expect pod canceltest-build to have been deleted")
	}
	if update.phase == nil || *update.phase != buildv1.BuildPhaseCancelled {
		t.Errorf("expected phase to be set to cancelled")
	}
	if update.reason == nil || *update.reason != buildv1.StatusReasonCancelledBuild {
		t.Errorf("expected status reason to be set to %s", buildv1.StatusReasonCancelledBuild)
	}
	if update.message == nil || *update.message != buildutil.StatusMessageCancelledBuild {
		t.Errorf("expected status message to be set to %s", buildutil.StatusMessageCancelledBuild)
	}
}

func TestShouldIgnore(t *testing.T) {

	setCompletionTimestamp := func(build *buildv1.Build) *buildv1.Build {
		now := metav1.Now()
		build.Status.CompletionTimestamp = &now
		return build
	}

	tests := []struct {
		name         string
		build        *buildv1.Build
		expectIgnore bool
	}{
		{
			name:         "new docker build",
			build:        dockerStrategy(mockBuild(buildv1.BuildPhaseNew, buildv1.BuildOutput{})),
			expectIgnore: false,
		},
		{
			name:         "running docker build",
			build:        dockerStrategy(mockBuild(buildv1.BuildPhaseRunning, buildv1.BuildOutput{})),
			expectIgnore: false,
		},
		{
			name:         "cancelled docker build",
			build:        dockerStrategy(mockBuild(buildv1.BuildPhaseCancelled, buildv1.BuildOutput{})),
			expectIgnore: true,
		},
		{
			name:         "completed docker build with no completion timestamp",
			build:        dockerStrategy(mockBuild(buildv1.BuildPhaseComplete, buildv1.BuildOutput{})),
			expectIgnore: false,
		},
		{
			name:         "completed docker build with completion timestamp",
			build:        setCompletionTimestamp(dockerStrategy(mockBuild(buildv1.BuildPhaseComplete, buildv1.BuildOutput{}))),
			expectIgnore: true,
		},
		{
			name:         "running pipeline build",
			build:        pipelineStrategy(mockBuild(buildv1.BuildPhaseRunning, buildv1.BuildOutput{})),
			expectIgnore: true,
		},
		{
			name:         "completed pipeline build",
			build:        pipelineStrategy(mockBuild(buildv1.BuildPhaseComplete, buildv1.BuildOutput{})),
			expectIgnore: true,
		},
	}

	for _, test := range tests {
		actual := shouldIgnore(test.build)
		if expected := test.expectIgnore; actual != expected {
			t.Errorf("%s: expected result: %v, actual: %v", test.name, expected, actual)
		}
	}

}

func TestIsValidTransition(t *testing.T) {
	phases := []buildv1.BuildPhase{
		buildv1.BuildPhaseNew,
		buildv1.BuildPhasePending,
		buildv1.BuildPhaseRunning,
		buildv1.BuildPhaseComplete,
		buildv1.BuildPhaseFailed,
		buildv1.BuildPhaseError,
		buildv1.BuildPhaseCancelled,
	}
	for _, fromPhase := range phases {
		for _, toPhase := range phases {
			if buildutil.IsTerminalPhase(fromPhase) && fromPhase != toPhase {
				if isValidTransition(fromPhase, toPhase) {
					t.Errorf("transition %v -> %v should be invalid", fromPhase, toPhase)
				}
				continue
			}
			if fromPhase == buildv1.BuildPhasePending && toPhase == buildv1.BuildPhaseNew {
				if isValidTransition(fromPhase, toPhase) {
					t.Errorf("transition %v -> %v should be invalid", fromPhase, toPhase)
				}
				continue
			}
			if fromPhase == buildv1.BuildPhaseRunning && (toPhase == buildv1.BuildPhaseNew || toPhase == buildv1.BuildPhasePending) {
				if isValidTransition(fromPhase, toPhase) {
					t.Errorf("transition %v -> %v shluld be invalid", fromPhase, toPhase)
				}
				continue
			}

			if !isValidTransition(fromPhase, toPhase) {
				t.Errorf("transition %v -> %v should be valid", fromPhase, toPhase)
			}
		}
	}
}

func TestIsTerminal(t *testing.T) {
	tests := map[buildv1.BuildPhase]bool{
		buildv1.BuildPhaseNew:       false,
		buildv1.BuildPhasePending:   false,
		buildv1.BuildPhaseRunning:   false,
		buildv1.BuildPhaseComplete:  true,
		buildv1.BuildPhaseFailed:    true,
		buildv1.BuildPhaseError:     true,
		buildv1.BuildPhaseCancelled: true,
	}
	for phase, expected := range tests {
		if actual := buildutil.IsTerminalPhase(phase); actual != expected {
			t.Errorf("unexpected response for %s: %v", phase, actual)
		}
	}
}

func TestSetBuildCompletionTimestampAndDuration(t *testing.T) {
	// set start time to 2 seconds ago to have some significant duration
	startTime := metav1.NewTime(time.Now().Add(time.Second * -2))
	earlierTime := metav1.NewTime(startTime.Add(time.Hour * -1))

	// Marker times used for validation
	afterStartTimeBeforeNow := metav1.NewTime(time.Time{})

	// Marker durations used for validation
	greaterThanZeroLessThanSinceStartTime := time.Duration(0)
	atLeastOneHour := time.Duration(0)
	zeroDuration := time.Duration(0)

	buildWithStartTime := &buildv1.Build{}
	buildWithStartTime.Status.StartTimestamp = &startTime
	buildWithNoStartTime := &buildv1.Build{}
	tests := []struct {
		name         string
		build        *buildv1.Build
		podStartTime *metav1.Time
		expected     *buildUpdate
	}{
		{
			name:         "build with start time",
			build:        buildWithStartTime,
			podStartTime: &earlierTime,
			expected: &buildUpdate{
				completionTime: &afterStartTimeBeforeNow,
				duration:       &greaterThanZeroLessThanSinceStartTime,
			},
		},
		{
			name:         "build with no start time",
			build:        buildWithNoStartTime,
			podStartTime: &earlierTime,
			expected: &buildUpdate{
				startTime:      &earlierTime,
				completionTime: &afterStartTimeBeforeNow,
				duration:       &atLeastOneHour,
			},
		},
		{
			name:         "build with no start time, no pod start time",
			build:        buildWithNoStartTime,
			podStartTime: nil,
			expected: &buildUpdate{
				startTime:      &afterStartTimeBeforeNow,
				completionTime: &afterStartTimeBeforeNow,
				duration:       &zeroDuration,
			},
		},
	}

	for _, test := range tests {
		update := &buildUpdate{}
		pod := &corev1.Pod{}
		pod.Status.StartTime = test.podStartTime
		setBuildCompletionData(test.build, pod, update)
		// Ensure that only the fields in the expected update are set
		if test.expected.podNameAnnotation == nil && (test.expected.podNameAnnotation != update.podNameAnnotation) {
			t.Errorf("%s: podNameAnnotation should not be set", test.name)
			continue
		}
		if test.expected.phase == nil && (test.expected.phase != update.phase) {
			t.Errorf("%s: phase should not be set", test.name)
			continue
		}
		if test.expected.reason == nil && (test.expected.reason != update.reason) {
			t.Errorf("%s: reason should not be set", test.name)
			continue
		}
		if test.expected.message == nil && (test.expected.message != update.message) {
			t.Errorf("%s: message should not be set", test.name)
			continue
		}
		if test.expected.startTime == nil && (test.expected.startTime != update.startTime) {
			t.Errorf("%s: startTime should not be set", test.name)
			continue
		}
		if test.expected.completionTime == nil && (test.expected.completionTime != update.completionTime) {
			t.Errorf("%s: completionTime should not be set", test.name)
			continue
		}
		if test.expected.duration == nil && (test.expected.duration != update.duration) {
			t.Errorf("%s: duration should not be set", test.name)
			continue
		}
		if test.expected.outputRef == nil && (test.expected.outputRef != update.outputRef) {
			t.Errorf("%s: outputRef should not be set", test.name)
			continue
		}
		now := metav1.NewTime(time.Now().Add(2 * time.Second))
		if test.expected.startTime != nil {
			if update.startTime == nil {
				t.Errorf("%s: expected startTime to be set", test.name)
				continue
			}
			switch test.expected.startTime {
			case &afterStartTimeBeforeNow:
				if !update.startTime.Time.After(startTime.Time) && !update.startTime.Time.Before(now.Time) {
					t.Errorf("%s: startTime (%v) not within expected range (%v - %v)", test.name, update.startTime, startTime, now)
					continue
				}
			default:
				if !update.startTime.Time.Equal(test.expected.startTime.Time) {
					t.Errorf("%s: startTime (%v) not equal expected time (%v)", test.name, update.startTime, test.expected.startTime)
					continue
				}
			}
		}
		if test.expected.completionTime != nil {
			if update.completionTime == nil {
				t.Errorf("%s: expected completionTime to be set", test.name)
				continue
			}
			switch test.expected.completionTime {
			case &afterStartTimeBeforeNow:
				if !update.completionTime.Time.After(startTime.Time) && !update.completionTime.Time.Before(now.Time) {
					t.Errorf("%s: completionTime (%v) not within expected range (%v - %v)", test.name, update.completionTime, startTime, now)
					continue
				}
			default:
				if !update.completionTime.Time.Equal(test.expected.completionTime.Time) {
					t.Errorf("%s: completionTime (%v) not equal expected time (%v)", test.name, update.completionTime, test.expected.completionTime)
					continue
				}
			}
		}
		if test.expected.duration != nil {
			if update.duration == nil {
				t.Errorf("%s: expected duration to be set", test.name)
				continue
			}
			switch test.expected.duration {
			case &greaterThanZeroLessThanSinceStartTime:
				sinceStart := now.Rfc3339Copy().Time.Sub(startTime.Rfc3339Copy().Time)
				if *update.duration <= 0 || *update.duration > sinceStart {
					t.Errorf("%s: duration (%v) not within expected range (%v - %v)", test.name, update.duration, 0, sinceStart)
					continue
				}
			case &atLeastOneHour:
				if *update.duration < time.Hour {
					t.Errorf("%s: duration (%v) is not at least one hour", test.name, update.duration)
					continue
				}
			default:
				if *update.duration != *test.expected.duration {
					t.Errorf("%s: duration (%v) not equal expected duration (%v)", test.name, update.duration, test.expected.duration)
					continue
				}
			}
		}
	}
}

func TestCreateBuildCAConfigMap(t *testing.T) {
	bc := newFakeBuildController(nil, nil, nil, nil)
	bc.additionalTrustedCAData = []byte(dummyCA)
	defer bc.stop()
	build := dockerStrategy(mockBuild(buildv1.BuildPhaseNew, buildv1.BuildOutput{}))
	pod := mockBuildPod(build)
	caMap := bc.createBuildCAConfigMapSpec(build, pod)
	if caMap == nil {
		t.Error("certificate authority configMap was not created")
	}
	if !hasBuildCAOwnerRef(pod, caMap) {
		t.Error("build CA configMap is missing owner ref to the build pod")
	}
	injectAnnotation := "service.alpha.openshift.io/inject-cabundle"
	val, exists := caMap.Annotations[injectAnnotation]
	if !exists {
		t.Errorf("expected CA configMap to have annotation %s", injectAnnotation)
	}
	if val != "true" {
		t.Errorf("expected annotation %s to be %s; got %s", injectAnnotation, "true", val)
	}
	if _, hasCA := caMap.Data[buildutil.AdditionalTrustedCAKey]; !hasCA {
		t.Errorf("expected CA configMap to have key %s", buildutil.AdditionalTrustedCAKey)
	}
	if caMap.Data[buildutil.AdditionalTrustedCAKey] != dummyCA {
		t.Errorf("expected CA configMap.%s to contain\n%s\ngot:\n%s", buildutil.AdditionalTrustedCAKey, dummyCA, caMap.Data[buildutil.AdditionalTrustedCAKey])
	}

}

func TestReadBuildCAData(t *testing.T) {
	bc := newFakeBuildController(nil, nil, nil, nil)
	defer bc.stop()
	tmpDir, err := ioutil.TempDir("", "build-ctrl-test")
	if err != nil {
		t.Fatalf("failed to create temp dir: %v", err)
	}
	defer os.RemoveAll(tmpDir)
	testFile := filepath.Join(tmpDir, "test-ca.crt")
	err = ioutil.WriteFile(testFile, []byte(dummyCA), 0600)
	if err != nil {
		t.Fatalf("failed to create test CA bundle: %v", err)
	}
	bc.additionalTrustedCAPath = testFile
	caData, err := bc.readBuildCAData()
	if err != nil {
		t.Fatalf("error reading CA data: %v", err)
	}
	if dummyCA != string(caData) {
		t.Errorf("expected additional trusted CA bundle to contain:\n%s\ngot:\n%s", dummyCA, string(caData))
	}

}

func mockBuild(phase buildv1.BuildPhase, output buildv1.BuildOutput) *buildv1.Build {
	return &buildv1.Build{
		ObjectMeta: metav1.ObjectMeta{
			Name:      "data-build",
			Namespace: "namespace",
			Annotations: map[string]string{
				buildutil.BuildConfigAnnotation: "test-bc",
			},
			Labels: map[string]string{
				"name": "dataBuild",
				buildutil.BuildRunPolicyLabel: string(buildv1.BuildRunPolicyParallel),
				buildutil.BuildConfigLabel:    "test-bc",
			},
		},
		Spec: buildv1.BuildSpec{
			CommonSpec: buildv1.CommonSpec{
				Source: buildv1.BuildSource{
					Git: &buildv1.GitBuildSource{
						URI: "http://my.build.com/the/build/Dockerfile",
					},
					ContextDir: "contextimage",
				},
				Output: output,
			},
		},
		Status: buildv1.BuildStatus{
			Phase: phase,
		},
	}
}

func dockerStrategy(build *buildv1.Build) *buildv1.Build {
	build.Spec.Strategy = buildv1.BuildStrategy{
		DockerStrategy: &buildv1.DockerBuildStrategy{},
	}
	return build
}

func pipelineStrategy(build *buildv1.Build) *buildv1.Build {
	build.Spec.Strategy = buildv1.BuildStrategy{
		JenkinsPipelineStrategy: &buildv1.JenkinsPipelineBuildStrategy{},
	}
	return build
}

func fakeImageClient(objects ...runtime.Object) imagev1client.Interface {
	return fakeimagev1client.NewSimpleClientset(objects...)
}

func fakeBuildClient(objects ...runtime.Object) buildv1client.Interface {
	return fakebuildv1client.NewSimpleClientset(objects...)
}

func fakeKubeExternalClientSet(objects ...runtime.Object) kubernetes.Interface {
	return fake.NewSimpleClientset(objects...)
}

func fakeKubeInternalClientSet(objects ...runtime.Object) kubernetes.Interface {
	return fake.NewSimpleClientset(objects...)
}

func fakeKubeExternalInformers(clientSet kubernetes.Interface) informers.SharedInformerFactory {
	return informers.NewSharedInformerFactory(clientSet, 0)
}

type fakeBuildController struct {
	*BuildController
	kubeExternalInformers informers.SharedInformerFactory
	buildInformers        buildv1informer.SharedInformerFactory
	imageInformers        imagev1informer.SharedInformerFactory
	stopChan              chan struct{}
}

func (c *fakeBuildController) start() {
	c.kubeExternalInformers.Start(c.stopChan)
	c.imageInformers.Start(c.stopChan)
	c.buildInformers.Start(c.stopChan)
	if !cache.WaitForCacheSync(wait.NeverStop, c.buildStoreSynced, c.podStoreSynced, c.secretStoreSynced, c.imageStreamStoreSynced) {
		panic("cannot sync cache")
	}
}

func (c *fakeBuildController) stop() {
	close(c.stopChan)
}

func newFakeBuildController(buildClient buildv1client.Interface, imageClient imagev1client.Interface, kubeExternalClient kubernetes.Interface, kubeInternalClient kubernetes.Interface) *fakeBuildController {
	if buildClient == nil {
		buildClient = fakeBuildClient()
	}
	if imageClient == nil {
		imageClient = fakeImageClient()
	}
	if kubeExternalClient == nil {
		kubeExternalClient = fakeKubeExternalClientSet()
	}
	if kubeInternalClient == nil {
		builderSA := corev1.ServiceAccount{}
		builderSA.Name = "builder"
		builderSA.Namespace = "namespace"
		kubeInternalClient = fakeKubeInternalClientSet(&builderSA)
	}

	kubeExternalInformers := fakeKubeExternalInformers(kubeExternalClient)
	buildInformers := buildv1informer.NewSharedInformerFactory(buildClient, 0)
	imageInformers := imagev1informer.NewSharedInformerFactory(imageClient, 0)
	stopChan := make(chan struct{})

	params := &BuildControllerParams{
		BuildInformer:       buildInformers.Build().V1().Builds(),
		BuildConfigInformer: buildInformers.Build().V1().BuildConfigs(),
		ImageStreamInformer: imageInformers.Image().V1().ImageStreams(),
		PodInformer:         kubeExternalInformers.Core().V1().Pods(),
		SecretInformer:      kubeExternalInformers.Core().V1().Secrets(),
		KubeClient:          kubeExternalClient,
		BuildClient:         buildClient,
		DockerBuildStrategy: &strategy.DockerBuildStrategy{
			Image: "test/image:latest",
		},
		SourceBuildStrategy: &strategy.SourceBuildStrategy{
			Image: "test/image:latest",
		},
		CustomBuildStrategy: &strategy.CustomBuildStrategy{},
		BuildDefaults:       builddefaults.BuildDefaults{},
		BuildOverrides:      buildoverrides.BuildOverrides{},
	}
	bc := &fakeBuildController{
		BuildController:       NewBuildController(params),
		stopChan:              stopChan,
		kubeExternalInformers: kubeExternalInformers,
		buildInformers:        buildInformers,
		imageInformers:        imageInformers,
	}
	bc.BuildController.recorder = &record.FakeRecorder{}
	bc.start()
	return bc
}

func validateUpdate(t *testing.T, name string, expected, actual *buildUpdate) {
	if expected.podNameAnnotation == nil {
		if actual.podNameAnnotation != nil {
			t.Errorf("%s: podNameAnnotation should be nil. Actual: %s", name, *actual.podNameAnnotation)
		}
	} else {
		if actual.podNameAnnotation == nil {
			t.Errorf("%s: podNameAnnotation should not be nil.", name)
		} else {
			if *expected.podNameAnnotation != *actual.podNameAnnotation {
				t.Errorf("%s: unexpected value for podNameAnnotation. Expected: %s. Actual: %s", name, *expected.podNameAnnotation, *actual.podNameAnnotation)
			}
		}
	}
	if expected.phase == nil {
		if actual.phase != nil {
			t.Errorf("%s: phase should be nil. Actual: %s", name, *actual.phase)
		}
	} else {
		if actual.phase == nil {
			t.Errorf("%s: phase should not be nil.", name)
		} else {
			if *expected.phase != *actual.phase {
				t.Errorf("%s: unexpected value for phase. Expected: %s. Actual: %s", name, *expected.phase, *actual.phase)
			}
		}
	}
	if expected.reason == nil {
		if actual.reason != nil {
			t.Errorf("%s: reason should be nil. Actual: %s", name, *actual.reason)
		}
	} else {
		if actual.reason == nil {
			t.Errorf("%s: reason should not be nil.", name)
		} else {
			if *expected.reason != *actual.reason {
				t.Errorf("%s: unexpected value for reason. Expected: %s. Actual: %s", name, *expected.reason, *actual.reason)
			}
		}
	}
	if expected.message == nil {
		if actual.message != nil {
			t.Errorf("%s: message should be nil. Actual: %s", name, *actual.message)
		}
	} else {
		if actual.message == nil {
			t.Errorf("%s: message should not be nil.", name)
		} else {
			if *expected.message != *actual.message {
				t.Errorf("%s: unexpected value for message. Expected: %s. Actual: %s", name, *expected.message, *actual.message)
			}
		}
	}
	if expected.startTime == nil {
		if actual.startTime != nil {
			t.Errorf("%s: startTime should be nil. Actual: %s", name, *actual.startTime)
		}
	} else {
		if actual.startTime == nil {
			t.Errorf("%s: startTime should not be nil.", name)
		} else {
			if !(*expected.startTime).Equal(actual.startTime) {
				t.Errorf("%s: unexpected value for startTime. Expected: %s. Actual: %s", name, *expected.startTime, *actual.startTime)
			}
		}
	}
	if expected.completionTime == nil {
		if actual.completionTime != nil {
			t.Errorf("%s: completionTime should be nil. Actual: %s", name, *actual.completionTime)
		}
	} else {
		if actual.completionTime == nil {
			t.Errorf("%s: completionTime should not be nil.", name)
		} else {
			if !(*expected.completionTime).Equal(actual.completionTime) {
				t.Errorf("%s: unexpected value for completionTime. Expected: %v. Actual: %v", name, *expected.completionTime, *actual.completionTime)
			}
		}
	}
	if expected.duration == nil {
		if actual.duration != nil {
			t.Errorf("%s: duration should be nil. Actual: %s", name, *actual.duration)
		}
	} else {
		if actual.duration == nil {
			t.Errorf("%s: duration should not be nil.", name)
		} else {
			if *expected.duration != *actual.duration {
				t.Errorf("%s: unexpected value for duration. Expected: %v. Actual: %v", name, *expected.duration, *actual.duration)
			}
		}
	}
	if expected.outputRef == nil {
		if actual.outputRef != nil {
			t.Errorf("%s: outputRef should be nil. Actual: %s", name, *actual.outputRef)
		}
	} else {
		if actual.outputRef == nil {
			t.Errorf("%s: outputRef should not be nil.", name)
		} else {
			if *expected.outputRef != *actual.outputRef {
				t.Errorf("%s: unexpected value for outputRef. Expected: %s. Actual: %s", name, *expected.outputRef, *actual.outputRef)
			}
		}
	}
}

func applyBuildPatch(build *buildv1.Build, patch []byte) (*buildv1.Build, error) {
	buildJSON, err := runtime.Encode(buildscheme.Encoder, build)
	if err != nil {
		return nil, err
	}
	patchedJSON, err := strategicpatch.StrategicMergePatch(buildJSON, patch, &buildv1.Build{})
	if err != nil {
		return nil, err
	}
	patchedVersionedBuild, err := runtime.Decode(buildscheme.Decoder, patchedJSON)
	if err != nil {
		return nil, err
	}
	return patchedVersionedBuild.(*buildv1.Build), nil
}

func applyBuildPatchReaction(t *testing.T, build *buildv1.Build, buildPtr **buildv1.Build) func(action clientgotesting.Action) (bool, runtime.Object, error) {
	return func(action clientgotesting.Action) (bool, runtime.Object, error) {
		patchAction := action.(clientgotesting.PatchActionImpl)
		var err error
		(*buildPtr), err = applyBuildPatch(build, patchAction.Patch)
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
			return true, nil, nil
		}
		return true, *buildPtr, nil
	}
}

type updateBuilder struct {
	update *buildUpdate
}

func newUpdate() *updateBuilder {
	return &updateBuilder{update: &buildUpdate{}}
}

func (b *updateBuilder) phase(phase buildv1.BuildPhase) *updateBuilder {
	b.update.setPhase(phase)
	return b
}

func (b *updateBuilder) reason(reason buildv1.StatusReason) *updateBuilder {
	b.update.setReason(reason)
	return b
}

func (b *updateBuilder) message(message string) *updateBuilder {
	b.update.setMessage(message)
	return b
}

func (b *updateBuilder) startTime(startTime metav1.Time) *updateBuilder {
	b.update.setStartTime(startTime)
	return b
}

func (b *updateBuilder) completionTime(completionTime metav1.Time) *updateBuilder {
	b.update.setCompletionTime(completionTime)
	return b
}

func (b *updateBuilder) duration(duration time.Duration) *updateBuilder {
	b.update.setDuration(duration)
	return b
}

func (b *updateBuilder) outputRef(ref string) *updateBuilder {
	b.update.setOutputRef(ref)
	return b
}

func (b *updateBuilder) podNameAnnotation(podName string) *updateBuilder {
	b.update.setPodNameAnnotation(podName)
	return b
}

func (b *updateBuilder) logSnippet(message string) *updateBuilder {
	b.update.setLogSnippet(message)
	return b
}

type fakeRunPolicy struct {
	notRunnable      bool
	onCompleteCalled bool
}

func (f *fakeRunPolicy) IsRunnable(*buildv1.Build) (bool, error) {
	return !f.notRunnable, nil
}

func (f *fakeRunPolicy) OnComplete(*buildv1.Build) error {
	f.onCompleteCalled = true
	return nil
}

func (f *fakeRunPolicy) Handles(buildv1.BuildRunPolicy) bool {
	return true
}

func mockBuildPod(build *buildv1.Build) *corev1.Pod {
	pod := &corev1.Pod{}
	pod.Name = buildapihelpers.GetBuildPodName(build)
	pod.Namespace = build.Namespace
	pod.Annotations = map[string]string{}
	pod.Annotations[buildutil.BuildAnnotation] = build.Name
	return pod
}

func mockBuildCAConfigMap(build *buildv1.Build, pod *corev1.Pod) *corev1.ConfigMap {
	cm := &corev1.ConfigMap{}
	cm.Name = buildapihelpers.GetBuildCAConfigMapName(build)
	cm.Namespace = build.Namespace
	if pod != nil {
		pod.OwnerReferences = []metav1.OwnerReference{
			{
				APIVersion: "v1",
				Kind:       "Pod",
				Name:       pod.Name,
				UID:        pod.UID,
			},
		}
	}
	return cm
}


text:
package org.elasticsearch.search.aggregations.bucket.terms.support;

import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.CharsRef;
import org.apache.lucene.util.UnicodeUtil;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Defines the include/exclude regular expression filtering for string terms aggregation. In this filtering logic,
 * exclusion has precedence, where the {@code include} is evaluated first and then the {@code exclude}.
 */
public class IncludeExclude {

    private final Matcher include;
    private final Matcher exclude;
    private final CharsRef scratch = new CharsRef();

    /**
     * @param include   The regular expression pattern for the terms to be included
     *                  (may only be {@code null} if {@code exclude} is not {@code null}
     * @param exclude   The regular expression pattern for the terms to be excluded
     *                  (may only be {@code null} if {@code include} is not {@code null}
     */
    public IncludeExclude(Pattern include, Pattern exclude) {
        assert include != null || exclude != null : "include & exclude cannot both be null"; // otherwise IncludeExclude object should be null
        this.include = include != null ? include.matcher("") : null;
        this.exclude = exclude != null ? exclude.matcher("") : null;
    }

    /**
     * Returns whether the given value is accepted based on the {@code include} & {@code exclude} patterns.
     */
    public boolean accept(BytesRef value) {
        UnicodeUtil.UTF8toUTF16(value, scratch);
        if (include == null) {
            // exclude must not be null
            return !exclude.reset(scratch).matches();
        }
        if (!include.reset(scratch).matches()) {
            return false;
        }
        if (exclude == null) {
            return true;
        }
        return !exclude.reset(scratch).matches();
    }
}


text:
/**
 * Monitor
 */
function Monitor()
{
    BaseMonitor.call(this);
}

Monitor.prototype = Object.create(BaseMonitor.prototype);
Monitor.prototype.constructor = Monitor;

/**
 * Clear
 */
Monitor.prototype.clear = function()
{
    process.stdout.write('\u001B[2J\u001B[0;0f');
};

/**
 * Write line
 *
 * @param {string} message
 */
Monitor.prototype.writeLine = function(message)
{
    process.stdout.write(message + '\n');
};


text:
using Infra;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LeetCodeCSharp
{
    public class _016_PathSum
    {
        /*
         * http://leetcode.com/onlinejudge#question_113
         */
        public List<List<int>> FindAllPathSum(TreeNode root, int targetValue)
        {
            List<List<int>> res = new List<List<int>>();
            List<TreeNode> tmp = new List<TreeNode>() {root};
            int sum = root.Value;
            Solve(root, res, tmp, sum, targetValue);
            return res;
        }

        private void Solve(TreeNode root, List<List<int>> res, List<TreeNode> tmp, int sum, int target)
        {
            if (sum == target &&
                tmp[tmp.Count-1].LeftChild == null &&
                tmp[tmp.Count-1].RightChild == null)
            {
                List<int> l = new List<int>();
                foreach (TreeNode node in tmp)
                {
                    l.Add(node.Value);
                }
                res.Add(l);
                return;
            }

            if (root.LeftChild != null)
            {
                tmp.Add(root.LeftChild);
                sum += root.LeftChild.Value;
                Solve(root.LeftChild, res, tmp, sum, target);
                sum -= root.LeftChild.Value;
                tmp.Remove(root.LeftChild);
            }

            if (root.RightChild != null)
            {
                tmp.Add(root.RightChild);
                sum += root.RightChild.Value;
                Solve(root.RightChild, res, tmp, sum, target);
                sum -= root.RightChild.Value;
                tmp.Remove(root.RightChild);
            }
        }
    }
}


text:
var Globals = (new function Globals($) {
	var _instance	= this;
	var _body		= $('body');

	this.init = function init() {
		_instance.window();

		setInterval(function() {
			_instance.window();
		}, 1000);

		$(document.body).on('click', '[data-tab]', function(event) {
			var element	= $(this);
			var tab		= element.data('tab');

			$('a[data-tab]').removeClass('active');
			element.addClass('active');

			$('input[name="tab"]').prop('checked', false);
			$('input[name="tab"]#' + tab).prop('checked', true);
		});

		$(document.body).on('click', '[data-action]', function(event) {
			var element	= $(this);
			var action	= element.data('action');

			switch(action) {
				case 'dismiss':
					Client.close();
				break;
				case 'payin':
					var knuddel = parseInt($('input[name="knuddel"]').val(), 10);

					if(isNaN(knuddel) || knuddel < 0) {
						knuddel = 0;
					}

					Client.executeSlashCommand('/appknuddel ' + Client.pageData.bot + ':' + knuddel);
					Client.close();
				break;
				case 'payout':
					var knuddel = parseInt($('input[name="knuddel"]').val(), 10);

					if(isNaN(knuddel) || knuddel < 0) {
						knuddel = 0;
					}

					Client.executeSlashCommand('/knuddelaccount payout:' + Client.pageData.app + ':' + knuddel);
					Client.close();
				break;
			}
		});

		this.setData(_body, 'client', Client.getClientType());
	};

	this.window = function window() {
		if(typeof(Client.pageData) != 'undefined' && typeof(Client.pageData.window) != 'undefined' && typeof(Client.pageData.window.icon) != 'undefined') {
			Client.getHostFrame().setIcon(Client.pageData.window.icon);
		}

		if(typeof(Client.pageData) != 'undefined' && typeof(Client.pageData.window) != 'undefined' && typeof(Client.pageData.window.icon) != 'undefined') {
			Client.getHostFrame().setTitle(Client.pageData.window.title);
		}
	};

	this.setData = function setData(element, name, data) {
		try {
			element.data(name, data);

			if(typeof(data) == 'boolean') {
				element.attr('data-' + name, data ? 'true' : 'false');
				return;
			}

			element.attr('data-' + name, data);
		} catch(e) {
			Client.sendEvent('exception', e);
		}
	};

	this.init();
}(jQuery));


text:
<?php
namespace Kahlan\Reporter\Coverage;

class Metrics
{
    /**
     * Reference to the parent metrics.
     *
     * @var object
     */
    protected $_parent = null;

    /**
     * The string name reference of the metrics.
     *
     * @var string
     */
    protected $_name = '';

    /**
     * The type of the metrics is about.
     *
     * @var string
     */
    protected $_type = 'namespace';

    /**
     * The metrics data.
     *
     * @var array The metrics:
     *            - `'loc'`      _integer_ : the number of line of code.
     *            - `'lloc'`     _integer_ : the number of logical line of code (i.e code statements or those lines which end in a semicolon)
     *            - `'nlloc'`    _integer_ : the number of non logical line of code (i.e uncoverable).
     *            - `'cloc'`     _integer_ : the number of covered line of code
     *            - `'methods'`  _integer_ : the number of methods.
     *            - `'cmethods'` _integer_ : the number of covered methods.
     *            - `'files'`    _array_   : the file paths.
     */
    protected $_metrics = [
        'loc'      => 0,
        'lloc'     => 0,
        'nlloc'    => 0,
        'cloc'     => 0,
        'coverage' => 0,
        'methods'  => 0,
        'cmethods' => 0,
        'files'    => [],
        'percent'  => 0
    ];

    /**
     * The child metrics of the current metrics.
     *
     * @param array
     */
    protected $_childs = [];

    /**
     * Constructor
     *
      * @param array $options Possible options values are:
     *                        - `'name'`   _string_  : the string name reference of the metrics.
     *                        - `'type'`   _string_  : the type of the metrics is about.
     *                        - `'parent'` _instance_: reference to the parent metrics.
     */
    public function __construct($options = [])
    {
        $defaults = ['name' => '', 'type' => 'namespace', 'parent' => null];
        $options += $defaults;

        $this->_parent = $options['parent'];
        $this->_type = $options['type'];

        if (!$this->_parent) {
            $this->_name = $options['name'];
            return;
        }

        $pname =  $this->_parent->name();
        switch ($this->_type) {
            case 'namespace':
            case 'function':
            case 'trait':
            case 'class':
                $this->_name = $pname ? $pname . '\\' . $options['name'] : $options['name'];
            break;
            case 'method':
                $this->_name = $pname ? $pname . '::' . $options['name'] : $options['name'];
            break;
        }
    }

    /**
     * Gets the parent instance.
     *
     * @return object The parent instance
     */
    public function parent()
    {
        return $this->_parent;
    }

    /**
     * Gets the name of the metrics.
     *
     * @return string The name of the metrics.
     */
    public function name()
    {
        return $this->_name;
    }

    /**
     * Gets the type of the metrics.
     *
     * @return string The type of the metrics.
     */
    public function type()
    {
        return $this->_type;
    }

    /**
     * Gets/Sets the metrics stats.
     *
     * @param  array $metrics The metrics data to set if defined.
     * @return array          The metrics data.
     */
    public function data($metrics = [])
    {
        if (func_num_args() === 0) {
            return $this->_metrics;
        }

        $this->_metrics = $metrics + $this->_metrics;

        if ($this->_metrics['lloc']) {
            $this->_metrics['percent'] = ($this->_metrics['cloc'] * 100) / $this->_metrics['lloc'];
        } else {
            $this->_metrics['percent'] = 100;
        }
    }

    /**
     * Adds some metrics to the current metrics.
     *
     * @param string $name The name reference of the metrics.
     * @param string $type The type of metrics to add.
     *                     Possible values are: `'namespace'`, `'class' or 'function'.
     * @param array        The metrics array to add.
     */
    public function add($name, $type, $metrics)
    {
        if (!$name) {
            $this->_merge($metrics, true);
            return;
        }
        list($name, $subname, $nameType) = $this->_parseName($name, $type);
        if (!isset($this->_childs[$name])) {
            $parent = $this;
            $this->_childs[$name] = new Metrics([
                'name'   => $name,
                'parent' => $parent,
                'type'   => $nameType
            ]);
        }
        ksort($this->_childs);
        $this->_merge($metrics);
        $this->_childs[$name]->add($subname, $type, $metrics);
    }

    /**
     * Gets the metrics from a name.
     *
     * @param  string $name The name reference of the metrics.
     * @return object       The metrics instance.
     */
    public function get($name = null)
    {
        if (!$name) {
            return $this;
        }
        list($name, $subname, $type) = $this->_parseName($name);

        if (!isset($this->_childs[$name])) {
            return;
        }
        return $this->_childs[$name]->get($subname);
    }

    /**
     * Gets the childs of the current metrics.
     *
     * @param  string $name The name reference of the metrics.
     * @return array        The metrics childs.
     */
    public function childs($name = null)
    {
        if (!$name) {
            return $this->_childs;
        }
        list($name, $subname, $type) = $this->_parseName($name);

        if (!isset($this->_childs[$name])) {
            return null;
        }
        return $this->_childs[$name]->childs($subname);
    }

    /**
     * Gets meta info of a metrics from a name reference..
     *
     * @param  string $name The name reference of the metrics.
     * @param  string $type The type to use by default if not auto detected.
     * @return array        The parsed name.
     */
    protected function _parseName($name, $type = null)
    {
        $subname = '';
        if (strpos($name, '\\') !== false) {
            $type = 'namespace';
            list($name, $subname) = explode('\\', $name, 2);
        } elseif (strpos($name, '::') !== false) {
            $type = 'class';
            list($name, $subname) = explode('::', $name, 2);
        } elseif (preg_match('~\(\)$~', $name)) {
            $type = ($this->_type === 'class' || $this->_type === 'trait') ? 'method' : 'function';
        }
        return [$name, $subname, $type];
    }

    /**
     * Merges some given metrics to the existing metrics .
     *
     * @param array   $metrics Metrics data to merge.
     * @param boolean $line    Set to `true` for function only
     */
    protected function _merge($metrics = [], $line = false)
    {
        $defaults = [
            'loc'      => [],
            'nlloc'    => [],
            'lloc'     => [],
            'cloc'     => [],
            'files'    => [],
            'methods'  => 0,
            'cmethods' => 0
        ];
        $metrics += $defaults;

        foreach (['loc', 'nlloc', 'lloc', 'cloc', 'coverage', 'files', 'methods', 'cmethods'] as $name) {
            $metrics[$name] += $this->_metrics[$name];
        }
        if (!$line) {
            unset($metrics['line']);
        }
        $this->data($metrics);
    }
}