text:
var libpath = "/Users/troy/event_calendar/lib";
var buildpath = "/Users/troy/event_calendar/build";
var fs = require("fs");
var util = require("util");
var _ = require("underscore");
var ICAL = require("ical.js");
var moment = require("moment-timezone");
var assert = require("chai").assert;
var nock = require("nock");
var sinon = require("sinon");
var db = require(libpath + "/node/db");
var ec = require(libpath + "/node/event_calendar");
var testResultsDir = "/Users/troy/calendar_events/lib/browser";

/**
 * Disable actual http requests...requests that
 * are not intercepted will throw an error
 */
nock.disableNetConnect();

/**
 * Convert a jcal event or array of events to a representation
 * suitable for full calendar
 */
function jCalToFullCalendar(jcal, isMultiEvent) {
  jcal = JSON.parse(JSON.stringify(jcal));
  function convertEvt(evt) {
    evt = evt instanceof ICAL.Component ? evt : new ICAL.Component(evt);
    return {
      id : evt.getFirstPropertyValue("uid"),
      title : evt.getFirstPropertyValue("summary"),
      allDay : false,
      start : evt.getFirstPropertyValue("dtstart").toString(),
      end :  evt.getFirstPropertyValue("dtend").toString()
    };
  }
  return isMultiEvent ? jcal.map(function(j){ evts.push(convertEvt(j)); }) :
                        [convertEvt(jcal)];
}

/**
 * Write json to a file
 */
function writeToFile(json, callback) {
  var outputFilename = testResultsDir + "/test_results.json";
  fs.writeFile(outputFilename, JSON.stringify(json, null, 2), function(err) {
    if(err) { console.log(err); }
    callback();
  });
}

var nonRepeatingEvtDoc = {
  "_id" : "5899182e1e1157919349134db9005873",
  "_rev" : "1-2bc7c31235b0091946e066b217147aff",
  "vevents" : [
    [ "vevent",
      [
        ["uid", {}, "text", "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com"],
        ["sequence", {}, "integer", 0],
        ["created", {}, "date-time", "2014-11-09T06:00:00Z"],
        ["last-modified", {}, "date-time", "2014-11-09T17:00:00Z"],
        ["dtstamp", {}, "date-time", "2014-11-09T17:00:00Z"],
        ["dtstart",
          {"tzid" : "America/Los_Angeles"},
          "date-time",
          "2014-11-09T09:00:00"
        ],
        ["dtend",
          {"tzid" : "America/Los_Angeles"},
          "date-time",
          "2014-11-09T10:00:00"
        ],
        ["summary", {}, "text", "Main event summary"],
        ["description", {}, "text", "description"]
      ],
      []
    ]
  ]
};

var repeatingEvtDoc = {
  "_id" : "5899182e1e1157919349134db9005873",
  "_rev" : "1-2bc7c31235b0091946e066b217147aff",
  "vevents" : [
    [ "vevent",
      [
        ["uid", {}, "text", "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com"],
        ["sequence", {}, "integer", 0],
        ["created", {}, "date-time", "2014-11-09T06:00:00Z"],
        ["last-modified", {}, "date-time", "2014-11-09T17:00:00Z"],
        ["dtstamp", {}, "date-time", "2014-11-09T17:00:00Z"],
        ["dtstart",
          {"tzid" : "America/Los_Angeles"},
          "date-time",
          "2014-11-09T09:00:00"
        ],
        ["dtend",
          {"tzid" : "America/Los_Angeles"},
          "date-time",
          "2014-11-09T10:00:00"
        ],
        ["summary", {}, "text", "Main event summary"],
        ["description", {}, "text", "description"],
        ["rrule",
          {},
          "recur",
          {"freq": "DAILY", "count" : 5}
        ]
      ],
      []
    ]
  ]
};

var repeatingEvtWithExceptionDoc = {
  "_id" : "5899182e1e1157919349134db9005873",
  "_rev" : "1-2bc7c31235b0091946e066b217147aff",
  "vevents" : [
    [ "vevent",
      [
        ["uid", {}, "text", "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com"],
        ["sequence", {}, "integer", 0],
        ["created", {}, "date-time", "2014-11-09T06:00:00Z"],
        ["last-modified", {}, "date-time", "2014-11-09T17:00:00Z"],
        ["dtstamp", {}, "date-time", "2014-11-09T17:00:00Z"],
        ["dtstart",
          {"tzid" : "America/Los_Angeles"},
          "date-time",
          "2014-11-09T09:00:00"
        ],
        ["dtend",
          {"tzid" : "America/Los_Angeles"},
          "date-time",
          "2014-11-09T10:00:00"
        ],
        ["summary", {}, "text", "Main event summary"],
        ["description", {}, "text", "description"],
        ["rrule",
          {},
          "recur",
          {"freq": "DAILY", "count" : 5}
        ]
      ],
      []
    ],
    [ "vevent",
      [
        ["uid", {}, "text", "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com"],
        ["sequence", {}, "integer", 0],
        ["created", {}, "date-time", "2014-11-10T06:00:00Z"],
        ["last-modified", {}, "date-time", "2014-11-10T17:00:00Z"],
        ["dtstamp", {}, "date-time", "2014-11-10T17:00:00Z"],
        ["recurrence-id",
          {"tzid" : "America/Los_Angeles"},
          "date-time",
          "2014-11-10T09:00:00"
        ],
        ["dtstart",
          {"tzid" : "America/Los_Angeles"},
          "date-time",
          "2014-11-10T11:00:00"
        ],
        ["dtend",
          {"tzid" : "America/Los_Angeles"},
          "date-time",
          "2014-11-10T12:00:00"
        ],
        ["summary", {}, "text", "Exception event summary"],
        ["description", {}, "text", "description"]
      ],
      []
    ]
  ]
};

/**
 * Private helper functions
 */
describe("private helper functions:", function() {

  describe("isOccurrenceDate", function(){
    it("Should return a boolean to indicate if date is an occurrence date", function(){
      var opts = {
        dtstart: "2014-12-01T09:00:00",
        dtend: "2014-12-01T10:00:00",
        tzid: "America/Los_Angeles",
        summary: "My summary",
        freq: "DAILY",
        count: 5
      };
      var evt = ec.newEvent(opts);
      assert(ec.isOccurrenceDate(evt, "2014-12-01T09:00:00"));
      assert(!ec.isOccurrenceDate(evt, "2014-12-01T09:01:00"));
      console.log(evt);
    });

  });

  describe("newExceptionEvent", function(){
    it("Should return a boolean to indicate if date is an occurrence date", function(){
      var opts = {
        dtstart: "2014-12-01T09:00:00",
        dtend: "2014-12-01T10:00:00",
        tzid: "America/Los_Angeles",
        summary: "My summary",
        freq: "DAILY",
        count: 5
      };
      var evt = ec.newEvent(opts);

      // updated dtstart and summary
      var exceptionSettings = {
        dtstart : "2014-12-03T11:00:00",
        dtend : "2014-12-03T12:00:00",
        uid : new ICAL.Component(evt).getFirstPropertyValue("uid"),
        summary: "Exception summary"
      };
      var exceptionEvent = ec.newExceptionEvent(exceptionSettings, evt);
      assert(new ICAL.Component(exceptionEvent).getFirstPropertyValue("dtstart").toString() === exceptionSettings.dtstart, "dtstart not set correctly");
    });
  });

  describe("updateExceptionEvent", function(){
    it("Should update non-repeating properties", function(){
      var exceptionEvent = [ "vevent",
        [
          ["uid", {}, "text", "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com"],
          ["sequence", {}, "integer", 1],
          ["created", {}, "date-time", "2014-11-01T06:00:00Z"],
          ["last-modified", {}, "date-time", "2014-11-01T17:00:00Z"],
          ["dtstamp", {}, "date-time", "2014-11-01T17:00:00Z"],
          ["recurrence-id",
            {"tzid" : "America/Los_Angeles"},
            "date-time",
            "2014-11-02T09:00:00"
          ],
          ["dtstart",
            {"tzid" : "America/Los_Angeles"},
            "date-time",
            "2014-11-02T11:00:00"
          ],
          ["dtend",
            {"tzid" : "America/Los_Angeles"},
            "date-time",
            "2014-11-02T12:00:00"
          ],
          ["summary", {}, "text", "Exception event"],
          ["description", {}, "text", "description"]
        ],
        []
      ];
      var updates = {
        tzid : "America/Los_Angeles",
        dtstart : "2014-11-02T12:00:00", // 1-hr change
        dtend : "2014-11-02T13:00:00",
        summary: "New summary",
        description: "New description"
      };
      var updatedEvent = ec.updateExceptionEvent(updates, exceptionEvent);
      assert(updatedEvent.getFirstPropertyValue("dtstart").toString() === updates.dtstart, "dtstart not updated properly");
      assert(updatedEvent.getFirstPropertyValue("summary") === updates.summary, "summary not updated properly");
      assert(updatedEvent.getFirstPropertyValue("description") === updates.description, "description not updated properly");
    });
  });

  describe("updateMainEvent", function(){
    it("Should ignore repeat properties when freq not in change set", function(){
      var doc = JSON.parse(JSON.stringify(nonRepeatingEvtDoc));
      var updates = {
        dtstart: "2014-11-09T09:00:00",
        dtend: "2014-11-09T10:00:00",
        tzid: "America/Los_Angeles",
        count: "6"
      };
      var evt = ec.updateMainEvent(updates, doc.vevents[0]);
      evt = new ICAL.Component(evt);
      assert(evt.getFirstPropertyValue("rrule") === null, "count not removed when freq not set");
    });
  });

  describe("updateMainEvent", function(){
    it("Should update repeat settings", function(){
      var doc = JSON.parse(JSON.stringify(repeatingEvtDoc));
      var updates = {
        dtstart: "2014-11-09T09:00:00",
        dtend: "2014-11-09T10:00:00",
        tzid: "America/Los_Angeles",
        freq: "MONTHLY",
        count: 10
      };
      var evt = ec.updateMainEvent(updates, doc.vevents[0]);
      evt = new ICAL.Component(evt);
      //console.log(util.inspect(evt.toJSON(), {depth: 5, colors: true}));
      assert(evt.getFirstPropertyValue("dtstart").toString() === updates.dtstart, "dtstart not updated properly");
      assert(evt.getFirstPropertyValue("rrule").freq === updates.freq, "freq not updated propertly");
      assert(evt.getFirstPropertyValue("rrule").interval === 1, "interval !== 1");
    });
  });

});

/**
 * Update Properties
 */
describe("Update property ->", function() {
  var sandbox, doc;
  before(function(){
    sandbox = sinon.sandbox.create();
    sandbox.stub(db, "getEvent", function(uid, callback) {
      callback(null, doc.vevents);
    });
    sandbox.stub(db, "updateEvent", function(evt, callback) {
      doc.vevents = evt;
      callback(null, evt);
    });
    sandbox.stub(db, "deleteEvent", function(evt, callback) {
      callback(null, doc.vevents);
    });
  });
  after(function(){
    sandbox.restore();
  });

  // dtstart
  it("Should update dtstart", function(){
      doc = JSON.parse(JSON.stringify(nonRepeatingEvtDoc));
      var changes = {
        uid : new ICAL.Component(doc.vevents[0]).getFirstPropertyValue("uid"),
        dtstart: "2014-12-26T05:27:45",
        dtend: "2014-12-26T06:27:45"
      };
      ec.updateEvent(changes, function(err, updatedEvt) {
        assert(err === null, "err is not null");
        updatedEvt = new ICAL.Component(updatedEvt[0]);
        var chk = updatedEvt.getFirstProperty("dtstart").getFirstValue("dtstart").toString();
        assert(chk == changes.dtstart);
        done();
      });
    });

  // freq
  it("Should update freq", function(){
    doc = JSON.parse(JSON.stringify(repeatingEvtDoc));
    var changes = {
      uid: new ICAL.Component(doc.vevents[0]).getFirstPropertyValue("uid"),
      freq: "MONTHLY"
    };
    ec.updateEvent(changes, function(err, updatedEvt){
      assert.isNull(err);
      updatedEvt = new ICAL.Component(updatedEvt[0]);
      var chk = updatedEvt.getFirstProperty("rrule").getFirstValue().freq;
      assert(chk == changes.freq, chk + " !== " + changes.freq);
      done();
    });
  });

  // interval
  it("Should update interval", function(){
    doc = JSON.parse(JSON.stringify(repeatingEvtDoc));
    var changes = {
      uid: new ICAL.Component(doc.vevents[0]).getFirstPropertyValue("uid"),
      freq: "DAILY", // no change here just want the new repeat settings to be valid
      interval: 2
    };
    ec.updateEvent(changes, function(err, updatedEvt){
      assert.isNull(err);
      updatedEvt = new ICAL.Component(updatedEvt[0]);
      var chk = updatedEvt.getFirstProperty("rrule").getFirstValue().interval;
      assert(chk == changes.interval, chk + " !== " + changes.interval);
      done();
    });
  });

  it("Should update byday", function(){
    doc = JSON.parse(JSON.stringify(repeatingEvtDoc));
    var changes = {
      uid: new ICAL.Component(doc.vevents[0]).getFirstPropertyValue("uid"),
      freq: "DAILY",
      byday: ["mo", "2tu"],
    };
    ec.updateEvent(changes, function(err, updatedEvt) {
      assert.isNull(err, "update err is not null");
      updatedEvt = new ICAL.Component(updatedEvt[0]);
      var chk = updatedEvt.getFirstProperty("rrule").getFirstValue().getComponent("byday");
      assert(_.isEqual(chk.sort(), changes.byday.sort()), chk + " !== " + changes.byday);
      done();
    });
  });

  // bymonth
  it("Should update bymonth", function(){
    doc = JSON.parse(JSON.stringify(repeatingEvtDoc));
    var changes = {
      uid: new ICAL.Component(doc.vevents[0]).getFirstPropertyValue("uid"),
      freq: "DAILY",
      bymonth: [2, 8]
    };
    ec.updateEvent(changes, function(err, updatedEvt) {
      assert.isNull(err, "update err is not null");
      updatedEvt = new ICAL.Component(updatedEvt[0]);
      var chk = updatedEvt.getFirstProperty("rrule").getFirstValue().getComponent("bymonth");
      assert(_.isEqual(chk.sort(), changes.bymonth.sort()), chk + " !== " + changes.bymonth);
      done();
    });
  });

  // bymonthday
  it("Should update bymonthday", function(){
    doc = JSON.parse(JSON.stringify(repeatingEvtDoc));
    var changes = {
      uid: new ICAL.Component(doc.vevents[0]).getFirstPropertyValue("uid"),
      freq: "DAILY",
      bymonthday: [1, 15],
    };
    ec.updateEvent(changes, function(err, updatedEvt){
      assert.isNull(err, "update err is not null");
      updatedEvt = new ICAL.Component(updatedEvt[0]);
      var chk = updatedEvt.getFirstProperty("rrule").getFirstValue().getComponent("bymonthday");
      assert(_.isEqual(chk.sort(), changes.bymonthday.sort()), chk + " !== " + changes.bymonthday);
      done();
    });
  });

  // bysetpos
  it("Should update bysetpos", function(){
    doc = JSON.parse(JSON.stringify(repeatingEvtDoc));
    var changes = {
      uid: new ICAL.Component(doc.vevents[0]).getFirstPropertyValue("uid"),
      freq: "DAILY",
      bysetpos: [1, 2],
    };
    ec.updateEvent(changes, function(err, updatedEvt) {
      assert.isNull(err, "update err is not null");
      updatedEvt = new ICAL.Component(updatedEvt[0]);
      var chk = updatedEvt.getFirstProperty("rrule").getFirstValue().getComponent("bysetpos");
      assert(_.isEqual(chk.sort(), changes.bysetpos.sort()), chk + " !== " + changes.bysetpos);
      done();
    });
  });

  it("Should update count", function(){
    doc = JSON.parse(JSON.stringify(repeatingEvtDoc));
    var changes = {
      uid: new ICAL.Component(doc.vevents[0]).getFirstPropertyValue("uid"),
      freq: "DAILY",
      count: 5
    };
    ec.updateEvent(changes, function(err, updatedEvt){
      assert.isNull(err, "update err is not null");
      updatedEvt = new ICAL.Component(updatedEvt[0]);
      var chk = updatedEvt.getFirstProperty("rrule").getFirstValue().count;
      assert(_.isEqual(chk, changes.count), chk + " !== " + changes.count);
      done();
    });
  });

  // until
  it("Should update until", function(){
    doc = JSON.parse(JSON.stringify(repeatingEvtDoc));
    var changes = {
      uid: new ICAL.Component(doc.vevents[0]).getFirstPropertyValue("uid"),
      freq: "DAILY",
      until: "2016-01-01T09:00:00"
    };
    ec.updateEvent(changes, function(err, updatedEvt){
      assert.isNull(err, "update err is not null");
      updatedEvt = new ICAL.Component(updatedEvt[0]);
      var chk = updatedEvt.getFirstProperty("rrule").getFirstValue().until.toString();
      assert(chk === changes.until, chk + " !== " + changes.until);
      done();
    });
  });

  // Update multiple
  it("Should update multiple properties", function(){
    doc = JSON.parse(JSON.stringify(repeatingEvtDoc));
    var changes = {
      uid: new ICAL.Component(doc.vevents[0]).getFirstPropertyValue("uid"),
      dtstart : "2014-12-01T08:30:00",
      dtend : "2014-12-01T09:30:00",
      freq: "DAILY",
      interval: 3,
      byday: ["2tu", "3fr"],
      bymonth: [3,9],
      bysetpos: [3],
      until: "2016-09-01T09:00:00"
    };
    ec.updateEvent(changes, function(err, updatedEvt){
      assert.isNull(err, "update err not null");
      console.log("updatedEvt: ", util.inspect(updatedEvt, {depth: null, colors: true}));
      updatedEvt = new ICAL.Component(updatedEvt[0]);
      // dtstart
      var chk = updatedEvt.getFirstProperty("dtstart").getFirstValue("dtstart").toString();
      assert(chk == changes.dtstart, chk + " !== " + changes.dtstart);
      // freq
      chk = updatedEvt.getFirstProperty("rrule").getFirstValue().freq;
      assert(_.isEqual(chk, changes.freq), chk + " !== " + changes.freq);
      // interval
      chk = updatedEvt.getFirstProperty("rrule").getFirstValue().interval;
      assert(_.isEqual(chk, changes.interval), chk + " !== " + changes.interval);
      // byday
      chk = updatedEvt.getFirstProperty("rrule").getFirstValue().getComponent("byday");
      assert(_.isEqual(chk.sort(), changes.byday.sort()), chk + " !== " + changes.byday);
      // bymonth
      chk = updatedEvt.getFirstProperty("rrule").getFirstValue().getComponent("bymonth");
      assert(_.isEqual(chk.sort(), changes.bymonth.sort()), chk + " !== " + changes.bymonth);
      // bysetpos
      chk = updatedEvt.getFirstProperty("rrule").getFirstValue().getComponent("bysetpos");
      assert(_.isEqual(chk.sort(), changes.bysetpos.sort()), chk + " !== " + changes.bysetpos);
      // until
      chk = updatedEvt.getFirstProperty("rrule").getFirstValue().until.toString();
      assert(_.isEqual(chk, changes.until), chk + " !== " + changes.until);
      done();
    });

  });

});

/**
 * Update Event
 */
describe("Update An Event", function() {
  var sandbox, doc;
  before(function(){
    sandbox = sinon.sandbox.create();
    sandbox.stub(db, "getEvent", function(uid, callback) {
      callback(null, doc.vevents);
    });
    sandbox.stub(db, "createEvent", function(evt, callback) {
      callback(null, evt);
    });
    sandbox.stub(db, "updateEvent", function(evt, callback) {
      doc.vevents = evt;
      callback(null, evt);
    });
    sandbox.stub(db, "deleteEvent", function(evt, callback) {
      callback(null, doc.vevents);
    });
  });
  after(function(){
    sandbox.restore();
  });

  it("Should create a new exception when updating a non-repeating property of the first occurrence applied to instance only.", function(done) {
    doc = JSON.parse(JSON.stringify(repeatingEvtDoc));
    var opts = {
      uid : "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com",
      summary: "Updated summary",
      updateType: "instanceOnly"
    };
    ec.updateEvent(opts, function(err, evt) {
      // console.log(util.inspect(arguments, {depth: 5, colors: true}));
      assert(err === null, "err is not null");
      assert(new ICAL.Component(evt).getFirstPropertyValue("summary") !== opts.summary, "original summary modified when it should not have been");
      assert(evt.length > 1, "evt.length not > 1" + evt.length);
      assert(new ICAL.Component(evt[1]).getFirstPropertyValue("summary")=== opts.summary, "summary not updated properly");
      done();
    });
  });

  it("Should update a non-repeating property of a pre-existing exception event:", function(done) {
    doc = JSON.parse(JSON.stringify(repeatingEvtWithExceptionDoc));
    var opts = {
      uid : "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com",
      recurrenceId : "2014-11-10T09:00:00",
      dtstart: "2014-11-10T12:30:00", // move exception evt 1.5 hrs ahead
      dtend: "2014-11-10T13:30:00",
      summary: "Updated exception event summary", // Update summary
      updateType: "instanceOnly"
    };
    ec.updateEvent(opts, function(err, evt) {
      //console.log(util.inspect(arguments, {depth: 5, colors: true}));
      assert(err === null, "err is not null");
      var e = new ICAL.Component(evt[1]);
      assert(e.getFirstPropertyValue("recurrence-id") == opts.recurrenceId, "recurrence-id not equal to opts.recurrenceId");
      assert(e.getFirstPropertyValue("dtstart").toString() === opts.dtstart, "dtstart not updated properly");
      assert(e.getFirstPropertyValue("summary")=== opts.summary, "summary not updated properly");
      done();
    });
  });

  it("Should create a new exception event, ignoring repeat settings, when updating first occurrence and applying to instance only.", function(done) {
    doc = JSON.parse(JSON.stringify(repeatingEvtDoc));
    var opts = {
      uid : "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com",
      recurrenceId : "2014-11-09T09:00:00",
      freq: "MONTHLY", // Updated freq
      summary: "Updated summary", // Updated summary
      updateType: "instanceOnly"
    };
    ec.updateEvent(opts, function(err, evt) {
      //console.log(util.inspect(arguments, {depth: 5, colors: true}));
      assert(err === null, "err is not null");
      var mainEvt = new ICAL.Component(evt[0]), exEvt = new ICAL.Component(evt[1]);
      assert(mainEvt.getFirstPropertyValue("summary") !== opts.summary, "main event summary updated when it should not have been");
      assert(doc.vevents.length === 2, "doc.vevents.length !== 2");
      assert(exEvt.getFirstPropertyValue("summary") === opts.summary, "summary not updated properly");
      assert(mainEvt.getFirstPropertyValue("rrule").freq === "DAILY", "freq !== DAILY");
      done();
    });
  });

  it("Should update a non-repeat property of 1st occurrence when applying to this and future:", function(done) {
    doc = JSON.parse(JSON.stringify(repeatingEvtDoc));
    var opts = {
      uid : "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com",
      recurrenceId : "2014-11-09T09:00:00",
      summary : "Updated summary", // updated summary
      updateType: "thisAndFuture"
    };
    ec.updateEvent(opts, function(err, evtJSON) {
      //console.log(util.inspect(doc, {colors: true, depth: 5}));
      assert(err === null, "err is not null");
      var mainEvt = new ICAL.Component(doc.vevents[0]);
      assert(mainEvt.getFirstPropertyValue("summary") === opts.summary, "main event summary not updated properly");
      assert(doc.vevents.length === 1, "doc.vevents.length !== 1");
      done();
    });
  });

  it("Should update a repeat property of the 1st occurrence when applying to this and future:", function(done) {
    doc = JSON.parse(JSON.stringify(repeatingEvtDoc));
    var opts = {
      uid : "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com",
      recurrenceId : "2014-11-09T09:00:00",
      freq: "MONTHLY", // Change freq
      updateType: "thisAndFuture"
    };
    ec.updateEvent(opts, function(err, evtJSON) {
      //console.log(util.inspect(evtJSON, {colors: true, depth: 5}));
      assert(err === null, "err is not null");
      var mainEvt = new ICAL.Component(doc.vevents[0]);
      assert(mainEvt.getFirstPropertyValue("rrule").freq === opts.freq, "main event freq not updated properly");
      assert(doc.vevents.length === 1, "doc.vevents.length !== 1");
      done();
    });
  });

  it("Should remove exception when first occurrence hours are updated to match a pre-existing exception event when applied to this and future:", function(done) {
    doc = JSON.parse(JSON.stringify(repeatingEvtWithExceptionDoc));
    var opts = {
      uid : "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com",
      recurrenceId : "2014-11-09T09:00:00",
      dtstart: "2014-11-09T11:00:00", // adjust start time to match exception event
      dtend: "2014-11-09T12:00:00", // keep dtend an hour after dtstart
      freq: "DAILY", // freq stays the same
      count : 5, // freq stays the same
      updateType: "thisAndFuture"
    };
    ec.updateEvent(opts, function(err, evtJSON) {
      //console.log(util.inspect(doc, {colors: true, depth: 5}));
      assert(err === null, "err is not null");
      var mainEvt = new ICAL.Component(doc.vevents[0]);
      assert(mainEvt.getFirstPropertyValue("dtstart").toString() === opts.dtstart, "dtstart not updated properly");
      assert(doc.vevents.length === 1, "doc.vevents.length is not 1"); // exception should be removed because it matches main event after update
      done();
    });
  });

  it("Should keep a pre-existing exception event when the first occurrence hours are updated so they do not match the exception and updates are applied to this and future.", function(done) {
    doc = JSON.parse(JSON.stringify(repeatingEvtWithExceptionDoc));
    var opts = {
      uid : "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com",
      recurrenceId : "2014-11-09T09:00:00",
      dtstart: "2014-11-09T16:00:00", // change hours so they don"t match exception
      dtend: "2014-11-09T17:00:00",
      freq: "DAILY",
      count : 5,
      updateType: "thisAndFuture"
    };
    ec.updateEvent(opts, function(err, evtJSON) {
      //console.log(util.inspect(doc, {colors: true, depth: 5}));
      assert(err === null, "err is not null");
      var mainEvt = new ICAL.Component(doc.vevents[0]);
      assert(mainEvt.getFirstPropertyValue("dtstart").toString() === opts.dtstart, "dtstart not updated properly");
      assert(doc.vevents.length === 1, "doc.vevents.length !== 1");
      done();
    });
  });

  it("Should update non-repeating property of main event and all exception events when updating the first occurrence and applying to this and future:", function(done) {
    doc = {
      "_id" : "5899182e1e1157919349134db9005873",
      "_rev" : "1-2bc7c31235b0091946e066b217147aff",
      "vevents" : [
        [ "vevent",
          [
            ["uid", {}, "text", "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com"],
            ["sequence", {}, "integer", 0],
            ["created", {}, "date-time", "2014-11-01T06:00:00Z"],
            ["last-modified", {}, "date-time", "2014-11-01T17:00:00Z"],
            ["dtstamp", {}, "date-time", "2014-11-01T17:00:00Z"],
            ["dtstart",
              {"tzid" : "America/Los_Angeles"},
              "date-time",
              "2014-11-01T09:00:00"
            ],
            ["dtend",
              {"tzid" : "America/Los_Angeles"},
              "date-time",
              "2014-11-01T10:00:00"
            ],
            ["rrule",
              {},
              "recur",
              {"freq": "DAILY", "count" : 5}
            ],
            ["summary", {}, "text", "Main event summary"],
            ["description", {}, "text", "description"]
          ],
          []
        ],
        [ "vevent",
          [
            ["uid", {}, "text", "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com"],
            ["sequence", {}, "integer", 1],
            ["created", {}, "date-time", "2014-11-01T06:00:00Z"],
            ["last-modified", {}, "date-time", "2014-11-01T17:00:00Z"],
            ["dtstamp", {}, "date-time", "2014-11-01T17:00:00Z"],
            ["recurrence-id",
              {"tzid" : "America/Los_Angeles"},
              "date-time",
              "2014-11-01T09:00:00"
            ],
            ["dtstart",
              {"tzid" : "America/Los_Angeles"},
              "date-time",
              "2014-11-01T12:30:00" // different so exception event is kept on update
            ],
            ["dtend",
              {"tzid" : "America/Los_Angeles"},
              "date-time",
              "2014-11-01T13:30:00"
            ],
            ["summary", {}, "text", "First occurrence exception event summary"],
            ["description", {}, "text", "First occurrence exception description"]
          ],
          []
        ],
        [ "vevent",
          [
            ["uid", {}, "text", "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com"],
            ["sequence", {}, "integer", 1],
            ["last-modified", {}, "date-time", "2014-11-02T17:00:00Z"],
            ["dtstamp", {}, "date-time", "2014-11-02T17:00:00Z"],
            ["recurrence-id",
              {"tzid" : "America/Los_Angeles"},
              "date-time",
              "2014-11-02T09:00:00"
            ],
            ["dtstart",
              {"tzid" : "America/Los_Angeles"},
              "date-time",
              "2014-11-02T11:00:00" // different so exception event is kept on update
            ],
            ["dtend",
              {"tzid" : "America/Los_Angeles"},
              "date-time",
              "2014-11-02T12:00:00"
            ],
            ["summary", {}, "text", "2nd occurrence exception event summary"],
            ["description", {}, "text", "2nd occurrence exception description"]
          ],
          []
        ]
      ]
    };
    var opts = {
      uid : "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com",
      recurrenceId : "2014-11-01T09:00:00",
      dtstart : "2014-11-01T09:00:00",
      dtend : "2014-11-01T10:00:00",
      freq: "DAILY",
      count : 5,
      summary: "Updated summary",
      updateType: "thisAndFuture"
    };
    ec.updateEvent(opts, function(err, evtJSON) {
      //console.log(util.inspect(doc, {colors: true, depth: 5}));
      assert(err === null, "err is not null");
      var mainEvt = new ICAL.Component(doc.vevents[0]), exEvt1 = new ICAL.Component(doc.vevents[1]), exEvt2 = new ICAL.Component(doc.vevents[2]);
      assert(mainEvt.getFirstPropertyValue("summary").toString() === opts.summary, "main evt summary not updated properly");
      assert( exEvt1.getFirstPropertyValue("summary").toString() === opts.summary, "exception event 1 summary not updated properly");
      assert( exEvt2.getFirstPropertyValue("summary").toString() === opts.summary, "exception event 2 summary not updated properly");
      done();
    });
  });

  it("Should stop old event from repeating and create a new event when updating a non-repeating property of 2+ occurrence with a pre-existing future exception event and applying updates to this and future", function(done) {
    doc = {
      "_id" : "5899182e1e1157919349134db9005873",
      "_rev" : "1-2bc7c31235b0091946e066b217147aff",
      "vevents" : [
        [ "vevent",
          [
            ["uid", {}, "text", "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com"],
            ["sequence", {}, "integer", 0],
            ["created", {}, "date-time", "2014-11-01T06:00:00Z"],
            ["last-modified", {}, "date-time", "2014-11-01T17:00:00Z"],
            ["dtstamp", {}, "date-time", "2014-11-01T17:00:00Z"],
            ["dtstart",
              {"tzid" : "America/Los_Angeles"},
              "date-time",
              "2014-11-01T09:00:00"
            ],
            ["dtend",
              {"tzid" : "America/Los_Angeles"},
              "date-time",
              "2014-11-01T10:00:00"
            ],
            ["rrule",
              {},
              "recur",
              {"freq": "DAILY", "count" : 5}
            ],
            ["summary", {}, "text", "Old summary"],
            ["description", {}, "text", "description"]
          ],
          []
        ],
        [ "vevent",
          [
            ["uid", {}, "text", "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com"],
            ["sequence", {}, "integer", 1],
            ["created", {}, "date-time", "2014-11-01T06:00:00Z"],
            ["last-modified", {}, "date-time", "2014-11-01T17:00:00Z"],
            ["dtstamp", {}, "date-time", "2014-11-01T17:00:00Z"],
            ["recurrence-id",
              {"tzid" : "America/Los_Angeles"},
              "date-time",
              "2014-11-03T09:00:00"
            ],
            ["dtstart",
              {"tzid" : "America/Los_Angeles"},
              "date-time",
              "2014-11-03T12:30:00"
            ],
            ["dtend",
              {"tzid" : "America/Los_Angeles"},
              "date-time",
              "2014-11-03T13:30:00"
            ],
            ["summary", {}, "text", "Exception event summary"],
            ["description", {}, "text", "description"]
          ],
          []
        ]
      ]
    };
    var opts = {
      uid : "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com",
      recurrenceId : "2014-11-02T09:00:00",
      dtstart: "2014-11-02T09:00:00",
      dtend: "2014-11-02T10:00:00",
      freq: "DAILY",
      count : 5,
      summary: "Updated summary",
      description: "description",
      updateType: "thisAndFuture"
    };
    ec.updateEvent(opts, function(err, evt) {
      //console.log(util.inspect(arguments, {colors: true, depth: 5}));
      assert(err === null, "err is not null");
      var oldMain = new ICAL.Component(doc.vevents[0]);
      assert(oldMain.getFirstPropertyValue("rrule").until == "2014-11-01T23:59:59", "until not set properly on old main event");
      assert(oldMain.getFirstPropertyValue("summary") == "Old summary", "old main summary updated when it should not have been");
      var newEvt = new ICAL.Component(evt[0]);
      //console.log(util.inspect(evt[0], {depth: null, colors: true}));
      assert(newEvt.getFirstPropertyValue("uid") !== oldMain.getFirstPropertyValue("uid"), "new event's UID is not different than the old event's UID");
      assert(newEvt.getFirstPropertyValue("summary") == opts.summary, "new event summary not created correctly");
      // I can"t access the exception event in the new event
      done();
    });
  });

  it("Should stop old event from repeating, create a new event, and remove future exception event when updating a repeating property of 2+ occurrence with a pre-existing future exception event that will not fall on one of the updated occurrence dates when updates are applied to this and future", function(done) {
    doc = {
      "_id" : "5899182e1e1157919349134db9005873",
      "_rev" : "1-2bc7c31235b0091946e066b217147aff",
      "vevents" : [
        [ "vevent",
          [
            ["uid", {}, "text", "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com"],
            ["sequence", {}, "integer", 0],
            ["created", {}, "date-time", "2014-11-01T06:00:00Z"],
            ["last-modified", {}, "date-time", "2014-11-01T17:00:00Z"],
            ["dtstamp", {}, "date-time", "2014-11-01T17:00:00Z"],
            ["dtstart",
              {"tzid" : "America/Los_Angeles"},
              "date-time",
              "2014-11-01T09:00:00"
            ],
            ["dtend",
              {"tzid" : "America/Los_Angeles"},
              "date-time",
              "2014-11-01T10:00:00"
            ],
            ["rrule",
              {},
              "recur",
              {"freq": "DAILY", "count" : 5}
            ],
            ["summary", {}, "text", "A summary"],
            ["description", {}, "text", "description"]
          ],
          []
        ],
        [ "vevent",
          [
            ["uid", {}, "text", "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com"],
            ["sequence", {}, "integer", 1],
            ["created", {}, "date-time", "2014-11-01T06:00:00Z"],
            ["last-modified", {}, "date-time", "2014-11-01T17:00:00Z"],
            ["dtstamp", {}, "date-time", "2014-11-01T17:00:00Z"],
            ["recurrence-id",
              {"tzid" : "America/Los_Angeles"},
              "date-time",
              "2014-11-03T09:00:00"
            ],
            ["dtstart",
              {"tzid" : "America/Los_Angeles"},
              "date-time",
              "2014-11-03T12:30:00"
            ],
            ["dtend",
              {"tzid" : "America/Los_Angeles"},
              "date-time",
              "2014-11-03T13:30:00"
            ],
            ["summary", {}, "text", "Exception event summary"],
            ["description", {}, "text", "description"]
          ],
          []
        ]
      ]
    };
    var opts = {
      uid : "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com",
      recurrenceId : "2014-11-02T09:00:00",
      dtstart: "2014-11-02T09:00:00",
      dtend: "2014-11-02T10:00:00",
      freq: "MONTHLY",
      count : 5,
      summary : "A summary",
      updateType: "thisAndFuture"
    };
    ec.updateEvent(opts, function(err, evtJSON) {
      //console.log(util.inspect(doc, {colors: true, depth: 5}));
      assert(err === null, "err is not null");
      // Assert old event has until 23:59:59
      var oldMain = new ICAL.Component(doc.vevents[0]);
      assert(oldMain.getFirstPropertyValue("rrule").until == "2014-11-01T23:59:59", "until not set properly on old main event");
      // Assert exception event was removed - Don"t have access to the new doc here so can"t
      done();
    });
  });

  it("Should update a non-repeat property of the main event and all exception events when updates are applied to all occurrences.", function(done) {
    doc = JSON.parse(JSON.stringify(repeatingEvtWithExceptionDoc));
    var opts = {
      uid : "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com",
      recurrenceId : "2014-11-11T09:00:00",
      summary : "Updated summary",
      dtstart: "2014-11-11T09:00:00",
      dtend: "2014-11-11T10:00:00",
      freq: "DAILY",
      count : 5,
      updateType: "all"
    };
    ec.updateEvent(opts, function(err, evtJSON) {
      //console.log(util.inspect(doc, {colors: true, depth: 5}));
      assert(err === null, "err is not null");
      for(var evt, i = 0; i < doc.vevents.length; ++i) {
        evt = new ICAL.Component(doc.vevents[i]);
        assert(evt.getFirstPropertyValue("summary") == opts.summary, "summary not updated propertly");
      }
      done();
    });
  });

  it("Should remove all exceptions when updating a repeat property of any occurrence in a series with a pre-existing exception event and applying updates to all occurrences.", function(done) {
    doc = JSON.parse(JSON.stringify(repeatingEvtWithExceptionDoc));
    var opts = {
      uid : "c8f7f2fd-4216-4e3b-8e38-c17190472651@intellasset.com",
      recurrenceId : "2014-11-11T09:00:00",
      dtstart: "2014-11-11T12:00:00",
      dtend: "2014-11-11T13:00:00",
      freq: "MONTHLY",
      count : 5,
      summary : "A summary",
      updateType: "all"
    };
    ec.updateEvent(opts, function(err, evtJSON) {
      //console.log("doc: ", util.inspect(doc, {colors: true, depth: 5}));
      assert(err === null, "err is not null");
      assert(doc.vevents.length === 1, "doc.vevents.length !== 1");
      done();
    });
  });

});

/**
 * Expand an event
 */
describe("Expand an event", function(){
  var sandbox;
  before(function(){
    sandbox = sinon.sandbox.create();
    sandbox.stub(db, "getEvent", function(uid, callback) {
      callback(null, doc.vevents);
    });
    sandbox.stub(db, "updateEvent", function(evt, callback) {
      doc.vevents = evt;
      callback(null, evt);
    });
    sandbox.stub(db, "deleteEvent", function(evt, callback) {
      callback(null, doc.vevents);
    });
  });
  after(function(){
    sandbox.restore();
  });

  it("Should return the main event when expanding a non-repeating event", function() {
    doc = JSON.parse(JSON.stringify(nonRepeatingEvtDoc));
    var expansion = ec.expandEvent(doc.vevents);
    assert(expansion.length === 1, "expansion.length !== 1");
    var evt = expansion[0];
    var origEvt = new ICAL.Event(new ICAL.Component(doc.vevents[0]));
    assert(evt.title == origEvt.summary, "title does not match summary");
    assert(evt.start == origEvt.startDate.toString(), "start does not match dtstart");
    assert(evt.end == origEvt.endDate.toString(), "end does not match dtend");
  });

  it("Should expand a repeating event", function(done) {
    doc = JSON.parse(JSON.stringify(repeatingEvtWithExceptionDoc));
    var expansion = ec.expandEvent(doc.vevents);
    assert(expansion.length == 5, "expansion.length !== 5");
    var ex = expansion[1];
    assert(ex.title == new ICAL.Event(new ICAL.Component(repeatingEvtWithExceptionDoc.vevents[1])).summary, "title does not match summary");
    writeToFile(expansion, function(){ done(); });
  });

});

/**
 * Delete an event
 */

describe("Delete event", function(){
  var sandbox, doc;
  before(function(){
    sandbox = sinon.sandbox.create();
    sandbox.stub(db, "getEvent", function(uid, callback) {
      callback(null, doc.vevents);
    });
    sandbox.stub(db, "updateEvent", function(evt, callback) {
      doc.vevents = evt;
      callback(null, evt);
    });
    sandbox.stub(db, "deleteEvent", function(evt, callback) {
      callback(null, doc.vevents);
    });
  });
  after(function(){
    sandbox.restore();
  });

  it("Should add an exdate when deleting an instance only with no pre-existing exception", function(done) {
    doc = JSON.parse(JSON.stringify(repeatingEvtDoc));
    var opts = {
      uid : new ICAL.Component(doc.vevents[0]).getFirstPropertyValue("uid"),
      recurrenceId : "2014-11-10T09:00:00",
      applyTo: "instanceOnly"
    };
    ec.deleteEvent(opts, function(err, evt){
      assert(new ICAL.Component(evt[0]).getFirstPropertyValue("exdate").toString() == opts.recurrenceId, "exdate not set properly");
      done();
    });
  });

  it("Should add an exdate and remove exception when deleting an instance only with a pre-existing exception", function(done) {
    doc = JSON.parse(JSON.stringify(repeatingEvtWithExceptionDoc));
    var opts = {
      uid : new ICAL.Component(doc.vevents[0]).getFirstPropertyValue("uid"),
      recurrenceId : "2014-11-10T09:00:00",
      applyTo: "instanceOnly"
    };
    ec.deleteEvent(opts, function(err, evt){
      assert(new ICAL.Component(evt[0]).getFirstPropertyValue("exdate").toString() == opts.recurrenceId, "exdate not set properly");
      assert(evt.length == 1, "exception event not removed");
      done();
    });
  });

  it("Should stop event from repeating and remove exception when deleting an occurrence of an event with an excpetion and applying to this and future", function(done) {
    doc = JSON.parse(JSON.stringify(repeatingEvtWithExceptionDoc));
    var opts = {
      uid : new ICAL.Component(doc.vevents[0]).getFirstPropertyValue("uid"),
      recurrenceId : "2014-11-10T09:00:00",
      applyTo: "thisAndFuture"
    };
    ec.deleteEvent(opts, function(err, evt){
      var until = new ICAL.Component(evt[0]).getFirstPropertyValue("rrule").until.toString();
      assert(until, "until not added to the main event");
      assert(evt.length == 1, "exception event not removed");
      done();
    });
  });

  it("Should delete the entire event when applying delete to all", function(done){
    doc = JSON.parse(JSON.stringify(repeatingEvtDoc));
    var opts = {
      uid : new ICAL.Component(doc.vevents[0]).getFirstPropertyValue("uid"),
      applyTo: "all"
    };
    ec.deleteEvent(opts, function(err, evt){
      assert.isNull(err, "err is not null");
      assert.isDefined(evt, "evt is not defined");
      done();
    });
  });

});


text:
package common

import (
	"bufio"
	"fmt"
	"net"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"
	"syscall"

	"github.com/appc/spec/aci"
	"github.com/appc/spec/schema/types"
	"github.com/hashicorp/errwrap"
)

const (
	sharedVolumesDir = "/sharedVolumes"
	stage1Dir        = "/stage1"
	stage2Dir        = "/opt/stage2"
	AppsInfoDir      = "/appsinfo"

	EnvLockFd                    = "RKT_LOCK_FD"
	EnvSELinuxContext            = "RKT_SELINUX_CONTEXT"
	EnvSELinuxMountContext       = "RKT_SELINUX_MOUNT_CONTEXT"
	Stage1TreeStoreIDFilename    = "stage1TreeStoreID"
	AppTreeStoreIDFilename       = "treeStoreID"
	OverlayPreparedFilename      = "overlay-prepared"
	PrivateUsersPreparedFilename = "private-users-prepared"

	PrepareLock = "prepareLock"

	MetadataServicePort    = 18112
	MetadataServiceRegSock = "/run/rkt/metadata-svc.sock"

	APIServiceListenAddr = "localhost:15441"

	DefaultLocalConfigDir  = "/etc/rkt"
	DefaultSystemConfigDir = "/usr/lib/rkt"

	// Default perm bits for the regular files
	// within the stage1 directory. (e.g. image manifest,
	// pod manifest, stage1ID, etc).
	DefaultRegularFilePerm = os.FileMode(0640)

	// Default perm bits for the regular directories
	// within the stage1 directory.
	DefaultRegularDirPerm = os.FileMode(0750)
)

const (
	FsMagicAUFS = 0x61756673 // https://goo.gl/CBwx43
	FsMagicZFS  = 0x2FC12FC1 // https://goo.gl/xTvzO5
)

// Stage1ImagePath returns the path where the stage1 app image (unpacked ACI) is rooted,
// (i.e. where its contents are extracted during stage0).
func Stage1ImagePath(root string) string {
	return filepath.Join(root, stage1Dir)
}

// Stage1RootfsPath returns the path to the stage1 rootfs
func Stage1RootfsPath(root string) string {
	return filepath.Join(Stage1ImagePath(root), aci.RootfsDir)
}

// Stage1ManifestPath returns the path to the stage1's manifest file inside the expanded ACI.
func Stage1ManifestPath(root string) string {
	return filepath.Join(Stage1ImagePath(root), aci.ManifestFile)
}

// PodManifestPath returns the path in root to the Pod Manifest
func PodManifestPath(root string) string {
	return filepath.Join(root, "pod")
}

// AppsPath returns the path where the apps within a pod live.
func AppsPath(root string) string {
	return filepath.Join(Stage1RootfsPath(root), stage2Dir)
}

// AppPath returns the path to an app's rootfs.
func AppPath(root string, appName types.ACName) string {
	return filepath.Join(AppsPath(root), appName.String())
}

// AppRootfsPath returns the path to an app's rootfs.
func AppRootfsPath(root string, appName types.ACName) string {
	return filepath.Join(AppPath(root, appName), aci.RootfsDir)
}

// RelAppPath returns the path of an app relative to the stage1 chroot.
func RelAppPath(appName types.ACName) string {
	return filepath.Join(stage2Dir, appName.String())
}

// RelAppRootfsPath returns the path of an app's rootfs relative to the stage1 chroot.
func RelAppRootfsPath(appName types.ACName) string {
	return filepath.Join(RelAppPath(appName), aci.RootfsDir)
}

// ImageManifestPath returns the path to the app's manifest file of a pod.
func ImageManifestPath(root string, appName types.ACName) string {
	return filepath.Join(AppPath(root, appName), aci.ManifestFile)
}

// AppsInfoPath returns the path to the appsinfo directory of a pod.
func AppsInfoPath(root string) string {
	return filepath.Join(root, AppsInfoDir)
}

// AppInfoPath returns the path to the app's appsinfo directory of a pod.
func AppInfoPath(root string, appName types.ACName) string {
	return filepath.Join(AppsInfoPath(root), appName.String())
}

// AppTreeStoreIDPath returns the path to the app's treeStoreID file of a pod.
func AppTreeStoreIDPath(root string, appName types.ACName) string {
	return filepath.Join(AppInfoPath(root, appName), AppTreeStoreIDFilename)
}

// AppImageManifestPath returns the path to the app's ImageManifest file
func AppImageManifestPath(root string, appName types.ACName) string {
	return filepath.Join(AppInfoPath(root, appName), aci.ManifestFile)
}

// SharedVolumesPath returns the path to the shared (empty) volumes of a pod.
func SharedVolumesPath(root string) string {
	return filepath.Join(root, sharedVolumesDir)
}

// MetadataServicePublicURL returns the public URL used to host the metadata service
func MetadataServicePublicURL(ip net.IP, token string) string {
	return fmt.Sprintf("http://%v:%v/%v", ip, MetadataServicePort, token)
}

func GetRktLockFD() (int, error) {
	if v := os.Getenv(EnvLockFd); v != "" {
		fd, err := strconv.ParseUint(v, 10, 32)
		if err != nil {
			return -1, err
		}
		return int(fd), nil
	}
	return -1, fmt.Errorf("%v env var is not set", EnvLockFd)
}

// SupportsOverlay returns whether the system supports overlay filesystem
func SupportsOverlay() bool {
	exec.Command("modprobe", "overlay").Run()

	f, err := os.Open("/proc/filesystems")
	if err != nil {
		fmt.Println("error opening /proc/filesystems")
		return false
	}
	defer f.Close()

	s := bufio.NewScanner(f)
	for s.Scan() {
		if s.Text() == "nodev\toverlay" {
			return true
		}
	}
	return false
}

// SupportsUserNS returns whether the kernel has CONFIG_USER_NS set
func SupportsUserNS() bool {
	if _, err := os.Stat("/proc/self/uid_map"); err == nil {
		return true
	}

	return false
}

// NetList implements the flag.Value interface to allow specification of --net with and without values
// Example: --net="all,net1:k1=v1;k2=v2,net2:l1=w1"
type NetList struct {
	mapping map[string]string
}

func (l *NetList) String() string {
	return strings.Join(l.Strings(), ",")
}

func (l *NetList) Set(value string) error {
	if l.mapping == nil {
		l.mapping = make(map[string]string)
	}
	for _, s := range strings.Split(value, ",") {
		netArgsPair := strings.Split(s, ":")
		netName := netArgsPair[0]

		if netName == "" {
			return fmt.Errorf("netname must not be empty")
		}

		if _, duplicate := l.mapping[netName]; duplicate {
			return fmt.Errorf("found duplicate netname %q", netName)
		}

		switch {
		case len(netArgsPair) == 1:
			l.mapping[netName] = ""
		case len(netArgsPair) == 2:
			if netName == "all" ||
				netName == "host" {
				return fmt.Errorf("arguments are not supported by special netname %q", netName)
			}
			l.mapping[netName] = netArgsPair[1]
		case len(netArgsPair) > 2:
			return fmt.Errorf("network %q provided with invalid arguments: %v", netName, netArgsPair[1:])
		default:
			return fmt.Errorf("unexpected case when processing network %q", s)
		}
	}
	return nil
}

func (l *NetList) Type() string {
	return "netList"
}

func (l *NetList) Strings() []string {
	if len(l.mapping) == 0 {
		return []string{"default"}
	}

	var list []string
	for k, v := range l.mapping {
		if v == "" {
			list = append(list, k)
		} else {
			list = append(list, fmt.Sprintf("%s:%s", k, v))
		}
	}
	return list
}

func (l *NetList) StringsOnlyNames() (list []string) {
	for k := range l.mapping {
		list = append(list, k)
	}

	return
}

// Check if host networking has been requested
func (l *NetList) Host() bool {
	return l.Specific("host")
}

// Check if 'none' (loopback only) networking has been requested
func (l *NetList) None() bool {
	return l.Specific("none")
}

// Check if the container needs to be put in a separate network namespace
func (l *NetList) Contained() bool {
	return !l.Host() && len(l.mapping) > 0
}

func (l *NetList) Specific(net string) bool {
	_, exists := l.mapping[net]
	return exists
}

func (l *NetList) SpecificArgs(net string) string {
	return l.mapping[net]
}

func (l *NetList) All() bool {
	return l.Specific("all")
}

// LookupPath search for bin in paths. If found, it returns its absolute path,
// if not, an error
func LookupPath(bin string, paths string) (string, error) {
	pathsArr := filepath.SplitList(paths)
	for _, path := range pathsArr {
		binPath := filepath.Join(path, bin)
		binAbsPath, err := filepath.Abs(binPath)
		if err != nil {
			return "", fmt.Errorf("unable to find absolute path for %s", binPath)
		}
		d, err := os.Stat(binAbsPath)
		if err != nil {
			continue
		}
		// Check the executable bit, inspired by os.exec.LookPath()
		if m := d.Mode(); !m.IsDir() && m&0111 != 0 {
			return binAbsPath, nil
		}
	}
	return "", fmt.Errorf("unable to find %q in %q", bin, paths)
}

// SystemdVersion parses and returns the version of a given systemd binary
func SystemdVersion(systemdBinaryPath string) (int, error) {
	versionBytes, err := exec.Command(systemdBinaryPath, "--version").CombinedOutput()
	if err != nil {
		return -1, errwrap.Wrap(fmt.Errorf("unable to probe %s version", systemdBinaryPath), err)
	}
	versionStr := strings.SplitN(string(versionBytes), "\n", 2)[0]
	var version int
	n, err := fmt.Sscanf(versionStr, "systemd %d", &version)
	if err != nil || n != 1 {
		return -1, fmt.Errorf("cannot parse version: %q", versionStr)
	}

	return version, nil
}

// FSSupportsOverlay checks whether the filesystem under which
// a specified path resides is compatible with OverlayFS
func FSSupportsOverlay(path string) bool {
	var data syscall.Statfs_t
	err := syscall.Statfs(path, &data)
	if err != nil {
		return false
	}

	if data.Type == FsMagicAUFS ||
		data.Type == FsMagicZFS {
		return false
	}

	return true
}

// RemoveEmptyLines removes empty lines from the given string
// and breaks it up into a list of strings at newline characters
func RemoveEmptyLines(str string) []string {
	lines := make([]string, 0)

	for _, v := range strings.Split(str, "\n") {
		if len(v) > 0 {
			lines = append(lines, v)
		}
	}

	return lines
}

redpajama_set_name: RedPajamaGithub


text:
Template.weddingsShow.created = function () {
  this.autorun(function () {
    this.subscription = Meteor.subscribe('wedding', Router.current().params._id);
  }.bind(this));
};

Template.weddingsShow.rendered = function () {
  this.autorun(function () {
    if (!this.subscription.ready()) {
      IonLoading.show();
    } else {
      IonLoading.hide();
    }
  }.bind(this));
};

Template.weddingsShow.helpers({
  wedding: function () {
    return Weddings.findOne({_id: Router.current().params._id});
  },

  comments: function () {
    return Comments.find({weddingId: Router.current().params._id}, {sort: {createdAt: -1}});
  }
});

Template.weddingsShow.events({
  'click [data-action=new-comment]': function (event, template) {
    if (Meteor.user()) {
      IonModal.open('newComment', {weddingId: this._id});
    } else {
      IonModal.open('signIn');
    }
  }

});


text:
package org.sakaiproject.service.gradebook.shared;

import java.util.Date;

/**
 *
 */
public class GradeDefinition {
	private String studentUid;
	private String graderUid;
	private Date dateRecorded;
	private String grade;
	private String gradeComment;
	private int gradeEntryType;
	private boolean gradeReleased;

	public String getStudentUid() {
		return studentUid;
	}
	public void setStudentUid(String studentUid) {
		this.studentUid = studentUid;
	}

	public String getGraderUid() {
		return graderUid;
	}
	public void setGraderUid(String graderUid) {
		this.graderUid = graderUid;
	}

	public Date getDateRecorded() {
		return dateRecorded;
	}
	public void setDateRecorded(Date dateRecorded) {
		this.dateRecorded = dateRecorded;
	}

	/**
	 *
	 * @return current grade for this student in the format according to
	 * the gradebook's grade entry type ie %, letter, points
	 */
	public String getGrade() {
		return grade;
	}

	/**
	 * current grade for this student in the format according to
	 * the gradebook's grade entry type ie %, letter, points
	 * @param grade
	 */
	public void setGrade(String grade) {
		this.grade = grade;
	}

	public String getGradeComment()
	{
		return gradeComment;
	}

	public void setGradeComment(String gradeComment)
	{
		this.gradeComment = gradeComment;
	}

	/**
	 *
	 * @return constant equivalent to the grade entry type for the gb -
	 * %, letter, points, etc. lets you know what format the given grade will
	 * be in
	 */
	public int getGradeEntryType() {
		return gradeEntryType;
	}

	/**
	 * constant equivalent to the grade entry type for the gb -
	 * %, letter, points, etc.  lets you know what format the given grade will
	 * be in
	 * @param gradeEntryType
	 */
	public void setGradeEntryType(int gradeEntryType) {
		this.gradeEntryType = gradeEntryType;
	}

	/**
	 *
	 * @return true if this grade has been released to the student
	 */
	public boolean isGradeReleased() {
		return gradeReleased;
	}

	/**
	 * true if this grade has been released to the student
	 * @param gradeReleased
	 */
	public void setGradeReleased(boolean gradeReleased) {
		this.gradeReleased = gradeReleased;
	}

}


text:
<#

.DESCRIPTION
  The DSC will configure a VSTS agent on a VM using Windows Powershell DSC.

.NOTES
  Version:        1.0
  Author:         Sampanna Mohite / Nazakat Hussain
  Creation Date:  12/03/2018
  Purpose/Change: Automated Deployments of VSTS Agents
#>

Configuration DeployVSTSAgent
{
  param (
    [Parameter(Mandatory=$false)]
    [string]$MachineName,

    [Parameter(Mandatory=$true)]
    [string]$UserName,

    [Parameter(Mandatory=$true)]
    [string]$Password,

    [Parameter(Mandatory=$false)]
    [string]$VSTSAccount,

    [Parameter(Mandatory=$true)]
    [string]$PersonalAccessToken,

    [Parameter(Mandatory=$true)]
    [string]$AgentName,

    [Parameter(Mandatory=$true)]
    [string]$PoolName,

    [Parameter(Mandatory=$true)]
    [int]$AgentCount,

    [Parameter(Mandatory=$true)]
    [string[]]$Modules
  )

  Import-DscResource -ModuleName PsDesiredStateConfiguration

  Node ($MachineName)
  {
    Script SetVstsAgents{
        GetScript = {@{
            Result = ""
        }}

        TestScript = {
            $false
        }
        SetScript ={

            #md c:\TestFolder01

            Write-Verbose "VSTSAccounbt - $using:VSTSAccount" -verbose
            Write-Verbose "Token" -verbose
            Write-Verbose "Agent count - $using:AgentCount" -verbose
            Write-Verbose "Entering DeployVSTSAgent.config.ps1" -verbose

            #$currentLocation = Split-Path -parent $MyInvocation.MyCommand.Definition
            #Write-Verbose "Current folder: $currentLocation" -verbose

            #Create a temporary directory where to download from VSTS the agent package (vsts-agent.zip) and then launch the configuration.
            $agentTempFolderName = Join-Path $env:temp ([System.IO.Path]::GetRandomFileName()).replace('.','')
            New-Item -ItemType Directory -Force -Path $agentTempFolderName
            Write-Verbose "Temporary Agent download folder: $agentTempFolderName" -verbose

            $serverUrl = "https://dev.azure.com/$using:VSTSAccount"
            Write-Verbose "Server URL: $serverUrl" -verbose

            $retryCount = 3
            $retries = 1

            Write-Verbose "Downloading Agent install files" -verbose
            [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

            do
            {
                try
                {
                    Write-Verbose "Trying to get download URL for latest VSTS agent release..."
                    $latestRelease = Invoke-RestMethod -Uri "https://api.github.com/repos/Microsoft/vsts-agent/releases"
                    $latestRelease = $latestRelease | Where-Object assets -ne $null | Sort-Object created_at -Descending | Select-Object -First 1
                    $assetsURL = ($latestRelease.assets).browser_download_url
                    $latestReleaseDownloadUrl = ((Invoke-RestMethod -Uri $assetsURL) -match 'win-x64').downloadurl
                    Invoke-WebRequest -Uri $latestReleaseDownloadUrl -Method Get -OutFile "$agentTempFolderName\agent.zip"
                    Write-Verbose "Downloaded agent successfully on attempt $retries" -verbose
                    break
                }
                catch
                {
                    $exceptionText = ($_ | Out-String).Trim()
                    Write-Verbose "Exception occurred downloading agent: $exceptionText in try number $retries" -verbose
                    $retries++
                    Start-Sleep -Seconds 30
                }
            }
            while ($retries -le $retryCount)

            Write-Verbose "Installing agents $using:AgentCount" -verbose
            Write-Verbose "Installing agents $using:AgentCount" -verbose
            Write-Verbose "VSTSAccounbt - $using:VSTSAccount" -verbose
            Write-Verbose "Token" -verbose
            Write-Verbose "Agent count - $using:AgentCount" -verbose
            Write-Verbose "Entering InstallVSOAgent.ps1" -verbose

            $serverUrl = "https://dev.azure.com/$using:VSTSAccount"
            Write-Verbose "$serverUrl" -verbose

            for ($i=0; $i -lt $using:AgentCount; $i++)
            {
                $Agent = ($using:AgentName + "-" + ($i + 1))
                Write-Verbose "Installing agents $Agent" -verbose

                # Construct the agent folder under the main (hardcoded) C: drive.
                $agentInstallationPath = Join-Path "C:" $Agent

                # Create the directory for this agent.
                New-Item -ItemType Directory -Force -Path $agentInstallationPath

                # Set the current directory to the agent dedicated one previously created.
                Push-Location -Path $agentInstallationPath

                Write-Verbose "Extracting the zip file for the agent" -verbose
                $destShellFolder = (new-object -com shell.application).namespace("$agentInstallationPath")
                $destShellFolder.CopyHere((new-object -com shell.application).namespace("$agentTempFolderName\agent.zip").Items(),16)

                # Removing the ZoneIdentifier from files downloaded from the internet so the plugins can be loaded
                # Don't recurse down _work or _diag, those files are not blocked and cause the process to take much longer
                Write-Verbose "Unblocking files" -verbose
                Get-ChildItem -Recurse -Path $agentInstallationPath | Unblock-File | out-null

                # Retrieve the path to the config.cmd file.
                $agentConfigPath = [System.IO.Path]::Combine($agentInstallationPath, 'config.cmd')
                Write-Verbose "Agent Location = $agentConfigPath" -Verbose
                if (![System.IO.File]::Exists($agentConfigPath))
                {
                    Write-Error "File not found: $agentConfigPath" -Verbose
                    return
                }

                # Call the agent with the configure command and all the options (this creates the settings file) without prompting
                # the user or blocking the cmd execution
                Write-Verbose "Configuring agent '$($Agent)'" -Verbose

                $pat = $using:PersonalAccessToken
                #Write-Verbose "Configuring agent '$($pat)'" -Verbose
                .\config.cmd --unattended --url $serverUrl --auth PAT --token $pat --pool $using:PoolName --agent $Agent --runasservice

                Write-Verbose "Agent install output: $LASTEXITCODE" -Verbose

                Pop-Location
            }

            # Adding new Path to PSModulePath environment variable
            $CurrentValue = [Environment]::GetEnvironmentVariable("PSModulePath", "Machine")
            [Environment]::SetEnvironmentVariable("PSModulePath", $CurrentValue + ";C:\Modules", "Machine")
            $NewValue = [Environment]::GetEnvironmentVariable("PSModulePath", "Machine")
            Write-Verbose "new Path is: $($NewValue)" -verbose

            # Creating new Path
            if (!(Test-Path -Path C:\Modules -ErrorAction SilentlyContinue))
            { New-Item -ItemType Directory -Name Modules -Path C:\ -Verbose }

            # Installing New Modules and Removing Old
            #Foreach ($Module in $using:Modules)
            { Find-Module -Name $Module.Name -RequiredVersion $Module.Version -Repository PSGallery -Verbose | Save-Module -Path C:\Modules -Verbose }

            #$DefaultModules = "PowerShellGet", "PackageManagement","Pester"

            Foreach ($Module in $DefaultModules)
            {
                if ($tmp = Get-Module $Module -ErrorAction SilentlyContinue) {
                Remove-Module $Module -Force }
                Find-Module -Name $Module -Repository PSGallery -Verbose | Install-Module -Force -Confirm:$false -SkipPublisherCheck -Verbose
            }

            # Uninstalling old Azure PowerShell Modules
            #$programName = "Microsoft Azure PowerShell"
            #$app = Get-WmiObject -Class Win32_Product -Filter "Name Like '$($programName)%'" -Verbose
            #$app.Uninstall()

            Write-Verbose "Exiting DeployVSTSAgent.Config.ps1" -Verbose
        }
    }
  }
}


text:
module Author

  def self.table_name_prefix
    'author_'
  end

  def self.fetch_data(user)
    users_online = User.where('last_seen > ?', 5.minutes.ago)
    site_storages = SiteStorage.fetch_data(user)
    site_types = SiteType.fetch_data(user)
    widgets = Widget.fetch_data(user)
    user_logs = User.current.user_logs
    error_logs = User.current.error_logs
    {
        users: User.count,
        users_online: users_online.length,
        site_storages: site_storages.length,
        site_types: site_types.length,
        widget_categories: WidgetCategory.count,
        widgets: widgets.length,
        user_logs: user_logs.length,
        error_logs: error_logs.length
    }
  end
end


text:
package org.apache.axis2.transport.testkit.http;

import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.axis2.transport.testkit.message.IncomingMessage;
import org.apache.axis2.transport.testkit.message.RESTMessage;
import org.apache.axis2.transport.testkit.message.RESTMessage.Parameter;
import org.mortbay.http.HttpException;
import org.mortbay.http.HttpRequest;

public class JettyRESTAsyncEndpoint extends JettyAsyncEndpoint<RESTMessage> {
    @Override
    protected IncomingMessage<RESTMessage> handle(HttpRequest request)
            throws HttpException, IOException {

        List<Parameter> parameters = new LinkedList<Parameter>();
        for (Map.Entry<String,List<String>> entry :
                ((Map<String,List<String>>)request.getParameters()).entrySet()) {
            for (String value : entry.getValue()) {
                parameters.add(new Parameter(entry.getKey(), value));
            }
        }
        return new IncomingMessage<RESTMessage>(null, new RESTMessage(parameters.toArray(
                new Parameter[parameters.size()])));
    }
}


text:
<?php

namespace Cake\I18n;

use Carbon\Carbon;
use IntlDateFormatter;
use JsonSerializable;
use RuntimeException;

/**
 * Extends the built-in DateTime class to provide handy methods and locale-aware
 * formatting helpers
 *
 */
class Time extends Carbon implements JsonSerializable
{

    /**
     * The format to use when formatting a time using `Cake\I18n\Time::i18nFormat()`
     * and `__toString`
     *
     * The format should be either the formatting constants from IntlDateFormatter as
     * described in (http://www.php.net/manual/en/class.intldateformatter.php) or a pattern
     * as specified in (http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details)
     *
     * It is possible to provide an array of 2 constants. In this case, the first position
     * will be used for formatting the date part of the object and the second position
     * will be used to format the time part.
     *
     * @var mixed
     * @see \Cake\I18n\Time::i18nFormat()
     */
    protected static $_toStringFormat = [IntlDateFormatter::SHORT, IntlDateFormatter::SHORT];

    /**
     * The format to use when formatting a time using `Cake\I18n\Time::nice()`
     *
     * The format should be either the formatting constants from IntlDateFormatter as
     * described in (http://www.php.net/manual/en/class.intldateformatter.php) or a pattern
     * as specified in (http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details)
     *
     * It is possible to provide an array of 2 constants. In this case, the first position
     * will be used for formatting the date part of the object and the second position
     * will be used to format the time part.
     *
     * @var mixed
     * @see \Cake\I18n\Time::nice()
     */
    public static $niceFormat = [IntlDateFormatter::MEDIUM, IntlDateFormatter::SHORT];

    /**
     * The default locale to be used for displaying formatted date strings.
     *
     * @var string
     */
    public static $defaultLocale;

    /**
     * The format to use when formatting a time using `Cake\I18n\Time::timeAgoInWords()`
     * and the difference is more than `Cake\I18n\Time::$wordEnd`
     *
     * @var string
     * @see \Cake\I18n\Time::timeAgoInWords()
     */
    public static $wordFormat = [IntlDateFormatter::SHORT, -1];

    /**
     * The format to use when formatting a time using `Time::timeAgoInWords()`
     * and the difference is less than `Time::$wordEnd`
     *
     * @var array
     * @see \Cake\I18n\Time::timeAgoInWords()
     */
    public static $wordAccuracy = [
        'year' => "day",
        'month' => "day",
        'week' => "day",
        'day' => "hour",
        'hour' => "minute",
        'minute' => "minute",
        'second' => "second",
    ];

    /**
     * The end of relative time telling
     *
     * @var string
     * @see \Cake\I18n\Time::timeAgoInWords()
     */
    public static $wordEnd = '+1 month';

    /**
     * In-memory cache of date formatters
     *
     * @var array
     */
    protected static $_formatters = [];

    /**
     * {@inheritDoc}
     */
    public function __construct($time = null, $tz = null)
    {
        if ($time instanceof \DateTime) {
            $tz = $time->getTimeZone();
            $time = $time->format('Y-m-d H:i:s');
        }

        if (is_numeric($time)) {
            $time = '@' . $time;
        }

        parent::__construct($time, $tz);
    }

    /**
     * Returns a nicely formatted date string for this object.
     *
     * The format to be used is stored in the static property `Time::niceFormat`.
     *
     * @param string|\DateTimeZone|null $timezone Timezone string or DateTimeZone object
     * in which the date will be displayed. The timezone stored for this object will not
     * be changed.
     * @param string|null $locale The locale name in which the date should be displayed (e.g. pt-BR)
     * @return string Formatted date string
     */
    public function nice($timezone = null, $locale = null)
    {
        return $this->i18nFormat(static::$niceFormat, $timezone, $locale);
    }

    /**
     * Returns true if this object represents a date within the current week
     *
     * @return bool
     */
    public function isThisWeek()
    {
        return static::now($this->getTimezone())->format('W o') == $this->format('W o');
    }

    /**
     * Returns true if this object represents a date within the current month
     *
     * @return bool
     */
    public function isThisMonth()
    {
        return static::now($this->getTimezone())->format('m Y') == $this->format('m Y');
    }

    /**
     * Returns true if this object represents a date within the current year
     *
     * @return bool
     */
    public function isThisYear()
    {
        return static::now($this->getTimezone())->format('Y') == $this->format('Y');
    }

    /**
     * Returns the quarter
     *
     * @param bool $range Range.
     * @return mixed 1, 2, 3, or 4 quarter of year or array if $range true
     */
    public function toQuarter($range = false)
    {
        $quarter = ceil($this->format('m') / 3);
        if ($range === false) {
            return $quarter;
        }

        $year = $this->format('Y');
        switch ($quarter) {
            case 1:
                return [$year . '-01-01', $year . '-03-31'];
            case 2:
                return [$year . '-04-01', $year . '-06-30'];
            case 3:
                return [$year . '-07-01', $year . '-09-30'];
            case 4:
                return [$year . '-10-01', $year . '-12-31'];
        }
    }

    /**
     * Returns a UNIX timestamp.
     *
     * @return string UNIX timestamp
     */
    public function toUnixString()
    {
        return $this->format('U');
    }

    /**
     * Returns either a relative or a formatted absolute date depending
     * on the difference between the current time and this object.
     *
     * ### Options:
     *
     * - `from` => another Time object representing the "now" time
     * - `format` => a fall back format if the relative time is longer than the duration specified by end
     * - `accuracy` => Specifies how accurate the date should be described (array)
     *    - year =>   The format if years > 0   (default "day")
     *    - month =>  The format if months > 0  (default "day")
     *    - week =>   The format if weeks > 0   (default "day")
     *    - day =>    The format if weeks > 0   (default "hour")
     *    - hour =>   The format if hours > 0   (default "minute")
     *    - minute => The format if minutes > 0 (default "minute")
     *    - second => The format if seconds > 0 (default "second")
     * - `end` => The end of relative time telling
     * - `relativeString` => The printf compatible string when outputting relative time
     * - `absoluteString` => The printf compatible string when outputting absolute time
     * - `timezone` => The user timezone the timestamp should be formatted in.
     *
     * Relative dates look something like this:
     *
     * - 3 weeks, 4 days ago
     * - 15 seconds ago
     *
     * Default date formatting is d/M/YY e.g: on 18/2/09. Formatting is done internally using
     * `i18nFormat`, see the method for the valid formatting strings
     *
     * The returned string includes 'ago' or 'on' and assumes you'll properly add a word
     * like 'Posted ' before the function output.
     *
     * NOTE: If the difference is one week or more, the lowest level of accuracy is day
     *
     * @param array $options Array of options.
     * @return string Relative time string.
     */
    public function timeAgoInWords(array $options = [])
    {
        $time = $this;

        $timezone = null;
        $format = static::$wordFormat;
        $end = static::$wordEnd;
        $relativeString = __d('cake', '%s ago');
        $absoluteString = __d('cake', 'on %s');
        $accuracy = static::$wordAccuracy;
        $from = static::now();
        $opts = ['timezone', 'format', 'end', 'relativeString', 'absoluteString', 'from'];

        foreach ($opts as $option) {
            if (isset($options[$option])) {
                ${$option} = $options[$option];
                unset($options[$option]);
            }
        }

        if (isset($options['accuracy'])) {
            if (is_array($options['accuracy'])) {
                $accuracy = $options['accuracy'] + $accuracy;
            } else {
                foreach ($accuracy as $key => $level) {
                    $accuracy[$key] = $options['accuracy'];
                }
            }
        }

        if ($timezone) {
            $time = clone $this;
            $time->timezone($timezone);
        }

        $now = $from->format('U');
        $inSeconds = $time->format('U');
        $backwards = ($inSeconds > $now);

        $futureTime = $now;
        $pastTime = $inSeconds;
        if ($backwards) {
            $futureTime = $inSeconds;
            $pastTime = $now;
        }
        $diff = $futureTime - $pastTime;

        if (!$diff) {
            return __d('cake', 'just now', 'just now');
        }

        if ($diff > abs($now - (new static($end))->format('U'))) {
            return sprintf($absoluteString, $time->i18nFormat($format));
        }

        // If more than a week, then take into account the length of months
        if ($diff >= 604800) {
            list($future['H'], $future['i'], $future['s'], $future['d'], $future['m'], $future['Y']) = explode('/', date('H/i/s/d/m/Y', $futureTime));

            list($past['H'], $past['i'], $past['s'], $past['d'], $past['m'], $past['Y']) = explode('/', date('H/i/s/d/m/Y', $pastTime));
            $weeks = $days = $hours = $minutes = $seconds = 0;

            $years = $future['Y'] - $past['Y'];
            $months = $future['m'] + ((12 * $years) - $past['m']);

            if ($months >= 12) {
                $years = floor($months / 12);
                $months = $months - ($years * 12);
            }
            if ($future['m'] < $past['m'] && $future['Y'] - $past['Y'] === 1) {
                $years--;
            }

            if ($future['d'] >= $past['d']) {
                $days = $future['d'] - $past['d'];
            } else {
                $daysInPastMonth = date('t', $pastTime);
                $daysInFutureMonth = date('t', mktime(0, 0, 0, $future['m'] - 1, 1, $future['Y']));

                if (!$backwards) {
                    $days = ($daysInPastMonth - $past['d']) + $future['d'];
                } else {
                    $days = ($daysInFutureMonth - $past['d']) + $future['d'];
                }

                if ($future['m'] != $past['m']) {
                    $months--;
                }
            }

            if (!$months && $years >= 1 && $diff < ($years * 31536000)) {
                $months = 11;
                $years--;
            }

            if ($months >= 12) {
                $years = $years + 1;
                $months = $months - 12;
            }

            if ($days >= 7) {
                $weeks = floor($days / 7);
                $days = $days - ($weeks * 7);
            }
        } else {
            $years = $months = $weeks = 0;
            $days = floor($diff / 86400);

            $diff = $diff - ($days * 86400);

            $hours = floor($diff / 3600);
            $diff = $diff - ($hours * 3600);

            $minutes = floor($diff / 60);
            $diff = $diff - ($minutes * 60);
            $seconds = $diff;
        }

        $fWord = $accuracy['second'];
        if ($years > 0) {
            $fWord = $accuracy['year'];
        } elseif (abs($months) > 0) {
            $fWord = $accuracy['month'];
        } elseif (abs($weeks) > 0) {
            $fWord = $accuracy['week'];
        } elseif (abs($days) > 0) {
            $fWord = $accuracy['day'];
        } elseif (abs($hours) > 0) {
            $fWord = $accuracy['hour'];
        } elseif (abs($minutes) > 0) {
            $fWord = $accuracy['minute'];
        }

        $fNum = str_replace(['year', 'month', 'week', 'day', 'hour', 'minute', 'second'], [1, 2, 3, 4, 5, 6, 7], $fWord);

        $relativeDate = '';
        if ($fNum >= 1 && $years > 0) {
            $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '{0} year', '{0} years', $years, $years);
        }
        if ($fNum >= 2 && $months > 0) {
            $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '{0} month', '{0} months', $months, $months);
        }
        if ($fNum >= 3 && $weeks > 0) {
            $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '{0} week', '{0} weeks', $weeks, $weeks);
        }
        if ($fNum >= 4 && $days > 0) {
            $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '{0} day', '{0} days', $days, $days);
        }
        if ($fNum >= 5 && $hours > 0) {
            $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '{0} hour', '{0} hours', $hours, $hours);
        }
        if ($fNum >= 6 && $minutes > 0) {
            $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '{0} minute', '{0} minutes', $minutes, $minutes);
        }
        if ($fNum >= 7 && $seconds > 0) {
            $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '{0} second', '{0} seconds', $seconds, $seconds);
        }

        // When time has passed
        if (!$backwards && $relativeDate) {
            return sprintf($relativeString, $relativeDate);
        }
        if (!$backwards) {
            $aboutAgo = [
                'second' => __d('cake', 'about a second ago'),
                'minute' => __d('cake', 'about a minute ago'),
                'hour' => __d('cake', 'about an hour ago'),
                'day' => __d('cake', 'about a day ago'),
                'week' => __d('cake', 'about a week ago'),
                'year' => __d('cake', 'about a year ago')
            ];

            return $aboutAgo[$fWord];
        }

        // When time is to come
        if (!$relativeDate) {
            $aboutIn = [
                'second' => __d('cake', 'in about a second'),
                'minute' => __d('cake', 'in about a minute'),
                'hour' => __d('cake', 'in about an hour'),
                'day' => __d('cake', 'in about a day'),
                'week' => __d('cake', 'in about a week'),
                'year' => __d('cake', 'in about a year')
            ];

            return $aboutIn[$fWord];
        }

        return $relativeDate;
    }

    /**
     * Returns the difference between this date and the provided one in a human
     * readable format.
     *
     * See `Time::timeAgoInWords()` for a full list of options that can be passed
     * to this method.
     *
     * @param \Carbon\Carbon|null $other the date to diff with
     * @param array $options options accepted by timeAgoInWords
     * @return string
     * @see Time::timeAgoInWords()
     */
    public function diffForHumans(Carbon $other = null, array $options = [])
    {
        $options = ['from' => $other] + $options;
        return $this->timeAgoInWords($options);
    }

    /**
     * Returns true this instance happened within the specified interval
     *
     * @param string|int $timeInterval the numeric value with space then time type.
     *    Example of valid types: 6 hours, 2 days, 1 minute.
     * @return bool
     */
    public function wasWithinLast($timeInterval)
    {
        $tmp = str_replace(' ', '', $timeInterval);
        if (is_numeric($tmp)) {
            $timeInterval = $tmp . ' days';
        }

        $interval = new static('-' . $timeInterval);
        $now = new static();

        return $this >= $interval && $this <= $now;
    }

    /**
     * Returns true this instance will happen within the specified interval
     *
     * @param string|int $timeInterval the numeric value with space then time type.
     *    Example of valid types: 6 hours, 2 days, 1 minute.
     * @return bool
     */
    public function isWithinNext($timeInterval)
    {
        $tmp = str_replace(' ', '', $timeInterval);
        if (is_numeric($tmp)) {
            $timeInterval = $tmp . ' days';
        }

        $interval = new static('+' . $timeInterval);
        $now = new static();

        return $this <= $interval && $this >= $now;
    }

    /**
     * Returns a formatted string for this time object using the preferred format and
     * language for the specified locale.
     *
     * It is possible to specify the desired format for the string to be displayed.
     * You can either pass `IntlDateFormatter` constants as the first argument of this
     * function, or pass a full ICU date formatting string as specified in the following
     * resource: http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details.
     *
     * ### Examples
     *
     * ```
     * $time = new Time('2014-04-20 22:10');
     * $time->i18nFormat(); // outputs '4/20/14, 10:10 PM' for the en-US locale
     * $time->i18nFormat(\IntlDateFormatter::FULL); // Use the full date and time format
     * $time->i18nFormat([\IntlDateFormatter::FULL, \IntlDateFormatter::SHORT]); // Use full date but short time format
     * $time->i18nFormat('yyyy-MM-dd HH:mm:ss'); // outputs '2014-04-20 22:10'
     * ```
     *
     * If you wish to control the default format to be used for this method, you can alter
     * the value of the static `Time::$defaultLocale` variable and set it to one of the
     * possible formats accepted by this function.
     *
     * You can read about the available IntlDateFormatter constants at
     * http://www.php.net/manual/en/class.intldateformatter.php
     *
     * If you need to display the date in a different timezone than the one being used for
     * this Time object without altering its internal state, you can pass a timezone
     * string or object as the second parameter.
     *
     * Finally, should you need to use a different locale for displaying this time object,
     * pass a locale string as the third parameter to this function.
     *
     * ### Examples
     *
     * ```
     * $time = new Time('2014-04-20 22:10');
     * $time->i18nFormat(null, null, 'de-DE');
     * $time->i18nFormat(\IntlDateFormatter::FULL, 'Europe/Berlin', 'de-DE');
     * ```
     *
     * You can control the default locale to be used by setting the static variable
     * `Time::$defaultLocale` to a  valid locale string. If empty, the default will be
     * taken from the `intl.default_locale` ini config.
     *
     * @param string|int|null $format Format string.
     * @param string|\DateTimeZone|null $timezone Timezone string or DateTimeZone object
     * in which the date will be displayed. The timezone stored for this object will not
     * be changed.
     * @param string|null $locale The locale name in which the date should be displayed (e.g. pt-BR)
     * @return string Formatted and translated date string
     */
    public function i18nFormat($format = null, $timezone = null, $locale = null)
    {
        $time = $this;

        if ($timezone) {
            $time = clone $this;
            $time->timezone($timezone);
        }

        $format = $format !== null ? $format : static::$_toStringFormat;
        $locale = $locale ?: static::$defaultLocale;
        return $this->_formatObject($time, $format, $locale);
    }

    /**
     * Returns a translated and localized date string.
     * Implements what IntlDateFormatter::formatObject() is in PHP 5.5+
     *
     * @param \DateTime $date Date.
     * @param string|int|array $format Format.
     * @param string $locale The locale name in which the date should be displayed.
     * @return string
     */
    protected function _formatObject($date, $format, $locale)
    {
        $pattern = $dateFormat = $timeFormat = $calendar = null;

        if (is_array($format)) {
            list($dateFormat, $timeFormat) = $format;
        } elseif (is_numeric($format)) {
            $dateFormat = $format;
        } else {
            $dateFormat = $timeFormat = IntlDateFormatter::FULL;
            $pattern = $format;
        }

        $timezone = $date->getTimezone()->getName();
        $key = "{$locale}.{$dateFormat}.{$timeFormat}.{$timezone}.{$calendar}.{$pattern}";

        if (!isset(static::$_formatters[$key])) {
            if ($timezone === '+00:00') {
                $timezone = 'UTC';
            } elseif ($timezone[0] === '+' || $timezone[0] === '-') {
                $timezone = 'GMT' . $timezone;
            }
            static::$_formatters[$key] = datefmt_create(
                $locale,
                $dateFormat,
                $timeFormat,
                $timezone,
                $calendar,
                $pattern
            );
        }

        return static::$_formatters[$key]->format($date);
    }

    /**
     * {@inheritDoc}
     */
    public function __toString()
    {
        return $this->i18nFormat();
    }

    /**
     * Get list of timezone identifiers
     *
     * @param int|string $filter A regex to filter identifier
     *   Or one of DateTimeZone class constants
     * @param string $country A two-letter ISO 3166-1 compatible country code.
     *   This option is only used when $filter is set to DateTimeZone::PER_COUNTRY
     * @param bool $group If true (default value) groups the identifiers list by primary region
     * @return array List of timezone identifiers
     * @since 2.2
     */
    public static function listTimezones($filter = null, $country = null, $group = true)
    {
        $regex = null;
        if (is_string($filter)) {
            $regex = $filter;
            $filter = null;
        }
        if ($filter === null) {
            $filter = \DateTimeZone::ALL;
        }
        $identifiers = \DateTimeZone::listIdentifiers($filter, $country);

        if ($regex) {
            foreach ($identifiers as $key => $tz) {
                if (!preg_match($regex, $tz)) {
                    unset($identifiers[$key]);
                }
            }
        }

        if ($group) {
            $groupedIdentifiers = [];
            foreach ($identifiers as $key => $tz) {
                $item = explode('/', $tz, 2);
                if (isset($item[1])) {
                    $groupedIdentifiers[$item[0]][$tz] = $item[1];
                } else {
                    $groupedIdentifiers[$item[0]] = [$tz => $item[0]];
                }
            }
            return $groupedIdentifiers;
        }
        return array_combine($identifiers, $identifiers);
    }

    /**
     * Resets the format used to the default when converting an instance of this type to
     * a string
     *
     * @return void
     */
    public static function resetToStringFormat()
    {
        static::setToStringFormat([IntlDateFormatter::SHORT, IntlDateFormatter::SHORT]);
    }

    /**
     * Sets the default format used when type converting instances of this type to string
     *
     * @param string|array|int $format Format.
     * @return void
     */
    public static function setToStringFormat($format)
    {
        static::$_toStringFormat = $format;
    }

    /**
     * Returns a new Time object after parsing the provided time string based on
     * the passed or configured date time format. This method is locale dependent,
     * Any string that is passed to this function will be interpreted as a locale
     * dependent string.
     *
     * When no $format is provided, the `toString` format will be used.
     *
     * If it was impossible to parse the provided time, null will be returned.
     *
     * Example:
     *
     * ```
     *  $time = Time::parseDateTime('10/13/2013 12:54am');
     *  $time = Time::parseDateTime('13 Oct, 2013 13:54', 'dd MMM, y H:mm');
     *  $time = Time::parseDateTime('10/10/2015', [IntlDateFormatter::SHORT, -1]);
     * ```
     *
     * @param string $time The time string to parse.
     * @param string|array $format Any format accepted by IntlDateFormatter.
     * @return static|null
     */
    public static function parseDateTime($time, $format = null)
    {
        $dateFormat = $format ?: static::$_toStringFormat;
        $timeFormat = $pattern = null;

        if (is_array($dateFormat)) {
            list($newDateFormat, $timeFormat) = $dateFormat;
            $dateFormat = $newDateFormat;
        } else {
            $pattern = $dateFormat;
            $dateFormat = null;
        }

        $formatter = datefmt_create(
            static::$defaultLocale,
            $dateFormat,
            $timeFormat,
            date_default_timezone_get(),
            null,
            $pattern
        );
        $time = $formatter->parse($time);
        if ($time) {
            $result = new static('@' . $time);
            $result->setTimezone(date_default_timezone_get());
            return $result;
        }
        return null;
    }

    /**
     * Returns a new Time object after parsing the provided $date string based on
     * the passed or configured date time format. This method is locale dependent,
     * Any string that is passed to this function will be interpreted as a locale
     * dependent string.
     *
     * When no $format is provided, the `wordFormat` format will be used.
     *
     * If it was impossible to parse the provided time, null will be returned.
     *
     * Example:
     *
     * ```
     *  $time = Time::parseDate('10/13/2013');
     *  $time = Time::parseDate('13 Oct, 2013', 'dd MMM, y');
     *  $time = Time::parseDate('13 Oct, 2013', IntlDateFormatter::SHORT);
     * ```
     *
     * @param string $date The date string to parse.
     * @param string|int $format Any format accepted by IntlDateFormatter.
     * @return static|null
     */
    public static function parseDate($date, $format = null)
    {
        if (is_int($format)) {
            $format = [$format, -1];
        }
        $format = $format ?: static::$wordFormat;
        return static::parseDateTime($date, $format);
    }

    /**
     * Returns a new Time object after parsing the provided $time string based on
     * the passed or configured date time format. This method is locale dependent,
     * Any string that is passed to this function will be interpreted as a locale
     * dependent string.
     *
     * When no $format is provided, the IntlDateFormatter::SHORT format will be used.
     *
     * If it was impossible to parse the provided time, null will be returned.
     *
     * Example:
     *
     * ```
     *  $time = Time::parseDate('11:23pm');
     * ```
     *
     * @param string $time The time string to parse.
     * @param string|int $format Any format accepted by IntlDateFormatter.
     * @return static|null
     */
    public static function parseTime($time, $format = null)
    {
        if (is_int($format)) {
            $format = [-1, $format];
        }
        $format = $format ?: [-1, IntlDateFormatter::SHORT];
        return static::parseDateTime($time, $format);
    }

    /**
     * Returns a string that should be serialized when converting this object to json
     *
     * @return string
     */
    public function jsonSerialize()
    {
        return $this->format(static::ISO8601);
    }

    /**
     * Returns the data that should be displayed when debugging this object
     *
     * @return array
     */
    public function __debugInfo()
    {
        return [
            'time' => $this->format(static::ISO8601),
            'timezone' => $this->getTimezone()->getName(),
            'fixedNowTime' => $this->hasTestNow() ? $this->getTestNow()->format(static::ISO8601) : false
        ];
    }
}


text:
package org.chromium.components.crash.browser;

import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.base.annotations.UsedByReflection;
import org.chromium.build.NativeLibraries;

@JNINamespace("crashpad")
final class CrashpadMain {
    @UsedByReflection("crashpad_linux.cc")
    public static void main(String[] argv) {
        try {
            for (String library : NativeLibraries.LIBRARIES) {
                System.loadLibrary(library);
            }
        } catch (UnsatisfiedLinkError e) {
            throw new RuntimeException(e);
        }
        CrashpadMainJni.get().crashpadMain(argv);
    }

    @NativeMethods
    interface Natives {
        void crashpadMain(String[] argv);
    }
}


text:
<?php

namespace MajorApi\AppBundle\Library\Service\Exception\Quickbooks;

use MajorApi\AppBundle\Library\Service\Exception\Exception;

class InvoiceInvalidCreationException extends Exception
{

    public static function create()
    {
        return new self("The QuickBooks Invoice can not be created because it is invalid.");
    }

}


text:
// Autogenerated from vk-api-schema. Please don't edit it manually.
package com.vk.api.sdk.queries.groups;

import com.vk.api.sdk.client.AbstractQueryBuilder;
import com.vk.api.sdk.client.VkApiClient;
import com.vk.api.sdk.client.actors.UserActor;
import com.vk.api.sdk.objects.base.responses.BoolResponse;
import com.vk.api.sdk.objects.groups.TagAddTagColor;
import java.util.Arrays;
import java.util.List;

/**
 * Query for Groups.tagAdd method
 */
public class GroupsTagAddQuery extends AbstractQueryBuilder<GroupsTagAddQuery, BoolResponse> {
    /**
     * Creates a AbstractQueryBuilder instance that can be used to build api request with various parameters
     *
     * @param client VK API client
     * @param actor actor with access token
     * @param groupId value of "group id" parameter. Minimum is 1.
     * @param tagName value of "tag name" parameter.
     */
    public GroupsTagAddQuery(VkApiClient client, UserActor actor, int groupId, String tagName) {
        super(client, "groups.tagAdd", BoolResponse.class);
        accessToken(actor.getAccessToken());
        groupId(groupId);
        tagName(tagName);
    }

    /**
     * Set group id
     *
     * @param value value of "group id" parameter. Minimum is 1.
     * @return a reference to this {@code AbstractQueryBuilder} object to fulfill the "Builder" pattern.
     */
    protected GroupsTagAddQuery groupId(int value) {
        return unsafeParam("group_id", value);
    }

    /**
     * Set tag name
     *
     * @param value value of "tag name" parameter.
     * @return a reference to this {@code AbstractQueryBuilder} object to fulfill the "Builder" pattern.
     */
    protected GroupsTagAddQuery tagName(String value) {
        return unsafeParam("tag_name", value);
    }

    /**
     * Set tag color
     *
     * @param value value of "tag color" parameter.
     * @return a reference to this {@code AbstractQueryBuilder} object to fulfill the "Builder" pattern.
     */
    public GroupsTagAddQuery tagColor(TagAddTagColor value) {
        return unsafeParam("tag_color", value);
    }

    @Override
    protected GroupsTagAddQuery getThis() {
        return this;
    }

    @Override
    protected List<String> essentialKeys() {
        return Arrays.asList("group_id", "access_token", "tag_name");
    }
}