text:
<?php
namespace php_active_record;
// connector: [770]
class AmericanInsectsAPI
{
    function __construct($folder)
    {
        $this->path_to_archive_directory = CONTENT_RESOURCE_LOCAL_PATH . '/' . $folder . '_working/';
        $this->archive_builder = new \eol_schema\ContentArchiveBuilder(array('directory_path' => $this->path_to_archive_directory));
        $this->taxon_ids = array();
        $this->object_ids = array();

        $this->domain = "http://americaninsects.net/";
        $this->to_exclude = array("index.", "glossary.", "maps.", "acknowledgment", "about.html", "faq.html", "works-consulted", "23", "24", "periplaneta-americana", "/http:");
        $this->stored_offline_urls_dump_file = "http://localhost/~eolit/cp/AmericanInsects/offline_urls.txt";
        $this->stored_offline_urls_dump_file = "https://dl.dropboxusercontent.com/u/7597512/AmericanInsects/offline_urls.txt";
        $this->download_options = array("download_wait_time" => 1000000, "timeout" => 1800, "download_attempts" => 1, "cache" => 1); // "expire_seconds" => 0 , "delay_in_minutes" => 2
        $this->debug = array();

        //for stats
        $this->TEMP_DIR = create_temp_dir() . "/";
        $this->current_offline_urls_dump_file = $this->TEMP_DIR . "offline_urls.txt";
        $this->current_offline_urls_dump_file2 = $this->TEMP_DIR . "offline_urls_unique.txt";
    }

    function get_all_taxa()
    {
        $this->stored_offline_urls = $this->get_rows_from_dump_file($this->stored_offline_urls_dump_file);
        $this->create_reference();
        $urls = self::get_urls_to_process();
        $this->process_urls($urls);
        $this->manuall_add_taxon();
        $this->archive_builder->finalize(TRUE);
        recursive_rmdir($this->TEMP_DIR); // comment this line to check offline_urls.txt
        debug("\n temporary directory removed: " . $this->TEMP_DIR);
    }

    private function process_urls($urls)
    {
        $i = 0;
        $total = count($urls);
        foreach($urls as $url)
        {
            $i++;
            echo "\n - $i of $total [$url]\n";
            if(isset($this->stored_offline_urls[$url])) continue;

            /* breakdown when caching debug
            $cont = false;
            // if($i >= 1 && $i < 1000)     $cont = true;
            // if($i >= 1000 && $i < 2000)  $cont = true;
            // if($i >= 2000 && $i < 3000)  $cont = true;
            // if($i >= 3000 && $i < 4000)  $cont = true;
            if(!$cont) continue;
            */

            if($html = Functions::lookup_with_cache($url, $this->download_options))
            {
                $html = trim(str_ireplace(array(' align="center"', ' class="style1"', ' class="style2"'), "", $html));
                if(preg_match("/>Family: (.*?)xxx/ims", $html . "xxx", $arr))
                {
                    $rec["source"] = $url;
                    if(preg_match("/<h1>(.*?)<\/h1>/ims", $html, $arr) ||
                       preg_match("/<FONT FACE=\"Arial\">(.*?)<\/FONT>/ims", $html, $arr) ||
                       preg_match("/<h2>(.*?)<\/h2>/ims", $html, $arr))
                    {
                        $sciname = Functions::remove_whitespace(strip_tags($arr[1]));
                        $sciname = trim(str_replace(array(chr(13), chr(10)), " ", $sciname));
                        //manual adjustments
                        if($sciname == "Small Winter Stoneflies") $sciname = "Allocapnia sp.";
                        if($sciname == "Embioptera: Family Oligotomidae") $sciname = "Oligotomidae";

                        $sciname = trim($sciname);
                        $to_exclude = array("cf.", "sp.", "Unidentified Stonefly", "Family");
                        $include = true;
                        foreach($to_exclude as $exclude)
                        {
                            if(is_numeric(stripos($sciname, $exclude))) $include = false;
                        }
                        if(!$include) continue;

                        $sciname = Functions::canonical_form($sciname);
                        // only species-level
                        if(stripos($sciname, " ") === false) continue;

                        // $images = self::parse_images($html, $url); working... temporarily commented
                        $images = array();
                        $info = self::parse_texts($html, $url);
                        $lengths = @$info["lengths"];
                        $wingspan = @$info["wingspan"];

                        if($images || $lengths)
                        {
                            $r = array();
                            $r["sciname"] = $sciname;
                            $r["taxon_id"] = str_replace(" ", "_", $r["sciname"]);
                            $r["source"] = $url;
                            self::create_instances_from_taxon_object($r);
                            $r["images"] = $images;
                            $r["lengths"] = $lengths;
                            $r["wingspan"] = $wingspan;
                            if($lengths) self::prepare_length_structured_data($r);
                            if($images) self::prepare_image_objects($r);
                        }
                    }
                    else echo "\n investigate: no sciname [$url]";
                }
            }
            else self::save_to_dump($url, $this->current_offline_urls_dump_file);
        }
        // print_r($this->debug);
        print "\n count:" . count($this->debug) . "\n";
    }

    private function manuall_add_taxon()
    {
        $records[] = array("sciname" => "Cordulegaster diastatops", "length" => "60-65", "url" => "http://www.americaninsects.net/d/cordulegaster-diastatops.html");
        $records[] = array("sciname" => "Cordulegaster bilineata", "length" => "60-65", "url" => "http://www.americaninsects.net/d/cordulegaster-diastatops.html");
        $records[] = array("sciname" => "Enallagma cyathigerum", "length" => "29-40", "url" => "http://americaninsects.net//d/enallagma-cyathigerum.html");
        $records[] = array("sciname" => "Enallagma boreale", "length" => "28-36", "url" => "http://americaninsects.net//d/enallagma-cyathigerum.html");
        foreach($records as $rec)
        {
            $r = array();
            $r["sciname"] = Functions::canonical_form($rec["sciname"]);
            $r["taxon_id"] = str_replace(" ", "_", $r["sciname"]);
            $r["source"] = $rec["url"];
            self::create_instances_from_taxon_object($r);
            $r["lengths"] = array($rec["length"]);
            self::prepare_length_structured_data($r);
        }
    }

    private function create_reference()
    {
        $r = new \eol_schema\Reference();
        $r->full_reference = "Cresswell, S. 2010-2014. American Insects. http://www.americaninsects.net";
        $r->identifier = md5($r->full_reference);
        $this->reference_id = $r->identifier;
        $this->archive_builder->write_object_to_file($r);
    }

    private function parse_texts($html, $url)
    {
        $texts = array();
        $length = "";
        $wingspan = false;
        if(preg_match("/>Wingspan: (.*?)</ims", $html, $arr))
        {
            $wingspan = true;
            $html = str_replace("Wingspan: ", "Length: ", $html);
        }
        if(preg_match("/>Length: (.*?)</ims", $html, $arr))
        {
            if($length = $arr[1])
            {
                $to_exclude = array("in image", "top photo", "first photo", "lower photo", "upper photo", "the photo", "in photo", "pictured",
                "Cantharini", "the right");
                foreach($to_exclude as $exclude)
                {
                    if(is_numeric(stripos($length, $exclude))) return array();
                }

                $length = trim(str_ireplace(array("females are a little larger than males", "Males usually smaller than the females",
                "males average smaller than females", "males tend  to be smaller than females", "Both sexes somewhat larger in  western North America",
                "some in the tribe are", "most in tribe", "most commonly", "adults are", "most in this genus",
                 "many in the tribe are", "in subfamily", "in the subfamily",
                "in this family", "in the family",
                "typically", "beetle", "barklouse", "many species", "in the genus are", "insect in photo", " mm", "often", "in the genus", "most are",
                "about", "fly", "Caddis", "insect", "under", "wasp", "around", " ",
                "most in genus", "usually", "adults", "most in family are", "in genus", "approximately"
                ), "", $length));

                //manual adjustment
                $length = str_replace("1.5 - 6.0 ;  3.3", "1.5 - 6.0", $length);
                $length = str_replace("7 - 9. In genus, 5 - 13", "7 - 9", $length);

                $chars = array(".", ",", ";");
                foreach($chars as $char)
                {
                    if(substr($length, -1) == $char) $length = substr($length, 0, strlen($length)-1);
                }
                echo "\n[$length]\n";
                $texts[] = $length;
            }
        }
        return array("lengths" => $texts, "wingspan" => $wingspan);
    }

    private function parse_images($html, $url)
    {
        $images = array();
        $to_exclude = array("button");
        if(preg_match_all("/<img (.*?)>/ims", $html, $arr))
        {
            foreach($arr[1] as $img)
            {
                $include = true;
                foreach($to_exclude as $exclude)
                {
                    if(strpos($img, $exclude) === false) {}
                    else $include = false;
                }
                if($include)
                {
                    $src = "";
                    $caption = "";
                    $image_path = "";
                    if(preg_match("/src=\"(.*?)\"/ims", $img, $arr2)) $src = $arr2[1];
                    if(preg_match("/alt=\"(.*?)\"/ims", $img, $arr2)) $caption = $arr2[1];
                    if($src)
                    {
                        if($val = self::get_directory_name($url)) $image_path = $val . "/" . $src;
                        if($image_path) $images[] = array("title" => $caption, "image" => $image_path);
                    }
                }
            }
        }
        return $images;
    }

    private function get_directory_name($url)
    {
        $info = pathinfo($url);
        if($info["dirname"] == "http:") return $this->domain;
        else                            return $info["dirname"];
        return false;
    }

    private function get_urls_to_process()
    {
        $urls = array();
        $urls[0] = self::get_urls_from_page($this->domain);
        $urls[1] = self::get_deep_level_urls($urls[0]);
        $urls[2] = self::get_deep_level_urls($urls[1]);
        $urls[3] = self::get_deep_level_urls($urls[2]);
        $urls[4] = self::get_deep_level_urls($urls[3]);
        $urls[5] = self::get_deep_level_urls($urls[4]);
        $temp = array_merge($urls[1], $urls[2], $urls[3], $urls[4], $urls[5]);
        $urls = array_values(array_unique($temp));
        $i = 0;
        foreach($urls as $url)
        {
            foreach($this->to_exclude as $exclude)
            {
                if(strpos($url, $exclude) === false) {}
                else unset($urls[$i]);
            }
            $i++;
        }
        $urls = array_map('trim', $urls);
        $urls = array_values(array_unique($urls));
        return $urls;
    }

    private function get_deep_level_urls($urls_to_process)
    {
        $temp = array();
        $total = count($urls_to_process);
        $i = 0;
        foreach($urls_to_process as $url)
        {
            $i++;
            echo "\n $i of $total - ";
            $temp = array_merge($temp, self::get_urls_from_page($url));
        }
        $temp = array_values(array_unique($temp));
        $final = array();
        foreach($temp as $url)
        {
            $info = pathinfo($url);
            $basename = $info["basename"];
            if(isset($this->basenames[$basename])) continue;
            else $this->basenames[$basename] = 1;
            $final[] = $url;
        }
        return $final;
    }

    private function get_urls_from_page($url)
    {
        if(isset($this->stored_offline_urls[$url])) return array();
        foreach($this->to_exclude as $exclude)
        {
            if(is_numeric(stripos($url, $exclude))) return array();
        }
        echo "\n processing [$url]\n";
        $temp = array();
        if($html = Functions::lookup_with_cache($url, $this->download_options))
        {
            $html = str_ireplace(array(' class="style1"', ' class="style2"', ' class="style3"', ' class="style4"', ' class="style5"',
                                       ' class="style6"', ' class="style7"', ' class="style8"', ' class="style9"', ' class="style10"',
                                       ' class="navbar"', ' class="style20"', ' class="style13"'), "", $html);
            $html = str_ireplace("%20.htm", ".htm", $html);
            $html = str_ireplace(" .htm", ".htm", $html);
            if(preg_match_all("/<a href\=\"(.*?)\">/ims", $html, $arr)) $temp = array_values(array_unique($arr[1]));
            else echo " - no urls \n ";
        }
        else self::save_to_dump($url, $this->current_offline_urls_dump_file);
        // generate url
        $final = array();
        if($temp)
        {
            $dirname = self::get_directory_name($url);
            foreach($temp as $url)
            {
                $include = true;
                foreach($this->to_exclude as $exclude)
                {
                    if(strpos($url, $exclude) === false) {}
                    else $include = false;
                }
                if($include) $final[] = $dirname . "/" . $url;
            }
        }
        return $final;
    }

    private function save_to_dump($data, $filename)
    {
        if(!($WRITE = fopen($filename, "a")))
        {
          debug(__CLASS__ .":". __LINE__ .": Couldn't open file: " . $filename);
          return;
        }
        if($data && is_array($data)) fwrite($WRITE, json_encode($data) . "\n");
        else                         fwrite($WRITE, $data . "\n");
        fclose($WRITE);
    }

    private function get_rows_from_dump_file($url) // utility
    {
        $path = Functions::save_remote_file_to_local($url, $this->download_options);
        $urls = array();
        foreach(new FileIterator($path) as $line_number => $line)
        {
            if($line) $urls[$line] = "";
        }
        unlink($path);
        return $urls;
    }

    // private function prepare_text_objects($rec)
    // {
    //     $articles = array();
    //     if(@$rec["texts"])
    //     {
    //         foreach($rec["texts"] as $type => $r) $articles[$type] = implode("<p>", $r);
    //         foreach($articles as $type => $description)
    //         {
    //             $description = trim($description);
    //             if(!$description) continue;
    //             $obj = array();
    //             $obj["description"] = "<p>" . $description;
    //             $obj["subject"] = self::get_subject($type);
    //             $obj["identifier"] = md5($rec["sciname"] . $description);
    //             $obj["type"] = "text";
    //             $obj["taxon_id"] = $rec["taxon_id"];
    //             $obj["source"] = $rec["source"];
    //             self::get_objects($obj);
    //         }
    //     }
    // }

    private function prepare_image_objects($rec)
    {
        if($imagez = @$rec["images"])
        {
            foreach($imagez as $image) self::save_image_object($image, $rec);
        }
    }

    private function save_image_object($image, $rec)
    {
        $obj = array();
        $obj["description"] = $image["title"];
        $obj["title"]       = "";
        $obj["identifier"]  = md5($image["image"]);
        $obj["type"]        = "image";
        $obj["taxon_id"]    = $rec["taxon_id"];
        $obj["source"]      = $rec["source"];
        $obj["accessURI"]   = $image["image"];
        self::get_objects($obj);
    }

    private function get_objects($rec)
    {
        $mr = new \eol_schema\MediaResource();
        if($rec["type"] == "text")
        {
            $mr->type               = 'http://purl.org/dc/dcmitype/Text';
            $mr->format             = 'text/html';
            $mr->CVterm             = $rec["subject"];
        }
        elseif($rec["type"] == "image")
        {
            $mr->type               = 'http://purl.org/dc/dcmitype/StillImage';
            $mr->format             = 'image/jpeg';
            $mr->accessURI          = $rec["accessURI"];
            $mr->title              = $rec["title"];
        }
        $mr->taxonID                = $rec["taxon_id"];
        $mr->identifier             = $rec["identifier"];
        $mr->language               = 'en';
        $mr->furtherInformationURL  = $rec["source"];
        $mr->description            = $rec["description"];
        $mr->UsageTerms             = 'http://creativecommons.org/licenses/by/3.0/';
        $mr->Owner                  = '';
        if(!isset($this->object_ids[$mr->identifier]))
        {
            $this->object_ids[$mr->identifier] = 1;
            $this->archive_builder->write_object_to_file($mr);
        }
    }

    private function prepare_length_structured_data($rec)
    {
        foreach($rec["lengths"] as $len)
        {
            if($len)
            {
                $length = self::clean_length_value($len);
                $lengths = explode(";", $length);
                $lengths = array_map('trim', $lengths);
                $ctr = 0;
                foreach($lengths as $length)
                {
                    $rec["remark"] = $length;
                    $length_no = trim(str_replace(array("female", "male", "worker", "queen", "drone", "mm", "to apex of abdomen", "greater than"), "", $length));
                    if(!$length_no) continue;
                    if($val = self::is_range($length_no)) $length_no = $val; // "3.50 to 4.0"
                    $arr = explode("-", $length_no);
                    $arr = array_map('trim', $arr);
                    if(count($arr) == 1)
                    {
                        $final = $length_no;
                        if(count(explode(" ", $length_no)) > 1) $rec["measurementRemarks"] = trim($length) . " (mm)";
                    }
                    else
                    {
                        $final = self::get_average($arr[0], $arr[1]);
                        $rec["measurementRemarks"] = "Source data are expressed as a range: " . trim($length) . " mm.";
                    }
                    $final = trim(preg_replace('/\s*\([^)]*\)/', '', $final)); //remove parenthesis
                    if(preg_match('!\d+\.*\d*!', $final, $match)) $final = $match[0]; //remove letters
                    if(is_numeric(strpos(@$rec["measurementRemarks"], "Source data are expressed as a range:"))) $rec["measurementRemarks"] .= " ($final mm. average).";
                    $rec["catnum"] = "length";
                    if($ctr) $rec["catnum"] .= $ctr;
                    $rec["statistical_method"] = "http://eol.org/schema/terms/average";
                    $rec["measurementUnit"] = "http://purl.obolibrary.org/obo/UO_0000016";
                    $length_measurement = "http://purl.obolibrary.org/obo/CMO_0000013";
                    if(is_numeric(stripos($length, "wingspan")) || @$rec["wingspan"]) $length_measurement = "http://www.owl-ontologies.com/unnamed.owl#Wingspan";
                    self::add_string_types("true", $rec, "length", $final, $length_measurement);
                    $this->debug[$final] = @$rec["measurementRemarks"];
                    $ctr++;
                }
            }
        }
    }

    private function clean_length_value($length)
    {
        $length = strtolower($length);
        $length = str_replace(array("\t", "\n", "males are smaller than females", "midilinae"), "", $length);
        $length = str_replace(">", "greater than", $length);
        $length = str_replace("workers", "worker", $length);
        $length = str_replace(". female", "; female", $length);
        $length = str_replace(". male", "; male", $length);
        $length = str_replace(". work", "; work", $length);
        return $length;
    }

    private function get_average($num1, $num2)
    {
        if(preg_match('!\d+\.*\d*!', $num1, $match)) $num1 = $match[0]; //remove letters
        if(preg_match('!\d+\.*\d*!', $num2, $match)) $num2 = $match[0];
        return round(($num1+$num2)/2, 1);
    }

    private function is_range($str)
    {
        $arr = explode(" to ", $str);
        if(count($arr) == 2)
        {
            if(is_numeric($arr[0]) && is_numeric($arr[1])) return str_replace(" to ", "-", $str);
        }
        return false;
    }

    private function create_instances_from_taxon_object($rec)
    {
        $taxon = new \eol_schema\Taxon();
        $taxon->taxonID                     = $rec["taxon_id"];
        $taxon->scientificName              = $rec["sciname"];
        $taxon->furtherInformationURL       = $rec["source"];
        if(!isset($this->taxon_ids[$taxon->taxonID]))
        {
            $this->taxon_ids[$taxon->taxonID] = 1;
            $this->archive_builder->write_object_to_file($taxon);
        }
    }

    private function add_string_types($measurementOfTaxon, $rec, $label, $value, $mtype)
    {
        $taxon_id = $rec["taxon_id"];
        $catnum = $rec["catnum"];
        $m = new \eol_schema\MeasurementOrFact();
        $occurrence = $this->add_occurrence($taxon_id, $catnum);
        $m->occurrenceID = $occurrence->occurrenceID;
        $m->measurementOfTaxon = $measurementOfTaxon;
        $m->source = $rec["source"];
        $m->measurementType = $mtype;
        $m->measurementValue = $value;
        $m->referenceID = $this->reference_id;
        if($val = @$rec["statistical_method"]) $m->statisticalMethod = $val;
        if($val = @$rec["measurementUnit"]) $m->measurementUnit = $val;
        if($val = @$rec["measurementRemarks"]) $m->measurementRemarks = $val;
        $this->archive_builder->write_object_to_file($m);
    }

    private function add_occurrence($taxon_id, $catnum)
    {
        $occurrence_id = $taxon_id . '_' . $catnum;
        if(isset($this->occurrence_ids[$occurrence_id])) return $this->occurrence_ids[$occurrence_id];
        $o = new \eol_schema\Occurrence();
        $o->occurrenceID = $occurrence_id;
        $o->taxonID = $taxon_id;
        $this->archive_builder->write_object_to_file($o);
        $this->occurrence_ids[$occurrence_id] = $o;
        return $o;
    }

    private function make_offline_urls_unique()
    {
        $stored_offline_urls = self::get_rows_from_dump_file($this->stored_offline_urls_dump_file);
        $temp = array_keys($stored_offline_urls);
        foreach($temp as $url) self::save_to_dump($url, $this->current_offline_urls_dump_file2);
    }

}
?>


text:
@implementation VKUploadImage
+ (instancetype)uploadImageWithData:(NSData *)data andParams:(VKImageParameters *)params {
    VKUploadImage *image = [VKUploadImage new];
    image.imageData = data;
    image.parameters = params ? : [VKImageParameters jpegImageWithQuality:0.9];
    return image;
}

+ (instancetype)uploadImageWithImage:(UIImage *)image andParams:(VKImageParameters *)params {
    VKUploadImage *upload = [VKUploadImage new];
    upload.sourceImage = image;
    upload.parameters = params ? : [VKImageParameters jpegImageWithQuality:0.9];
    return upload;
}
@end

redpajama_set_name: RedPajamaGithub


text:
echo "Download Docker CLI"
curl -L https://github.com/docker/compose/releases/download/1.8.0-rc2/docker-compose-`uname -s`-`uname -m` > /tmp/docker-compose
chmod +x /tmp/docker-compose

export PATH="/tmp/docker-compose:$PATH"

if [ -n "$DEBUG" ]; then
  docker --version
  docker-compose --version
fi


text:
package com.ait.lienzo.client.core.shape.wires.event;

import com.ait.lienzo.client.core.shape.wires.WiresConnector;

public class WiresConnectorPointsChangedEvent extends AbstractWiresEvent<WiresConnector, WiresConnectorPointsChangedHandler>
{
    public static final Type<WiresConnectorPointsChangedHandler> TYPE = new Type<WiresConnectorPointsChangedHandler>();

    public WiresConnectorPointsChangedEvent(WiresConnector shape)
    {
        super(shape);
    }

    @Override
    public Type<WiresConnectorPointsChangedHandler> getAssociatedType()
    {
        return TYPE;
    }

    @Override
    protected void dispatch(WiresConnectorPointsChangedHandler handler)
    {
        handler.onPointsChanged(this);
    }
}


text:
require 'rails_helper'

describe Admin::PipelinesController do
  before do
    allow(controller).to receive(:pipeline_pause_service).with(no_args).and_return(@pipeline_pause_service = double('Pipeline Pause Service'))
  end

  include ConfigSaveStubbing
  include TaskMother

  before(:each) do
    @user = Username.new(CaseInsensitiveString.new("loser"))
    allow(controller).to receive(:current_user).and_return(@user)
    allow(controller).to receive(:go_config_service).with(no_args).and_return(@go_config_service = double('Go Config Service'))
    @template_config_service = double('Template Config Service')
    allow(controller).to receive(:template_config_service).and_return(@template_config_service)
    allow(controller).to receive(:security_service).and_return(@security_service = double('Security Service'))
    @pluggable_task_service = double('Pluggable_task_service')

    allow(controller).to receive(:pluggable_task_service).and_return(@pluggable_task_service)
    allow(controller).to receive(:task_view_service).and_return(@task_view_service = double('Task View Service'))
    allow(controller).to receive(:package_definition_service).with(no_args).and_return(@package_definition_service = StubPackageDefinitionService.new)
    allow(controller).to receive(:pipeline_selections_service).and_return(@pipeline_selections_service = double('pipeline selections service'))
  end

  describe "routes" do
    it "should match /edit" do
      expect({:get => "/admin/pipelines/foo.bar/general"}).to route_to(:controller => "admin/pipelines", :action => "edit", :pipeline_name => 'foo.bar', :current_tab => 'general', :stage_parent => "pipelines")
    end

    it "should match /update" do
      expect({:put => "/admin/pipelines/foo.baz/general"}).to route_to(:controller => "admin/pipelines", :action => "update", :pipeline_name => 'foo.baz', :current_tab => 'general', :stage_parent => "pipelines")
    end

    it "should match /pause_info" do
      expect({:get => "/admin/pipelines/foo.baz/pause_info.json"}).to route_to(:controller => "admin/pipelines", :action => "pause_info", :pipeline_name => 'foo.baz', :format => "json")
      expect(pause_info_refresh_path(:pipeline_name => 'foo.baz')).to eq("/admin/pipelines/foo.baz/pause_info.json")
    end

    it "should match /new" do
      expect({:get => "/admin/pipeline/new"}).to route_to(:controller => "admin/pipelines", :action => "new")
      expect(pipeline_new_path).to eq("/admin/pipeline/new")
      expect(pipeline_new_path(:group => "foo.bar")).to eq("/admin/pipeline/new?group=foo.bar")
    end

    it "should match /create" do
      expect({:post => "/admin/pipelines"}).to route_to(:controller => "admin/pipelines", :action => "create")
      expect(pipeline_create_path).to eq("/admin/pipelines")
    end

    it "should match /clone" do
      expect({:get => "/admin/pipeline/foo.bar/clone"}).to route_to(:controller => "admin/pipelines", :action => "clone", :pipeline_name => 'foo.bar')
      expect(pipeline_clone_path(:pipeline_name => "foo.bar")).to eq("/admin/pipeline/foo.bar/clone")
    end

    it "should match /save_clone" do
      expect({:post => "/admin/pipeline/save_clone"}).to route_to(:controller => "admin/pipelines", :action => "save_clone")
      expect(pipeline_save_clone_path).to eq("/admin/pipeline/save_clone")
    end

  end

  describe "pause_info" do
    before(:each) do
      pipeline_config = PipelineConfigMother.pipelineConfigWithMingleConfiguration("HelloWorld", "http://mingleurl.com:7823", "go", "'status' > 'In Dev'")

      pipeline_config_for_edit = ConfigForEdit.new(pipeline_config, BasicCruiseConfig.new, BasicCruiseConfig.new)

      @result = HttpLocalizedOperationResult.new
      allow(HttpLocalizedOperationResult).to receive(:new).and_return(@result)

      expect(@go_config_service).to receive(:loadForEdit).with('HelloWorld', @user, @result).and_return(pipeline_config_for_edit)
      allow(@go_config_service).to receive(:checkConfigFileValid).and_return(com.thoughtworks.go.config.validation.GoConfigValidity.valid())
      allow(@go_config_service).to receive(:registry)

      @pause_info = PipelinePauseInfo.paused("just for fun", "loser")
      expect(@pipeline_pause_service).to receive(:pipelinePauseInfo).with("HelloWorld").and_return(@pause_info)
    end

    it "should load pause_info for json" do
      get :pause_info,params:{:pipeline_name => "HelloWorld", :format => "json"}

      expect(assigns[:pipeline]).not_to be_nil
      expect(assigns[:pause_info]).to eq(@pause_info)
    end
  end

  describe "edit" do
    before(:each) do
      pipeline_config = PipelineConfigMother.pipelineConfigWithMingleConfiguration("HelloWorld", "http://mingleurl.com:7823", "go", "'status' > 'In Dev'")
      pipeline_config.setLabelTemplate("some_label_template")
      @pipeline_config_for_edit = ConfigForEdit.new(pipeline_config, BasicCruiseConfig.new, BasicCruiseConfig.new)

      @result = HttpLocalizedOperationResult.new
      allow(HttpLocalizedOperationResult).to receive(:new).and_return(@result)

      allow(@go_config_service).to receive(:checkConfigFileValid).and_return(com.thoughtworks.go.config.validation.GoConfigValidity.valid())
      allow(@go_config_service).to receive(:registry)
    end

    describe "for authorized user" do
      before(:each) do
        @pause_info = PipelinePauseInfo.paused("just for fun", "loser")
        expect(@pipeline_pause_service).to receive(:pipelinePauseInfo).with("HelloWorld").and_return(@pause_info)
        expect(@go_config_service).to receive(:loadForEdit).with('HelloWorld', @user, @result).and_return(@pipeline_config_for_edit)
      end

      describe "GET general" do
        it "should load pipeline name, pipeline label template" do
          get :edit, params:{:pipeline_name => "HelloWorld", :current_tab => 'general', :stage_parent => "pipelines"}

          expect(assigns[:pipeline].name()).to eq(CaseInsensitiveString.new("HelloWorld"))
          expect(assigns[:pipeline].getLabelTemplate()).to eq("some_label_template")
          expect(assigns[:pause_info]).to eq(@pause_info)
          assert_template layout: "pipelines/details"
        end
      end

      describe "GET project_management" do
        it "should load mingle gadget config" do
          get :edit, params:{:pipeline_name => "HelloWorld", :current_tab => 'project_management', :stage_parent=>"pipelines"}

          assigns[:pipeline].getMingleConfig().getProjectIdentifier() == "go"
          assigns[:pipeline].getMingleConfig().getQuotedMql() == "'status' > 'In Dev'"
          expect(assigns[:pause_info]).to eq(@pause_info)
        end
      end
    end

    describe "with view" do
      render_views

      before do
        allow(@go_config_service).to receive(:isSecurityEnabled).and_return(false)
      end

      it "should error out when user is unauthorized" do
        expect(@go_config_service).to receive(:loadForEdit).with('HelloWorld', anything(), anything()) do |_, _, result|
          result.forbidden('Unauthorized to edit HelloWorld pipeline.', HealthStateType.forbidden_for_pipeline("HelloWorld"))
          nil
        end

        get :edit, params:{:pipeline_name => "HelloWorld", :current_tab => 'general', :stage_parent=>"pipelines"}

        expect(assigns[:pipeline]).to be_nil
        expect(response.status).to eq(403)
        expect(response.body).to have_selector("h3", :text => "Unauthorized to edit HelloWorld pipeline.")
      end
    end
  end

  describe "update" do
    before(:each) do
      allow(controller).to receive(:populate_config_validity)

      @cruise_config = BasicCruiseConfig.new()
      cruise_config_mother = GoConfigMother.new
      @pipeline = cruise_config_mother.addPipeline(@cruise_config, "pipeline-name", "stage-name", ["build-name"].to_java(java.lang.String))

      @pipeline_config_for_edit = ConfigForEdit.new(@pipeline, @cruise_config, @cruise_config)

      @go_config_service = stub_service(:go_config_service)
      allow(@go_config_service).to receive(:registry)
    end

    describe "for authorized user" do
      before(:each) do
        @pause_info = PipelinePauseInfo.paused("just for fun", "loser")

        expect(@pipeline_pause_service).to receive(:pipelinePauseInfo).with("pipeline-name").at_least(1).and_return(@pause_info)
      end

      it "should set config attributes on pipeline when updating" do
        stub_save_for_success

        put :update, params:{:pipeline_name => "pipeline-name", :current_tab => 'general', :pipeline => {"labelTemplate" => "${COUNT}-something"}, :config_md5 => "md5", :stage_parent=>"pipelines"}

        expect(assigns[:pipeline]).to eq(@pipeline)
        expect(@pipeline.getLabelTemplate()).to eq("${COUNT}-something")
        expect(assigns[:pause_info]).to eq(@pause_info)
      end

      it "should set variables and parameters to empty if not sent in params" do
        stub_save_for_success
        @pipeline.variables().add("key1", "value1")

        put :update, params:{:pipeline_name => "pipeline-name", :current_tab => 'general', :config_md5 => "md5", :default_as_empty_list => ["pipeline>variables"], :stage_parent=>"pipelines"}

        expect(assigns[:pipeline].variables().isEmpty()).to eq(true)

        @pipeline.addParam(ParamConfig.new("param1", "value1"))

        stub_save_for_success

        put :update, params:{:pipeline_name => "pipeline-name", :current_tab => 'general', :config_md5 => "md5", :default_as_empty_list => ["pipeline>params"], :stage_parent=>"pipelines"}

        expect(assigns[:pipeline].getParams().isEmpty()).to eq(true)
        expect(assigns[:pause_info]).to eq(@pause_info)
      end

      it "should update only if configuration is valid" do
        stub_save_for_validation_error do |result, _, node|
          node.addError("labelTemplate", "invalid-label")
          result.badRequest("Failed to update pipeline 'pipeline-name'.")
        end

        put :update, params:{:pipeline_name => "pipeline-name", :current_tab => 'general', :pipeline => {"labelTemplate" => "${COUNT}-#junk"}, :config_md5 => "md5", :stage_parent=>"pipelines"}

        expect(assigns[:errors].size).to eq(0)
        expect(assigns[:pause_info]).to eq(@pause_info)
        assert_template layout: "pipelines/details"
      end

      describe "params" do
        it "should report errors on deleted params that are referenced elsewhere" do
          stub_save_for_validation_error do |result, _, node|
            node.addError("labelTemplate", ParamSubstitutionHandler::NO_PARAM_FOUND_MSG.gsub("'%s'", "'to-be-deleted'"))
            result.badRequest("Failed to update pipeline 'pipeline-name'.")
          end

          @pipeline.addParam(ParamConfig.new("to-be-deleted", "original-deleted-value"))
          @pipeline.addParam(ParamConfig.new("to-be-modified", "original-value"))

          put :update, params:{:pipeline_name => "pipeline-name", :current_tab => 'parameters', :config_md5 => "md5", :stage_parent=>"pipelines", :default_as_empty_list => ["pipeline>params"],
              :pipeline => {:params => [{:name => "to-be-modified", :valueForDisplay => "modified-value"},
                                        {:name => "added", :valueForDisplay => "added-value"}]}}
          expect(assigns[:pause_info]).to eq(@pause_info)
          params = assigns[:pipeline].getParams()
          expect(params.size()).to eq(3)

          deleted = params.get(0)
          expect(deleted.getName()).to eq("to-be-deleted")
          expect(deleted.getValue()).to eq("original-deleted-value")
          expect(deleted.errors().on(ParamConfig::NAME)).to eq("Parameter cannot be deleted because it is referenced by other elements")

          mod = params.get(1)
          expect(mod.getName()).to eq("to-be-modified")
          expect(mod.getValue()).to eq("modified-value")
          expect(mod.getValueForDisplay()).to eq("modified-value")

          added = params.get(2)
          expect(added.getName()).to eq("added")
          expect(added.getValue()).to eq("added-value")
          expect(added.getValueForDisplay()).to eq("added-value")
        end

        it "should report errors on renamed params that are referenced elsewhere" do
          stub_save_for_validation_error do |result, _, node|
            node.addError("labelTemplate", ParamSubstitutionHandler::NO_PARAM_FOUND_MSG.gsub("'%s'", "'to-be-deleted'"))
            result.badRequest("Failed to update pipeline 'pipeline-name'.")
          end

          @pipeline.addParam(ParamConfig.new("to-be-deleted", "original-deleted-value"))
          @pipeline.addParam(ParamConfig.new("to-be-modified", "original-value"))

          put :update, params:{:pipeline_name => "pipeline-name", :current_tab => 'parameters', :config_md5 => "md5", :stage_parent=>"pipelines", :default_as_empty_list => ["pipeline>params"], :pipeline => {:params => [{:name => "renamed", :valueForDisplay => "renamed-value", :original_name => "to-be-deleted"},
                                                                                {:name => "to-be-modified", :valueForDisplay => "modified-value"}]}}
          params = assigns[:pipeline].getParams()
          expect(params.size()).to eq(2)

          renamed = params.get(0)
          expect(renamed.getName()).to eq("renamed")
          expect(renamed.getValue()).to eq("renamed-value")
          expect(renamed.errors().on(ParamConfig::NAME)).to eq("Parameter 'to-be-deleted' cannot be renamed because it is referenced by other elements")

          mod = params.get(1)
          expect(mod.getName()).to eq("to-be-modified")
          expect(mod.getValue()).to eq("modified-value")
        end
      end
    end

  end

  describe "new" do

    before(:each) do
      allow(@go_config_service).to receive(:checkConfigFileValid).and_return(com.thoughtworks.go.config.validation.GoConfigValidity.valid())
      allow(@go_config_service).to receive(:registry)
      allow(@go_config_service).to receive(:rolesForUser).and_return(nil)
      @cruise_config = BasicCruiseConfig.new
      expect(@go_config_service).to receive(:getConfigForEditing).and_return(@cruise_config)
      @cruise_config_mother = GoConfigMother.new
      expect(@task_view_service).to receive(:getTaskViewModels).and_return(Object.new())
      expect(@security_service).to receive(:modifiableGroupsForUser).with(@user).and_return(["group1", "group2"])
    end

    it "should have a new pipeline group with a pipeline in it" do
      expect(@go_config_service).to receive(:getCurrentConfig).and_return(@cruise_config)

      expect(@template_config_service).to receive(:getTemplateViewModels).with(anything).and_return([])

      get :new

      job_configs = JobConfigs.new([JobConfig.new(CaseInsensitiveString.new("defaultJob"), ResourceConfigs.new, ArtifactConfigs.new, com.thoughtworks.go.config.Tasks.new([AntTask.new].to_java(Task)))].to_java(JobConfig))
      pipeline = PipelineConfig.new(CaseInsensitiveString.new(""), MaterialConfigs.new, [StageConfig.new(CaseInsensitiveString.new("defaultStage"), job_configs)].to_java(StageConfig))
      expect(assigns[:pipeline_group]).to eq(BasicPipelineConfigs.new([pipeline].to_java(PipelineConfig)))
      expect(assigns[:pipeline]).to eq(pipeline)
      expect(assigns[:all_pipelines]).to eq(java.util.ArrayList.new)
      expect(assigns[:cruise_config]).to eq(@cruise_config)
      expect(assigns[:original_cruise_config]).to eq(@cruise_config)
      assert_template layout: "application"
    end

    it "should populate group name if adding to an existing group and get all existing pipelines as list of string" do
      cruise_config_mother = GoConfigMother.new
      cruise_config_mother.addPipeline(@cruise_config, "new_pipeline", "stageName", ["jobname"].to_java(java.lang.String))
      expect(@go_config_service).to receive(:getCurrentConfig).and_return(@cruise_config)
      allow(@security_service).to receive(:hasViewOrOperatePermissionForPipeline).and_return(true)
      expect(@template_config_service).to receive(:getTemplateViewModels).with(anything).and_return([])

      get :new, params:{:group => "foo.bar"}

      expect(assigns[:group_name]).to eq("foo.bar")
      list_of_pipelines = java.util.ArrayList.new
      list_of_pipelines.add(CaseInsensitiveString.new("new_pipeline"))
      expect(assigns[:all_pipelines]).to eq(list_of_pipelines)
    end

    it "should have template list assigned" do
      expect(@go_config_service).to receive(:getCurrentConfig).and_return(@cruise_config)
      template_name = "someTemplateName"
      GoConfigMother.new.addPipelineWithTemplate(@cruise_config, "someTemplatePipeline", template_name, "stageName", ["jobName"].to_java(java.lang.String))

      list_of_templates = [TemplatesViewModel.new(@cruise_config.getTemplateByName(CaseInsensitiveString.new(template_name)), true, true)]
      expect(@template_config_service).to receive(:getTemplateViewModels).with(anything).and_return(list_of_templates)

      get :new

      expect(assigns[:template_list]).to eq(list_of_templates)
    end

    it "should have pipelines using templates listed in the pipelineStageJsontemplate list assigned" do
      template_name = "someTemplateName"
      cruise_config_interpolated = BasicCruiseConfig.new
      @cruise_config_mother.addPipeline(@cruise_config, "pipeline2", "stage-2", ["job-2"].to_java(java.lang.String))
      @cruise_config_mother.addPipelineWithTemplate(@cruise_config, "someTemplatePipeline", template_name, "stageName", ["jobName"].to_java(java.lang.String))

      @cruise_config_mother.addPipeline(cruise_config_interpolated, "pipeline2", "stage-2", ["job-2"].to_java(java.lang.String))
      @cruise_config_mother.addPipeline(cruise_config_interpolated, "someTemplatePipeline", "templateStage", ["templateJob"].to_java(java.lang.String))

      list_of_templates = [TemplatesViewModel.new(@cruise_config.getTemplateByName(CaseInsensitiveString.new(template_name)), true, true)]
      expect(@template_config_service).to receive(:getTemplateViewModels).with(anything).and_return(list_of_templates)

      allow(@security_service).to receive(:hasViewOrOperatePermissionForPipeline).and_return(true)

      expect(@go_config_service).to receive(:getCurrentConfig).and_return(cruise_config_interpolated)

      get :new

      expect(assigns[:pipeline_stages_json]).to eq("[{\"pipeline\":\"pipeline2\",\"stage\":\"stage-2\"},{\"pipeline\":\"someTemplatePipeline\",\"stage\":\"templateStage\"}]")
    end

    it "should have modifiable group and pipelineStageJson for DependencyMaterial is assigned" do
      @cruise_config_mother.addPipeline(@cruise_config, "pipeline2", "stage-2", ["job-2"].to_java(java.lang.String))
      @cruise_config_mother.addPipeline(@cruise_config, "a", "b", ["job-1"].to_java(java.lang.String))
      @cruise_config_mother.addPipeline(@cruise_config, "pipeline1", "stage-1", ["job-1"].to_java(java.lang.String))
      @cruise_config_mother.addPipeline(@cruise_config, "Ab", "stage-1", ["job-1"].to_java(java.lang.String))

      expect(@template_config_service).to receive(:getTemplateViewModels).with(anything).and_return([])
      allow(@security_service).to receive(:hasViewOrOperatePermissionForPipeline).and_return(true)

      expect(@go_config_service).to receive(:getCurrentConfig).and_return(@cruise_config)

      get :new

      expect(assigns[:groups_json]).to eq([{"group" => "group1"}, {"group" => "group2"}].to_json)
      expect(assigns[:pipeline_stages_json]).to eq("[{\"pipeline\":\"a\",\"stage\":\"b\"},{\"pipeline\":\"Ab\",\"stage\":\"stage-1\"},{\"pipeline\":\"pipeline1\",\"stage\":\"stage-1\"},{\"pipeline\":\"pipeline2\",\"stage\":\"stage-2\"}]")
    end
  end

  describe "create" do
    before :each do
      set_up_registry
      task_preference = com.thoughtworks.go.plugin.access.pluggabletask.TaskPreference.new(TaskMother::ApiTaskForTest.new)
      PluggableTaskConfigStore.store().setPreferenceFor("curl.plugin", task_preference)
    end

    after :each do
      unload_all_from_registry
      PluggableTaskConfigStore.store().removePreferenceFor("curl.plugin")
    end

    before(:each) do
      PackageMetadataStore.getInstance().removeMetadata("pluginid")

      @cruise_config_mother = GoConfigMother.new
      @result = HttpLocalizedOperationResult.new
      allow(HttpLocalizedOperationResult).to receive(:new).and_return(@result)

      allow(@go_config_service).to receive(:checkConfigFileValid).and_return(com.thoughtworks.go.config.validation.GoConfigValidity.valid())
      allow(@go_config_service).to receive(:rolesForUser).and_return(nil)
      @cruise_config = BasicCruiseConfig.new
      @repository1 = PackageRepositoryMother.create("repo-id", "repo1-name", "pluginid", "version1.0", Configuration.new([ConfigurationPropertyMother.create("k1", false, "v1")].to_java(ConfigurationProperty)))
      @pkg = PackageDefinitionMother.create("pkg-id", "package3-name", Configuration.new([ConfigurationPropertyMother.create("k2", false, "p3v2")].to_java(ConfigurationProperty)), @repository1)
      @repository1.setPackages(Packages.new([@pkg].to_java(PackageDefinition)))
      repos = PackageRepositories.new
      repos.add(@repository1)
      @cruise_config.setPackageRepositories(repos)
      expect(@go_config_service).to receive(:getConfigForEditing).and_return(GoConfigCloner.new().deepClone(@cruise_config))
      allow(@go_config_service).to receive(:registry)
      ReflectionUtil.setField(@cruise_config, "md5", "1234abcd")
      @pause_info = PipelinePauseInfo.paused("just for fun", "loser")
      allow(@pipeline_pause_service).to receive(:pipelinePauseInfo).with("new-pip").and_return(@pause_info)

      allow(@pipeline_selections_service).to receive(:update)
      allow(controller).to receive(:cookies).and_return({})
      allow(@security_service).to receive(:modifiableGroupsForUser).with(@user).and_return(["group1", "group2"])
    end

    after(:each) do
      PackageMetadataStore.getInstance().removeMetadata("pluginid")
    end

    it "should populate group name from the submitted value if it is present" do
      expect(@template_config_service).to receive(:getTemplateViewModels).with(anything).and_return([])
      expect(@go_config_service).to receive(:getCurrentConfig).twice.and_return(GoConfigCloner.new().deepClone(@cruise_config))

      stub_save_for_success
      expect(@pipeline_pause_service).to receive(:pause).with("new-pip", "Under construction", @user)

      post :create, params:{:config_md5 => "1234abcd", :pipeline_group => {:group => "new-group", :pipeline => {:name => "new-pip"}}}

      expect(assigns[:group_name]).to eq("new-group")
    end

    it "should create a new pipeline in a new pipeline group and pause the pipeline" do
      expect(@template_config_service).to receive(:getTemplateViewModels).with(anything).and_return([])
      expect(@go_config_service).to receive(:getCurrentConfig).twice.and_return(GoConfigCloner.new().deepClone(@cruise_config))

      stub_save_for_success
      expect(@pipeline_pause_service).to receive(:pause).with("new-pip", "Under construction", @user)

      post :create, params:{:config_md5 => "1234abcd", :pipeline_group => {:group => "new-group", :pipeline => {:name => "new-pip"}}}

      expect(@cruise_config.getAllErrors().size).to eq(0)
      expect(assigns[:pause_info]).to eq(@pause_info)
      assert_save_arguments
      assert_update_command ::ConfigUpdate::SaveAction, ::ConfigUpdate::RefsAsUpdatedRefs
      expect(response).to redirect_to anything
    end

    it "should update a users pipeline selections when that user successfully creates a new pipeline" do
      expect(@template_config_service).to receive(:getTemplateViewModels).with(anything).and_return([])
      pipeline_name = "new-pip"

      current_user_entity_id = 9999
      allow(controller).to receive(:current_user_entity_id).and_return(current_user_entity_id)

      selected_pipeline_id = "456"
      allow(controller).to receive(:cookies).and_return(cookiejar={:selected_pipelines => selected_pipeline_id})

      expect(@go_config_service).to receive(:getCurrentConfig).twice.and_return(GoConfigCloner.new().deepClone(@cruise_config))
      expect(@pipeline_pause_service).to receive(:pause).with("new-pip", "Under construction", @user)
      expect(@pipeline_selections_service).to receive(:update).with(selected_pipeline_id, current_user_entity_id, CaseInsensitiveString.new(pipeline_name))

      stub_save_for_success
      post :create, params:{:config_md5 => "1234abcd", :pipeline_group => {:group => "new-group", :pipeline => {:name => pipeline_name}}}
    end

    it "should NOT update a users pipeline selections when that user does not successfully creates a new pipeline" do
      expect(@template_config_service).to receive(:getTemplateViewModels).with(anything).and_return([])
      expect(@task_view_service).to receive(:getTaskViewModels).and_return(Object.new)
      expect(@task_view_service).to receive(:getViewModel).with(anything, anything).and_return(TaskViewModel.new(nil, nil))
      expect(@task_view_service).to receive(:getModelOfType).with(anything, anything).and_return(TaskViewModel.new(nil, nil))
      allow(@security_service).to receive(:hasViewOrOperatePermissionForPipeline).and_return(true)

      pipeline_name = "new-pip"

      expect(@go_config_service).to receive(:getCurrentConfig).twice.and_return(GoConfigCloner.new().deepClone(@cruise_config))
      expect(@pipeline_selections_service).not_to receive(:update)

      stub_save_for_validation_error do |result, _, _|
        result.forbidden("unauthorized", nil)
      end
      post :create, params:{:config_md5 => "1234abcd", :pipeline_group => {:group => "new-group", :pipeline => {:name => pipeline_name}}}
    end

    it "should create a new pipeline based on a template" do
      template_name = "some_template"
      @cruise_config.addTemplate(PipelineTemplateConfigMother.createTemplate(template_name))
      list_of_templates = [TemplatesViewModel.new(@cruise_config.getTemplateByName(CaseInsensitiveString.new(template_name)), true, true)]
      expect(@template_config_service).to receive(:getTemplateViewModels).with(anything).and_return(list_of_templates)

      expect(@go_config_service).to receive(:getCurrentConfig).twice.and_return(GoConfigCloner.new().deepClone(@cruise_config))

      stub_save_for_success
      expect(@pipeline_pause_service).to receive(:pause).with("new-pip", "Under construction", @user)

      post :create, params:{:config_md5 => "1234abcd", :pipeline_group => {:group => "new-group", :pipeline => {:name => "new-pip", :configurationType => PipelineConfig::CONFIGURATION_TYPE_TEMPLATE, :templateName => template_name}}}

      expect(@cruise_config.getAllErrors().size).to eq(0)
      expect(assigns[:pause_info]).to eq(@pause_info)
      assert_save_arguments
      assert_update_command ::ConfigUpdate::SaveAction, ::ConfigUpdate::RefsAsUpdatedRefs
      expect(response).to redirect_to anything
    end

    it "should throw up if pipeline name is empty and populate all states required for new action" do
      expect(@template_config_service).to receive(:getTemplateViewModels).with(anything).and_return([])
      @cruise_config_mother.addPipeline(@cruise_config, "pipeline2", "stage-2", ["job-2"].to_java(java.lang.String))

      task_view_models = Object.new()
      expect(@task_view_service).to receive(:getTaskViewModels).and_return(task_view_models)
      expect(@task_view_service).to receive(:getViewModel).with(anything, anything).and_return(TaskViewModel.new(nil, nil))
      expect(@task_view_service).to receive(:getModelOfType).with(anything, anything).and_return(TaskViewModel.new(nil, nil))
      allow(@security_service).to receive(:hasViewOrOperatePermissionForPipeline).and_return(true)

      expect(@go_config_service).to receive(:getCurrentConfig).twice.and_return(GoConfigCloner.new().deepClone(@cruise_config))

      @pause_info = PipelinePauseInfo.paused("just for fun", "loser")
      expect(@pipeline_pause_service).to receive(:pipelinePauseInfo).with("").and_return(@pause_info)

      stub_save_for_validation_error do |result, cruise_config, pipeline|
        pipeline.addError("name", "empty pipeline name")
        result.badRequest("Save failed, see errors below");
      end

      post :create, params:{:config_md5 => "1234abcd", :pipeline_group => {:group => "new-group", :pipeline => {:name => ""}}}

      expect(assigns[:errors].size).to eq(1)
      expect(assigns[:errors][0]).to eq("empty pipeline name")
      expect(assigns[:groups_json]).to eq([{"group" => "group1"}, {"group" => "group2"}].to_json)
      expect(assigns[:pipeline_stages_json]).to eq("[{\"pipeline\":\"pipeline2\",\"stage\":\"stage-2\"}]")
      job_configs = JobConfigs.new([JobConfig.new(CaseInsensitiveString.new("defaultJob"), ResourceConfigs.new, ArtifactConfigs.new, com.thoughtworks.go.config.Tasks.new([AntTask.new].to_java(Task)))].to_java(JobConfig))
      stage_config = StageConfig.new(CaseInsensitiveString.new("defaultStage"), job_configs)
      pipeline_config = PipelineConfig.new(CaseInsensitiveString.new(""), com.thoughtworks.go.config.materials.MaterialConfigs.new, [stage_config].to_java(StageConfig))
      expect(assigns[:pipeline]).to eq(pipeline_config)
      expect(assigns[:pipeline_group]).to eq(BasicPipelineConfigs.new("new-group", Authorization.new, [pipeline_config].to_java(PipelineConfig)))
      expect(assigns[:group_name]).to eq("new-group")
      expect(assigns[:task_view_models]).to eq(task_view_models)
      list_of_pipelines = java.util.ArrayList.new
      list_of_pipelines.add(CaseInsensitiveString.new("pipeline2"))
      expect(assigns[:all_pipelines]).to eq(list_of_pipelines)
      assert_save_arguments
      assert_template "new"
      assert_template layout: "application"
      expect(response.status).to eq(400)
    end

    it "should handle validation errors for a pipeline based on a template" do
      template_name = "some_template"
      @cruise_config.addTemplate(PipelineTemplateConfigMother.createTemplate(template_name))
      list_of_templates = [TemplatesViewModel.new(@cruise_config.getTemplateByName(CaseInsensitiveString.new(template_name)), true, true)]
      expect(@template_config_service).to receive(:getTemplateViewModels).with(anything).and_return(list_of_templates)

      @cruise_config_mother.addPipeline(@cruise_config, "pipeline2", "stage-2", ["job-2"].to_java(java.lang.String))
      task_view_models = Object.new()
      expect(@task_view_service).to receive(:getTaskViewModels).and_return(task_view_models)
      expect(@security_service).to receive(:modifiableGroupsForUser).with(@user).and_return(["group1", "group2"])
      allow(@security_service).to receive(:hasViewOrOperatePermissionForPipeline).and_return(true)

      expect(@go_config_service).to receive(:getCurrentConfig).twice.and_return(GoConfigCloner.new().deepClone(@cruise_config))

      @pause_info = PipelinePauseInfo.paused("just for fun", "loser")
      expect(@pipeline_pause_service).to receive(:pipelinePauseInfo).with("").and_return(@pause_info)

      stub_save_for_validation_error do |result, cruise_config, pipeline|
        pipeline.addError("name", "empty pipeline name")
        result.badRequest("Save failed, see errors below");
      end

      post :create, params:{:config_md5 => "1234abcd", :pipeline_group => {:group => "new-group", :pipeline => {:name => "", :configurationType => PipelineConfig::CONFIGURATION_TYPE_TEMPLATE, :templateName => "some_template"}}}

      expect(assigns[:errors].size).to eq(1)
      expect(assigns[:errors][0]).to eq("empty pipeline name")
      expect(assigns[:group_name]).to eq("new-group")
      expect(assigns[:task_view_models]).to eq(task_view_models)
      assert_save_arguments
      assert_template "new"
      assert_template layout: "application"
      expect(response.status).to eq(400)
    end

    it "should load group name if user does not have permission for that group" do
      expect(@template_config_service).to receive(:getTemplateViewModels).with(anything).and_return([])
      allow(@security_service).to receive(:hasViewOrOperatePermissionForPipeline).and_return(true)
      expect(@task_view_service).to receive(:taskInstanceFor).with("ant").and_return(AntTask.new)
      task_view_models = Object.new()
      expect(@task_view_service).to receive(:getTaskViewModels).and_return(task_view_models)
      expect(@task_view_service).to receive(:getViewModel).with(anything, anything).and_return(TaskViewModel.new(nil, nil))
      expect(@task_view_service).to receive(:getModelOfType).with(anything, anything).and_return(TaskViewModel.new(nil, nil))
      @cruise_config_mother.addPipeline(@cruise_config, "pipeline2", "stage-2", ["job-2"].to_java(java.lang.String))
      expect(@go_config_service).to receive(:getCurrentConfig).twice.and_return(GoConfigCloner.new().deepClone(@cruise_config))

      stub_save_for_validation_error do |result, cruise_config, node|
        result.forbidden("unauthorized", nil)
      end

      job = {:name => "job", :tasks => {:taskOptions => "ant", "ant" => {}}}
      stage = {:name => "stage", :jobs => [job]}
      post :create, params:{:config_md5 => "1234abcd", :pipeline_group => {:group => "defaultGroup", :pipeline => {:name => "new-pip", :stage => stage}}}

      expect(assigns[:group_name]).to eq("defaultGroup")
    end

    it "should populate new package material with submitted value if it is present" do
      expect(@template_config_service).to receive(:getTemplateViewModels).with(anything).and_return([])
      expect(@go_config_service).to receive(:getCurrentConfig).twice.and_return(GoConfigCloner.new().deepClone(@cruise_config))

      stub_save_for_success
      expect(@pipeline_pause_service).to receive(:pause).with("new-pip", "Under construction", @user)

      pkg_params = {:create_or_associate_pkg_def => "associate", :package_definition => {:repositoryId => "repo-id"}, :packageId => "pkg-id"}
      post :create, params:{:config_md5 => "1234abcd", :pipeline_group => {:group => "new-group", :pipeline => {:name => "new-pip", :materials => {:materialType => PackageMaterialConfig::TYPE}}}, :material => pkg_params}

      expect(assigns[:group_name]).to eq("new-group")
      new_pipeline = @cruise_config.getPipelineConfigByName(CaseInsensitiveString.new("new-pip"))
      expect(new_pipeline.material_configs.get(0).type).to eq(PackageMaterialConfig::TYPE)
      expect(new_pipeline.material_configs.get(0).getPackageId()).to eq("pkg-id")
    end

    it "should create new package material with submitted value if it is present" do
      expect(@template_config_service).to receive(:getTemplateViewModels).with(anything).and_return([])
      expect(@go_config_service).to receive(:getCurrentConfig).twice.and_return(GoConfigCloner.new().deepClone(@cruise_config))

      stub_save_for_success
      expect(@pipeline_pause_service).to receive(:pause).with("new-pip", "Under construction", @user)

      pkg_params = {:create_or_associate_pkg_def => "create", :package_definition => {:repositoryId => "repo-id", :name => "pkg-name"}}
      post :create, params:{:config_md5 => "1234abcd", :pipeline_group => {:group => "new-group", :pipeline => {:name => "new-pip", :materials => {:materialType => PackageMaterialConfig::TYPE}}}, :material => pkg_params}

      expect(assigns[:group_name]).to eq("new-group")
      new_pipeline = @cruise_config.getPipelineConfigByName(CaseInsensitiveString.new("new-pip"))
      expect(new_pipeline.material_configs.get(0).type).to eq(PackageMaterialConfig::TYPE)
      expect(new_pipeline.material_configs.get(0).getPackageDefinition().getName()).to eq("pkg-name")
    end

    it "should load package material data if pipeline save fails" do
      expect(@template_config_service).to receive(:getTemplateViewModels).with(anything).and_return([])
      expect(@task_view_service).to receive(:getTaskViewModels).and_return(Object.new())
      expect(@task_view_service).to receive(:getViewModel).with(anything, anything).and_return(TaskViewModel.new(nil, nil))
      expect(@task_view_service).to receive(:getModelOfType).with(anything, anything).and_return(TaskViewModel.new(nil, nil))
      allow(@security_service).to receive(:hasViewOrOperatePermissionForPipeline).and_return(true)
      package_material_config = PackageMaterialConfig.new()
      package_material_config.setPackageDefinition(PackageDefinitionMother.create("pkg-id", "package3-name", nil, @repository1))
      @pipeline = @cruise_config_mother.addPipeline(@cruise_config, "pipeline2", "stage-2", MaterialConfigs.new([package_material_config].to_java(com.thoughtworks.go.domain.materials.MaterialConfig)), ["job-2"].to_java(java.lang.String))
      @subject = @pipeline
      expect(@go_config_service).to receive(:getCurrentConfig).twice.and_return(GoConfigCloner.new().deepClone(@cruise_config))

      stub_save_for_validation_error do |result, cruise_config, node|
        result.forbidden("unauthorized", nil)
      end

      allow(@pipeline_pause_service).to receive(:pipelinePauseInfo).with("pipeline2").and_return(@pause_info)
      PackageMetadataStore.getInstance().addMetadataFor("pluginid", PackageConfigurations.new())

      # params do not matter since we have stubbed save for error & @pipeline is the object that is worked upon
      pkg_params = {:create_or_associate_pkg_def => "associate", :package_definition => {:repositoryId => "repo-id"}, :packageId => "pkg-id"}
      post :create, params:{:config_md5 => "1234abcd", :pipeline_group => {:group => "defaultGroup", :pipeline => {:name => "new-pip", :materials => {:materialType => PackageMaterialConfig::TYPE}}}, :material => pkg_params}

      expect(assigns[:group_name]).to eq("defaultGroup")
      expect(assigns[:package_configuration].name).to eq("package3-name")
    end

    it "should be able to create a pipeline with a pluggable task" do
      expect(@template_config_service).to receive(:getTemplateViewModels).with(anything).and_return([])
      allow(@pluggable_task_service).to receive(:validate)
      @new_task = PluggableTask.new( PluginConfiguration.new("curl.plugin", "1.0"), Configuration.new([ConfigurationPropertyMother.create("Url", false, nil)].to_java(ConfigurationProperty)))
      expect(@task_view_service).to receive(:taskInstanceFor).with("pluggableTask").and_return(@new_task)
      expect(@go_config_service).to receive(:getCurrentConfig).twice.and_return(GoConfigCloner.new().deepClone(@cruise_config))
      stub_save_for_success
      pipeline_name = "new-pip"
      expect(@pipeline_pause_service).to receive(:pause).with(pipeline_name, "Under construction", @user)

      job = {:name => "job", :tasks => {:taskOptions => "pluggableTask", "pluggableTask" => {:foo => "bar"}}}
      stage = {:name => "stage", :jobs => [job]}
      post :create, params:{:config_md5 => "1234abcd", :pipeline_group => {:group => "new-group", :pipeline => {:name => pipeline_name, :stage => stage}}}

      expect(@cruise_config.getAllErrors().size).to eq(0)
      expect(assigns[:pause_info]).to eq(@pause_info)
      assert_save_arguments
      assert_update_command ::ConfigUpdate::SaveAction, ::ConfigUpdate::RefsAsUpdatedRefs
      pipeline_config = @cruise_config.getPipelineConfigByName(CaseInsensitiveString.new(pipeline_name))
      expect(pipeline_config.getFirstStageConfig().getJobs().first().getTasks().first().instance_of?(PluggableTask)).to eq(true)
      expect(response).to redirect_to anything
    end

    it "should validate pluggable tasks before create" do
      expect(@template_config_service).to receive(:getTemplateViewModels).with(anything).and_return([])
      allow(@pluggable_task_service).to receive(:validate) do |task|
        task.getConfiguration().getProperty("key").addError("key", "some error")
      end
      @new_task = PluggableTask.new( PluginConfiguration.new("curl.plugin", "1.0"), Configuration.new([ConfigurationPropertyMother.create("key", false, nil)].to_java(ConfigurationProperty)))
      expect(@task_view_service).to receive(:taskInstanceFor).with("pluggableTask").and_return(@new_task)
      expect(@task_view_service).to receive(:getViewModel).with(@new_task, "new").and_return(TaskViewModel.new(nil, nil))
      expect(@task_view_service).to receive(:getModelOfType).with(anything, anything).and_return(TaskViewModel.new(nil, nil))
      expect(@go_config_service).to receive(:getCurrentConfig).twice.and_return(GoConfigCloner.new().deepClone(@cruise_config))
      stub_save_for_validation_error do |result, cruise_config, pipeline|
        result.badRequest("Save failed, see errors below")
      end
      expect(@task_view_service).to receive(:getTaskViewModels).and_return(Object.new())
      pipeline_name = "new-pip"

      job = {:name => "job", :tasks => {:taskOptions => "pluggableTask", "pluggableTask" => {:key => "value"}}}
      stage = {:name => "stage", :jobs => [job]}
      post :create, params:{:config_md5 => "1234abcd", :pipeline_group => {:group => "new-group", :pipeline => {:name => pipeline_name, :stage => stage}}}

      task_to_be_saved = assigns[:pipeline].getFirstStageConfig().getJobs().first().getTasks().first()
      expect(task_to_be_saved.instance_of?(PluggableTask)).to eq(true)
      expect(task_to_be_saved.getConfiguration().getProperty("key").errors().getAll().size()).to be > 0
      expect(task_to_be_saved.getConfiguration().getProperty("key").errors().getAllOn("key").get(0)).to eq("some error")
      assert_template "new"
      assert_template layout: "application"
      expect(response.status).to eq(400)
    end
  end

  describe "clone" do

    before :each do
      allow(controller).to receive(:go_config_service).with(no_args).and_return(@go_config_service = double('Go Config Service'))
      allow(@go_config_service).to receive(:checkConfigFileValid).and_return(com.thoughtworks.go.config.validation.GoConfigValidity.valid())
      allow(controller).to receive(:security_service).and_return(@security_service = double('Security Service'))
      @cruise_config = BasicCruiseConfig.new
      @pipeline = PipelineConfigMother.pipelineConfig("foo.bar")
      @cruise_config.addPipeline("group1", @pipeline)
      expect(@go_config_service).to receive(:getConfigForEditing).and_return(@cruise_config)
      expect(@security_service).to receive(:modifiableGroupsForUser).with(@user).and_return(["group1", "group2"])
      allow(@go_config_service).to receive(:registry)
    end

    describe "clone:get" do
      it "should populate variables for cloning pipeline with pipeline name and group" do
        get :clone, params:{:pipeline_name => "foo.bar", :config_md5 => "1234abcd", :group => "group1"}

        clonedPipeline = @pipeline.duplicate()
        expect(assigns[:pipeline]).to eq(clonedPipeline)
        expect(assigns[:pipeline_group]).to eq(BasicPipelineConfigs.new([clonedPipeline].to_java(PipelineConfig)))
        expect(assigns[:group_name]).to eq("group1")
        expect(assigns[:groups_list]).to eq(["group1", "group2"])
        expect(assigns[:groups_json]).to eq([{"group" => "group1"}, {"group" => "group2"}].to_json)
        assert_template layout: false
      end
    end

    describe "save_clone" do
      before :each do
        allow(@pipeline_pause_service).to receive(:pause)
        allow(@pipeline_selections_service).to receive(:update)
      end

      it "should save cloned pipeline successfully" do
        @cruise_config.addPipeline("foo.bar", @pipeline)
        stub_save_for_success
        expect(@pipeline_pause_service).to receive(:pause).with("new-pip", "Under construction", @user)

        post :save_clone, params:{:config_md5 => "1234abcd", :pipeline_group => {:group => "group1", :pipeline => {:name => "new-pip"}}, :pipeline_name => @pipeline.name().to_s}

        expect(@cruise_config.getAllErrors().size).to eq(0)
        expect(assigns[:pause_info]).to eq(@pause_info)

        expect(response.location).to match(/\/admin\/pipelines\/new-pip\/general/)
        expect(response.status).to eq(200)
        expect(response.body).to eq("Saved successfully")
      end

      it "should save cloned pipeline successfully when group is not set" do
        @cruise_config.addPipeline("foo.bar", @pipeline)
        stub_save_for_success
        expect(@pipeline_pause_service).to receive(:pause).with("new-pip", "Under construction", @user)

        post :save_clone, params:{:config_md5 => "1234abcd", :pipeline_group => {:pipeline => {:name => "new-pip"}}, :pipeline_name => @pipeline.name().to_s}

        expect(@cruise_config.getAllErrors().size).to eq(0)
        expect(assigns[:pause_info]).to eq(@pause_info)

        expect(response.location).to match(/\/admin\/pipelines\/new-pip\/general/)
        expect(response.status).to eq(200)
        expect(response.body).to eq("Saved successfully")
      end

      it "should show validation errors" do
        @cruise_config.addPipeline("foo.bar", @pipeline)
        stub_save_for_validation_error do |result, _, node|
           node.addError("name", "Pipeline name is not unique")
           result.badRequest("Failed to update pipeline 'pipeline-name'.")
        end

        post :save_clone, params:{:config_md5 => "1234abcd", :pipeline_group => {:group => "group1", :pipeline => {:name => "new-pip"}}, :pipeline_name => @pipeline.name().to_s}

        expect(@cruise_config.getAllErrors().size).to eq(1)
        expect(assigns[:errors].size).to eq(1)
        expect(response.status).to eq(400)
        expect(response.location).to be_nil
      end

      it "should update the user's pipeline selections when save clone is successful" do
        @cruise_config.addPipeline("foo.bar", @pipeline)
        stub_save_for_success

        current_user_entity_id = 9999
        allow(controller).to receive(:current_user_entity_id).and_return(current_user_entity_id)

        selected_pipeline_id = "456"
        allow(controller).to receive(:cookies).and_return(cookiejar={:selected_pipelines => selected_pipeline_id})

        expect(@pipeline_selections_service).to receive(:update).with(selected_pipeline_id, current_user_entity_id, CaseInsensitiveString.new("new-pip"))

        post :save_clone, params:{:config_md5 => "1234abcd", :pipeline_group => {:group => "group1", :pipeline => {:name => "new-pip"}}, :pipeline_name => @pipeline.name().to_s}
      end

      it "should not update the user's pipeline selections when save clone is not successful" do
        stub_save_for_validation_error do |result, _, _|
          result.badRequest("Failed to update pipeline 'pipeline-name'.")
        end

        post :save_clone, params:{:config_md5 => "1234abcd", :pipeline_group => {:group => "group1", :pipeline => {:name => "new-pip"}}, :pipeline_name => @pipeline.name().to_s}

        expect(@pipeline_selections_service).to_not receive(:update)
      end
    end
  end

  describe "clone with error" do
    before :each do
      allow(@go_config_service).to receive(:checkConfigFileValid).and_return(com.thoughtworks.go.config.validation.GoConfigValidity.valid())
      @cruise_config = BasicCruiseConfig.new
      expect(@go_config_service).to receive(:getConfigForEditing).and_return(@cruise_config)
      allow(@go_config_service).to receive(:registry)
    end
    it "should render error if pipeline to be cloned does not exist" do
      get :clone, params:{:pipeline_name => "doesNotExist", :config_md5 => "1234abcd", :group => "group1"}

      expect(response.response_code).to eq(404)
      assert_template layout: "application"
    end
  end
end


text:
	<link rel="stylesheet" type="text/css" href="/stylesheets/styles.css">

Blog

	<form method="post">

Subject

			<input type="text" name="subject" value={{subject}} >

Blog Post

			<textarea name="content">{{content}}</textarea>

{{error}}

		<input type="submit">
	</form>


text:
<!DOCTYPE html>

    <META http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Content moved</title>
    <meta name="author" content="Mark Seemann">
    <meta http-equiv="refresh" content="0;/2009/10/05/Writingabook"><link rel="canonical" href="/2009/10/05/Writingabook">

    This page has moved to /2009/10/05/Writingabook.


text:
MultiPoint
==========

  .. autoclass:: geoscript.geom.MultiPoint


text:
package io.opentelemetry.sdk.trace;

import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.utility.DockerImageName;
import org.testcontainers.utility.MountableFile;

public class SpanPipelineBenchmark {
  private SpanPipelineBenchmark() {}

  @State(Scope.Benchmark)
  public abstract static class AbstractProcessorBenchmark {
    private static final DockerImageName OTLP_COLLECTOR_IMAGE =
        DockerImageName.parse("otel/opentelemetry-collector-dev:latest");
    private static final int EXPOSED_PORT = 5678;
    private static final int HEALTH_CHECK_PORT = 13133;
    private Tracer tracer;
    private SdkTracerProvider tracerProvider;

    protected abstract SpanProcessor getSpanProcessor(String collectorAddress);

    protected abstract void runThePipeline();

    protected void doWork() {
      for (int j = 0; j < 100; j++) {
        Span span = tracer.spanBuilder("PipelineBenchmarkSpan " + j).startSpan();
        for (int i = 0; i < 10; i++) {
          span.setAttribute("benchmarkAttribute_" + i, "benchmarkAttrValue_" + i);
        }
        span.end();
      }
      // we flush the SDK in order to make sure that the BatchSpanProcessor doesn't drop spans.
      // this means that this benchmark is mostly useful for measuring allocations, not throughput.
      tracerProvider.forceFlush().join(1, TimeUnit.SECONDS);
    }

    @Setup(Level.Trial)
    @SuppressWarnings("SystemOut")
    public void setup() {
      // Configuring the collector test-container
      GenericContainer<?> collector =
          new GenericContainer<>(OTLP_COLLECTOR_IMAGE)
              .withExposedPorts(EXPOSED_PORT, HEALTH_CHECK_PORT)
              .waitingFor(Wait.forHttp("/").forPort(HEALTH_CHECK_PORT))
              .withCopyFileToContainer(
                  MountableFile.forClasspathResource("/otel.yaml"), "/etc/otel.yaml")
              .withCommand("--config /etc/otel.yaml");

      collector.start();

      SpanProcessor spanProcessor = makeSpanProcessor(collector);

      tracerProvider =
          SdkTracerProvider.builder()
              .setSampler(Sampler.alwaysOn())
              .addSpanProcessor(spanProcessor)
              .build();

      tracer = tracerProvider.get("PipelineBenchmarkTracer");
    }

    private SpanProcessor makeSpanProcessor(GenericContainer<?> collector) {
      try {
        String host = collector.getHost();
        Integer port = collector.getMappedPort(EXPOSED_PORT);
        String address = new URL("http", host, port, "").toString();
        return getSpanProcessor(address);
      } catch (MalformedURLException e) {
        throw new IllegalStateException("can't make a url", e);
      }
    }

    @Benchmark
    @BenchmarkMode(Mode.Throughput)
    @Warmup(iterations = 5, time = 1)
    @Measurement(iterations = 15, time = 1)
    @OutputTimeUnit(TimeUnit.SECONDS)
    @Fork(1)
    @Threads(1)
    public void measureSpanPipeline() {
      runThePipeline();
    }
  }

  public static class SimpleSpanProcessorBenchmark extends AbstractProcessorBenchmark {
    @Override
    protected SpanProcessor getSpanProcessor(String collectorAddress) {
      return SimpleSpanProcessor.create(
          OtlpGrpcSpanExporter.builder()
              .setEndpoint(collectorAddress)
              .setTimeout(Duration.ofSeconds(50))
              .build());
    }

    @Override
    protected void runThePipeline() {
      doWork();
    }
  }

  public static class BatchSpanProcessorBenchmark extends AbstractProcessorBenchmark {

    @Override
    protected SpanProcessor getSpanProcessor(String collectorAddress) {
      return BatchSpanProcessor.builder(
              OtlpGrpcSpanExporter.builder()
                  .setEndpoint(collectorAddress)
                  .setTimeout(Duration.ofSeconds(50))
                  .build())
          .build();
    }

    @Override
    protected void runThePipeline() {
      doWork();
    }
  }
}


text:
void glInit()
{
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0.0, WINDOW_WIDTH, WINDOW_HEIGHT, 1.0, -1.0, 1.0);
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  glClearColor(0.0, 0.0, 0.0, 0.0);
}

void runGameEvents(int *isRunning)
{
  SDL_Event event;
  while(SDL_PollEvent(&event))
  {
    switch(event.type)
    {
      case SDL_QUIT:
        *isRunning = 0;
        break;
      case SDL_KEYDOWN:
        if(event.key.keysym.sym == SDLK_ESCAPE)
          *isRunning = 0;
        break;
      default:
        break;
    }
  }
}

void processKeypresses(Uint8 *keys, World *world, unsigned int entity)
{
  world->input[entity].keyLeft = keys[SDLK_LEFT];
  world->input[entity].keyRight = keys[SDLK_RIGHT];
  world->input[entity].keyFire = keys[SDLK_SPACE];
}

int getFontTexture(char* text)
{
  SDL_Color textColor = { 55, 255, 5 };
  TTF_Font *font = TTF_OpenFont("FreeSans.ttf", 92);
  SDL_Surface *surface = TTF_RenderText_Blended(font, text, textColor);
  int colors = surface->format->BytesPerPixel;
  int format;
  GLuint texture;

  if(colors == 4)
  {
    if(surface->format->Rmask == 0x000000ff)
      format = GL_RGBA;
    else
      format = GL_BGRA;
  }
  else
  {
    if(surface->format->Rmask == 0x000000ff)
      format = GL_RGB;
    else
      format = GL_BGR;
  }

  glGenTextures(1, &texture);
  glBindTexture(GL_TEXTURE_2D, texture);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexImage2D(GL_TEXTURE_2D, 0, colors, surface->w, surface->h, 0, format, GL_UNSIGNED_BYTE, surface->pixels);
  SDL_FreeSurface(surface);
  TTF_CloseFont(font);
  return texture;
}

void drawFont(char* text)
{
  int texture = getFontTexture(text);
  glBindTexture(GL_TEXTURE_2D, texture);
  glEnable(GL_TEXTURE_2D);
  glColor3f(1.0, 1.0, 1.0);
  glPushMatrix();
  glBegin(GL_QUADS);
  glTexCoord2i(0, 0);
  glVertex2f(50, 500);
  glTexCoord2i(1, 0);
  glVertex2f(150, 500);
  glTexCoord2i(1, 1);
  glVertex2f(150, 530);
  glTexCoord2i(0, 1);
  glVertex2f(50, 530);
  glEnd();
  glDisable(GL_TEXTURE_2D );
  glPopMatrix();
  glFlush();
}

typedef struct
{
  unsigned int entity;
  int destinations[5];
  int cd;
} Drone;

Drone drones[10];

void createDrones(World *world)
{
  for(int x = 0; x < 10; ++x)
  {
    drones[x].entity = createDumbDrone(world, -20 - (x*25), 500, 20.0f, 20.0f);
    drones[x].destinations[0] = 200;
    drones[x].destinations[1] = 100;
    drones[x].destinations[2] = 200 + (x * 50);
    drones[x].cd = 0;
    world->velocity[drones[x].entity].x = 5;
  }
}
void moveDrones(World *world)
{
  for(int x = 0; x < 10; ++x)
  {
    if(drones[x].cd == 0 && world->position[drones[x].entity].x == drones[x].destinations[0])
    {
      world->velocity[drones[x].entity].x = 0;
      world->velocity[drones[x].entity].y = -5;
      drones[x].cd = 1;
    }
    if(drones[x].cd == 1 && world->position[drones[x].entity].y == drones[x].destinations[1])
    {
      world->velocity[drones[x].entity].y = 0;
      world->velocity[drones[x].entity].x = 5;
      drones[x].cd = 2;
    }
    if(drones[x].cd == 2 && world->position[drones[x].entity].x == drones[x].destinations[2])
    {
      world->velocity[drones[x].entity].x = 0;
      drones[x].cd = 3;
    }
  }

  if(drones[9].cd == 3)
  {
    for(int x = 0; x < 10; ++x)
    {
      world->mask[drones[x].entity][COMPONENT_AI] = COMPONENT_ENABLED;
      drones[x].cd = 4;
    }
  }
}

int main(void)
{
  SDL_Init(SDL_INIT_EVERYTHING);
  TTF_Init();
  SDL_Surface *screen = SDL_SetVideoMode(WINDOW_WIDTH, WINDOW_HEIGHT, 32, SDL_SWSURFACE|SDL_DOUBLEBUF|SDL_OPENGL);
  glInit();

  int isRunning = 1;
  Uint8 *keys = SDL_GetKeyState(NULL);

  World world;
  System render, player, movement, maxDuration, collision, collisionR, pfCollision, aifCollision, aiMove, aiFire;

  memset(&world, 0, sizeof(world));
  initializeWorld(&world);

  unsigned int hkship = createHKShip(&world, (WINDOW_WIDTH/2 - 25), (WINDOW_HEIGHT - 60), 50.0f, 40.0f, 0.0f, 0.0f, "hkship1.png");

  createDrones(&world);

  unsigned int renderComps[2] = {COMPONENT_POSITION, COMPONENT_SPRITE};
  render.maskCount = 2;
  render.function = &renderFunction;
  memcpy(&render.mask, &renderComps, sizeof(renderComps));

  unsigned int playerComps[4] = {COMPONENT_INPUT, COMPONENT_POSITION, COMPONENT_VELOCITY, COMPONENT_FIRE_DELAY};
  player.maskCount = 4;
  player.function = &playerControlFunction;
  memcpy(&player.mask, &playerComps, sizeof(playerComps));

  unsigned int movementComps[2] = {COMPONENT_POSITION, COMPONENT_VELOCITY};
  movement.maskCount = 2;
  movement.function = &movementFunction;
  memcpy(&movement.mask, &movementComps, sizeof(movementComps));

  unsigned int maxDurationComps[1] = {COMPONENT_MAX_DURATION};
  maxDuration.maskCount = 1;
  maxDuration.function = &maxDurationFunction;
  memcpy(&maxDuration.mask, &maxDurationComps, sizeof(maxDurationComps));

  unsigned int collisionComps[2] = {COMPONENT_COLLIDABLE, COMPONENT_POSITION};
  collision.maskCount = 2;
  collision.function = &collisionDetectionFunction;
  memcpy(&collision.mask, &collisionComps, sizeof(collisionComps));

  unsigned int collisionRComps[1] = {COMPONENT_COLLIDABLE};
  collisionR.maskCount = 1;
  collisionR.function = &collisionActionFunction;
  memcpy(&collisionR.mask, &collisionRComps, sizeof(collisionRComps));

  unsigned int aiMoveComps[3] = {COMPONENT_POSITION, COMPONENT_VELOCITY, COMPONENT_AI};
  aiMove.maskCount = 3;
  aiMove.function = &moveAIFunction;
  memcpy(&aiMove.mask, &aiMoveComps, sizeof(aiMoveComps));

  unsigned int aiFireComps[3] = {COMPONENT_POSITION, COMPONENT_FIRE_DELAY, COMPONENT_AI};
  aiFire.maskCount = 3;
  aiFire.function = &fireAIFunction;
  memcpy(&aiFire.mask, &aiFireComps, sizeof(aiFireComps));

  unsigned int pfcComps[2] = {COMPONENT_PLAYER_FRIENDLY, COMPONENT_COLLIDABLE};
  pfCollision.maskCount = 2;
  pfCollision.function = &playerFriendlyCollisionFunction;
  memcpy(&pfCollision.mask, &pfcComps, sizeof(pfcComps));

  unsigned int aicComps[2] = {COMPONENT_AI_FRIENDLY, COMPONENT_COLLIDABLE};
  aifCollision.maskCount = 2;
  aifCollision.function = &aiFriendlyCollisionFunction;
  memcpy(&aifCollision.mask, &aicComps, sizeof(aicComps));

  Uint32 start;
  Uint32 last = 1;
  while(isRunning)
  {
    start = SDL_GetTicks();

    runGameEvents(&isRunning);
    processKeypresses(keys, &world, hkship);
    runSystem(&player, &world);
    runSystem(&aiMove, &world);
    runSystem(&movement, &world);
    runSystem(&aiFire, &world);

    runSystem(&collision, &world);
    runSystem(&pfCollision, &world);
    runSystem(&aifCollision, &world);
    runSystem(&collisionR, &world);
    glClear(GL_COLOR_BUFFER_BIT);
    runSystem(&render, &world);
    moveDrones(&world);
    char temp[8];
    sprintf(temp, "FPS: %d", (1000/last) );
    drawFont(temp);
    runSystem(&maxDuration, &world);
    SDL_GL_SwapBuffers();

    if(1000/60 > (SDL_GetTicks() - start))
      SDL_Delay(1000/60 - (SDL_GetTicks() - start));
    last = (SDL_GetTicks() - start);
  }

  SDL_FreeSurface(screen);
  TTF_Quit();
  SDL_Quit();
  return 0;
}


text:
/*****************************************************************************
*
* exgssi - ex_get_size_set_ids
*
* author - Sandia National Laboratories
*          Larry A. Schoof - Original
*          James A. Schutt - 8 byte float and standard C definitions
*          Vic Yarberry    - Added headers and error logging
*
*
* environment - UNIX
*
* entry conditions -
*   input parameters:
*       int     exoid                   exodus file id
*
* exit conditions -
*       int*    size_set_ids            array of side set IDs
*
* revision history -
*
*  Id
*
*****************************************************************************/

#include <stdlib.h>
#include "exodusII.h"
#include "exodusII_int.h"

/*
 *  reads the side set ids from the database
 */

int ex_get_side_set_ids (int  exoid,
                         int *ids)
{
   int dimid, varid, iresult;
   long num_side_sets, start[1], count[1];
   nclong *longs;
   char errmsg[MAX_ERR_LENGTH];

   exerrval = 0;        /* clear error code */

/* inquire id's of previously defined dimensions and variables  */

   if ((dimid = ncdimid (exoid, DIM_NUM_SS)) < 0)
   {
     exerrval = ncerr;
     sprintf(errmsg,
            "Warning: no side sets stored in file id %d", exoid);
     ex_err("ex_get_side_set_ids",errmsg,exerrval);
     return (EX_WARN);
   }

   if (ncdiminq (exoid, dimid, (char *) 0, &num_side_sets) == -1)
   {
     exerrval = ncerr;
     sprintf(errmsg,
            "Error: failed to get number of side sets in file id %d", exoid);
     ex_err("ex_get_side_set_ids",errmsg,exerrval);
     return (EX_FATAL);
   }

   if ((varid = ncvarid (exoid, VAR_SS_IDS)) == -1)
   {
     exerrval = ncerr;
     sprintf(errmsg,
            "Error: failed to locate side set ids in file id %d", exoid);
     ex_err("ex_get_side_set_ids",errmsg,exerrval);
     return (EX_FATAL);
   }

/* read in the side set ids  */

/* application code has allocated an array of ints but netcdf is expecting
   a pointer to nclongs;  if ints are different sizes than nclongs,
   we must allocate an array of nclongs then convert them to ints with ltoi */

   start[0] = 0;
   count[0] = num_side_sets;

   if (sizeof(int) == sizeof(nclong)) {
      iresult = ncvarget (exoid, varid, start, count, ids);
   } else {
     if (!(longs = malloc(num_side_sets * sizeof(nclong)))) {
       exerrval = EX_MEMFAIL;
       sprintf(errmsg,
               "Error: failed to allocate memory for side set ids for file id %d",
               exoid);
       ex_err("ex_get_side_set_ids",errmsg,exerrval);
       return (EX_FATAL);
     }
     iresult = ncvarget (exoid, varid, start, count, longs);
   }

   if (iresult == -1)
   {
     exerrval = ncerr;
     sprintf(errmsg,
            "Error: failed to get side set ids in file id %d", exoid);
     ex_err("ex_get_side_set_ids",errmsg,exerrval);
     return (EX_FATAL);
   }

   if (sizeof(int) != sizeof(nclong)) {
      ltoi (longs, ids, num_side_sets);
      free (longs);
   }

   return(EX_NOERR);
}


text:
=====================================
Wiping clean the contents of a server
=====================================

.. index:: object: memcached_st

Wipe contents of memcached servers

--------
SYNOPSIS
--------

#include <libmemcached/memcached.h>

.. c:function:: memcached_return_t memcached_flush (memcached_st *ptr, time_t expiration)

Compile and link with -lmemcached

-----------
DESCRIPTION
-----------

:c:func::`memcached_flush` is used to wipe clean the contents of :program:`memcached` servers.
It will either do this immediately or expire the content based on the
expiration time passed to the method (a value of zero causes an immediate
flush). The operation is not atomic to multiple servers, just atomic to a
single server. That is, it will flush the servers in the order that they were
added.

------
RETURN
------

A value of type :c:type:`memcached_return_t` is returned
On success that value will be :c:type:`MEMCACHED_SUCCESS`.
Use :c:type:`memcached_strerror` to translate this value to a printable string.

----
HOME
----

To find out more information please check:
`http://libmemcached.org/ <http://libmemcached.org/>`_

------
AUTHOR
------

Brian Aker, <brian@tangent.org>

--------
SEE ALSO
--------

:manpage:`memcached(1)` :manpage:`libmemcached(3)` :manpage:`memcached_strerror(3)`


text:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.jbpm</groupId>
    <artifactId>jbpm-container-integration-deps</artifactId>
    <version>7.2.0-SNAPSHOT</version>
  </parent>

  <artifactId>idep-jbpm-persistence</artifactId>

  <name>jBPM :: Container Test IDEPS jBPM Persistence</name>

  <dependencies>
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-persistence-jpa</artifactId>
    </dependency>
    <dependency>
      <groupId>org.jbpm</groupId>
      <artifactId>jbpm-persistence-jpa</artifactId>
    </dependency>
    <dependency>
      <groupId>org.jbpm</groupId>
      <artifactId>jbpm-human-task-jpa</artifactId>
    </dependency>
  </dependencies>

</project>


text:
<ion-header>
  <ion-navbar>
    <button ion-button menuToggle>
      <ion-icon name="menu"></ion-icon>
    </button>
    <ion-title>Zymometer {{appVersion}}</ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <ion-grid>
    <ion-row>
      <ion-col col-12>
        <ion-list no-lines>
          <ion-item>
            <ion-input name="brewName" placeholder="New Brew Name" type="text" [(ngModel)]="newBrew"></ion-input>
            <button large outline icon-left item-right ion-button (click)="addBrew()" [disabled]="!newBrew">
                <ion-icon name="add-circle"></ion-icon>
                Add
            </button>
          </ion-item>
        </ion-list>
      </ion-col>
      <ion-col col-12>
        <ion-card>
          <ion-card-header>
            Your Brews
          </ion-card-header>

          <ion-card-content>
            <ion-list>
              <button ion-item detail-push *ngFor="let brew of brews" (click)="viewBrew(brew)">
              <ion-icon name="beer" item-left></ion-icon>
              {{brew.name}} ({{brew.events.length}} Events) {{brew.isFinished ? '[Finished]' : ''}}
            </button>
            </ion-list>
          </ion-card-content>
        </ion-card>
      </ion-col>
    </ion-row>
  </ion-grid>
</ion-content>


text:
wordpress_id: 522
title: "POTD: Hanging Right"
wordpress_url: http://spaetzel.com/PermaLink,guid,408.aspx
layout: post
---

        No the lamp isn't bent. Though it is shaped oldly. I took this photo realizing that
        I had a cool subject just waiting there (been in need of a bulb for a long time, dang
        oddball bulbs)

        Kind of neat. Too much work today to go out and do a proper shoot.


text:
function route(handle, pathname, res) {
    console.log("Ruteando " + pathname);
    if (typeof handle[pathname] === 'function') {
        handle[pathname](res, pathname);
    } else {
        console.log("No se encontro manipulador para " + pathname);
        res.writeHead(404, {"Content-Type": "text/html"});
        res.write("Holy 404 Error, Batman!");
        res.end();
    }
}
exports.route = route;


text:
<?php

namespace Cartalyst\Sentinel\tests;

use Cartalyst\Sentinel\Cookies\IlluminateCookie;
use Mockery as m;
use PHPUnit_Framework_TestCase;

class IlluminateCookieTest extends PHPUnit_Framework_TestCase
{
    /**
     * Close mockery.
     *
     * @return void
     */
    public function tearDown()
    {
        m::close();
    }

    public function testPut()
    {
        $cookie = new IlluminateCookie($request = m::mock('Illuminate\Http\Request'), $jar = m::mock('Illuminate\Cookie\CookieJar'), 'foo');
        $jar->shouldReceive('forever')->with('foo', 'bar')->once()->andReturn('cookie');
        $jar->shouldReceive('queue')->with('cookie')->once();
        $cookie->put('bar');
    }

    public function testGetWithQueuedCookie()
    {
        $cookie = new IlluminateCookie($request = m::mock('Illuminate\Http\Request'), $jar = m::mock('Illuminate\Cookie\CookieJar'), 'foo');
        $jar->shouldReceive('getQueuedCookies')->once()->andReturn(['foo' => 'bar']);
        $this->assertEquals('bar', $cookie->get());
    }

    public function testGetWithPreviousCookies()
    {
        $cookie = new IlluminateCookie($request = m::mock('Illuminate\Http\Request'), $jar = m::mock('Illuminate\Cookie\CookieJar'), 'foo');
        $jar->shouldReceive('getQueuedCookies')->once()->andReturn([]);
        $request->shouldReceive('cookie')->with('foo')->once()->andReturn('bar');
        $this->assertEquals('bar', $cookie->get());
    }

    public function testForget()
    {
        $cookie = new IlluminateCookie($request = m::mock('Illuminate\Http\Request'), $jar = m::mock('Illuminate\Cookie\CookieJar'), 'foo');
        $jar->shouldReceive('forget')->with('foo')->once()->andReturn('cookie');
        $jar->shouldReceive('queue')->with('cookie')->once();
        $cookie->forget();
    }
}


text:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Major Version</key><integer>1</integer>
	<key>Minor Version</key><integer>1</integer>
	<key>Date</key><date>2014-06-07T10:09:26Z</date>
	<key>Application Version</key><string>11.2.2</string>
	<key>Features</key><integer>5</integer>
	<key>Show Content Ratings</key><true/>
	<key>Music Folder</key><string>file://localhost/C:/Users/Jhoan/Music/iTunes/iTunes%20Music/</string>
	<key>Library Persistent ID</key><string>91C13E0C75650CBC</string>
	<key>Tracks</key>
	<dict>

		<key>1140</key>
		<dict>
			<key>Track ID</key><integer>1140</integer>
			<key>Name</key><string>True</string>
			<key>Artist</key><string>Akira Yamaoka</string>
			<key>Album Artist</key><string>AKIRA YAMAOKA</string>
			<key>Composer</key><string>Akira Yamaoka</string>
			<key>Album</key><string>Silent Hill 2 OST</string>
			<key>Genre</key><string>Soundtracks</string>
			<key>Kind</key><string>Archivo de audio MPEG</string>
			<key>Size</key><integer>2999644</integer>
			<key>Total Time</key><integer>186906</integer>
			<key>Disc Number</key><integer>1</integer>
			<key>Disc Count</key><integer>1</integer>
			<key>Track Number</key><integer>24</integer>
			<key>Date Modified</key><date>2011-12-26T05:48:07Z</date>
			<key>Date Added</key><date>2014-01-25T06:46:02Z</date>
			<key>Bit Rate</key><integer>128</integer>
			<key>Sample Rate</key><integer>44100</integer>
			<key>Comments</key><string> 000006E3 00000944 00001210 00001966 00013897 00011187 00007160 00007EA1 0000EA77 00011187</string>
			<key>Play Count</key><integer>75</integer>
			<key>Play Date</key><integer>3466467508</integer>
			<key>Play Date UTC</key><date>2013-11-05T08:38:28Z</date>
			<key>Skip Count</key><integer>10</integer>
			<key>Skip Date</key><date>2013-07-06T04:35:11Z</date>
			<key>Rating</key><integer>80</integer>
			<key>Album Rating</key><integer>60</integer>
			<key>Album Rating Computed</key><true/>
			<key>Artwork Count</key><integer>2</integer>
			<key>Persistent ID</key><string>3B8772E172835671</string>
			<key>Track Type</key><string>File</string>
			<key>Location</key><string>file://localhost/F:/Music/Akira%20Yamaoka/Silent%20Hill%202%20OST/24%20True.mp3</string>
			<key>File Folder Count</key><integer>-1</integer>
			<key>Library Folder Count</key><integer>-1</integer>
		</dict>

		<key>2904</key>
		<dict>
			<key>Track ID</key><integer>2904</integer>
			<key>Name</key><string>Raging Zef Boner</string>
			<key>Artist</key><string>Die Antwoord</string>
			<key>Album Artist</key><string>Die Antwoord</string>
			<key>Album</key><string>Donker Mag</string>
			<key>Genre</key><string>Electronic</string>
			<key>Kind</key><string>Archivo de audio MPEG</string>
			<key>Size</key><integer>8096916</integer>
			<key>Total Time</key><integer>199706</integer>
			<key>Track Number</key><integer>5</integer>
			<key>Year</key><integer>2014</integer>
			<key>Date Modified</key><date>2014-06-04T08:29:03Z</date>
			<key>Date Added</key><date>2014-06-05T00:28:45Z</date>
			<key>Bit Rate</key><integer>320</integer>
			<key>Sample Rate</key><integer>44100</integer>
			<key>Play Count</key><integer>2</integer>
			<key>Play Date</key><integer>3484972217</integer>
			<key>Play Date UTC</key><date>2014-06-07T12:50:17Z</date>
			<key>Rating</key><integer>100</integer>
			<key>Album Rating</key><integer>100</integer>
			<key>Album Rating Computed</key><true/>
			<key>Artwork Count</key><integer>1</integer>
			<key>Persistent ID</key><string>F533BEE189778D10</string>
			<key>Track Type</key><string>File</string>
			<key>Location</key><string>file://localhost/F:/Software/Die%20Antwoord%20-%20Donker%20Mag%202014%20320kbps%20CBR%20MP3%20%5BVX%5D/05%20-%20Die%20Antwoord%20-%20Raging%20Zef%20Boner.mp3</string>
			<key>File Folder Count</key><integer>-1</integer>
			<key>Library Folder Count</key><integer>-1</integer>
		</dict>
	</dict>

</dict>
</plist>


text:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Country> europe = new ArrayList<Country>();
        europe.add(new Country(81903000,357121.41,"Germany"));
        europe.add(new Country(64667000,668763, "France"));
        europe.add(new Country( 4985900,385199, "Norway"));
        europe.add(new Country( 9514406,450295, "Sweden"));
        europe.add(new Country(47212990,504645, "Spain"));
        europe.add(new Country( 8014000, 41285, "Switzerland"));
        europe.add(new Country(   36371,     2.02, "Monaco"));
        System.out.println(europe);
        Collections.sort(europe);
        System.out.println(europe);
        Collections.sort(europe, new PopulationDensityComperator());
        System.out.println(europe);
    }
}