text:
<!doctype html>

  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>

<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />

  <link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />

    <link href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">

<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.1.0" rel="stylesheet" type="text/css" />

  <meta name="keywords" content="Hexo, NexT" />

  <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico?v=5.1.0" />

<meta name="description" content="Synchronized关键字
synchronized提供的是排它的、不公平的、可重入的锁,这是JAVA对象内含的锁对象.

Keep in mind that using synchronized on methods is really just shorthand (assume class is SomeClass)
 1synchronized static void foo() &#">
<meta property="og:type" content="article">
<meta property="og:title" content="Synchronized关键字">
<meta property="og:url" content="http://yoursite.com/2017/01/24/多线程/Synchronized关键字/index.html">
<meta property="og:site_name" content="Essviv">
<meta property="og:description" content="Synchronized关键字
synchronized提供的是排它的、不公平的、可重入的锁,这是JAVA对象内含的锁对象.

Keep in mind that using synchronized on methods is really just shorthand (assume class is SomeClass)
 1synchronized static void foo() &#">
<meta property="og:updated_time" content="2017-03-08T08:38:11.000Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Synchronized关键字">
<meta name="twitter:description" content="Synchronized关键字
synchronized提供的是排它的、不公平的、可重入的锁,这是JAVA对象内含的锁对象.

Keep in mind that using synchronized on methods is really just shorthand (assume class is SomeClass)
 1synchronized static void foo() &#">

  <link rel="canonical" href="http://yoursite.com/2017/01/24/多线程/Synchronized关键字/"/>

  <title> Synchronized关键字 | Essviv </title>

        Essviv

Dare to be different

    <button>

    </button>

            首页

            归档

    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2017/01/24/多线程/Synchronized关键字/">

      <meta itemprop="name" content="Essviv">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="https://github.com/Essviv/images/blob/master/avatar.jpg?raw=true">

      <meta itemprop="name" content="Essviv">

                Synchronized关键字

                发表于

              <time title="创建于" itemprop="dateCreated datePublished" datetime="2017-01-24T10:20:54+08:00">
                2017-01-24
              </time>

                |

Synchronized关键字

synchronized提供的是排它的、不公平的、可重入的锁,这是JAVA对象内含的锁对象.

Keep in mind that using synchronized on methods is really just shorthand (assume class is SomeClass)

1

synchronized static void foo() {    ...}

is the same as

1

static void foo() {    synchronized(SomeClass.class) {        ...    }}

and

1

synchronized void foo() {    ...}

is the same as

1

void foo() {    synchronized(this) {        ...    }}

happens-before

happends-before关系是一种保证关系,它保证一个语句的执行结果对另一个语句可见,其本质是一种可见性保证。以下几种情况均存在这种关系:

在同一个线程中执行的语句,自动拥有happends-before的关系

对锁的unlock操作和随后对同一个锁的lock操作有happens-before关系,由于这种关系有传递性,因此在unlock之前的所有操作对lock之后所有的操作可见

对volatile变量的写操作和随后对它的读操作有happens-before关系

线程的start操作和线程中执行的所有操作有happens-before关系

被调用了join操作的线程, 它执行的所有操作对调用该(join)操作的线程有happens-before关系

参考文献

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/package-summary.html#MemoryVisibility

http://blog.sina.com.cn/s/blog_4ae8f77f0101iifx.html

您的支持将鼓励我继续创作!

    <button id="rewardButton" disable="enable" onclick="var qr = document.getElementById('QR'); if (qr.style.display === 'none') {qr.style.display='block';} else {qr.style.display='none'}">
      赏
    </button>

微信打赏

支付宝打赏

                 阻塞锁与自旋锁

                java集合学习之Queue的实现5

            文章目录

            站点概览

Essviv

                145
                日志

                27
                标签

                  GitHub

Synchronized关键字

happens-before

参考文献

  ©
  2017

  Essviv

  由 Hexo 强力驱动

  主题 -

    NexT.Mist


text:
using System;
using System.Data.Common;

namespace XDatabase.Core
{
    public abstract partial class XQuery
    {
        public int Update(string pSqlQuery, params XParameter[] args)
        {
            ClearError();
            try
            {
                if (!IsConnectionActive)
                {
                    OpenConnection();
                }
                using (var command = GetCommand())
                {
                    command.Connection = Connection;
                    command.CommandText = pSqlQuery;
                    command.CommandTimeout = Timeout;

                    if (args != null)
                    {
                        foreach (var arg in args)
                        {
                            var parameter = GetParameter(arg.ParameterName, arg.Value);
                            command.Parameters.Add(parameter);
                        }
                    }
                    return command.ExecuteNonQuery();
                }
            }
            catch (Exception ex)
            {
                RegisterError(ex.Message);
                return -1;
            }
            finally
            {
                CloseConnection();
            }
        }

        public int Delete(string pSqlQuery, params XParameter[] args)
        {
            return Update(pSqlQuery, args);
        }

        public int Insert(string pSqlQuery, params XParameter[] args)
        {
            return Update(pSqlQuery, args);
        }

        public int Create(string pSqlQuery, params XParameter[] args)
        {
            return Update(pSqlQuery, args);
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
#include <jni.h>

#include "tensorflow/lite/delegates/flex/delegate.h"
#include "tensorflow/lite/delegates/utils/simple_delegate.h"
#include "tensorflow/lite/testing/init_tensorflow.h"

extern "C" {

JNIEXPORT void JNICALL
Java_org_tensorflow_lite_flex_FlexDelegate_nativeInitTensorFlow(JNIEnv* env,
                                                                jclass clazz) {
  ::tflite::InitTensorFlow();
}

JNIEXPORT jlong JNICALL
Java_org_tensorflow_lite_flex_FlexDelegate_nativeCreateDelegate(JNIEnv* env,
                                                                jclass clazz) {
  return reinterpret_cast<jlong>(tflite::FlexDelegate::Create().release());
}

JNIEXPORT void JNICALL
Java_org_tensorflow_lite_flex_FlexDelegate_nativeDeleteDelegate(
    JNIEnv* env, jclass clazz, jlong delegate) {
  tflite::TfLiteDelegateFactory::DeleteSimpleDelegate(
      reinterpret_cast<struct TfLiteDelegate*>(delegate));
}

}  // extern "C"


text:
#ifndef QUICKSTEP_QUERY_OPTIMIZER_EXPRESSIONS_PREDICATE_HPP_
#define QUICKSTEP_QUERY_OPTIMIZER_EXPRESSIONS_PREDICATE_HPP_

#include <memory>
#include <unordered_map>
#include <unordered_set>

#include "query_optimizer/expressions/ExprId.hpp"
#include "query_optimizer/expressions/Expression.hpp"
#include "types/Type.hpp"
#include "types/TypeFactory.hpp"
#include "utility/Macros.hpp"

namespace quickstep {

class CatalogAttribute;
class Predicate;

namespace optimizer {
namespace expressions {

/** \addtogroup OptimizerExpressions
 *  @{
 */

class Predicate;
typedef std::shared_ptr<const Predicate> PredicatePtr;

/**
 * @brief Expression that returns boolean values.
 */
class Predicate : public Expression {
 public:
  /**
   * @brief Destructor.
   */
  ~Predicate() override {}

  const Type& getValueType() const override {
    // The type system does not have a bool type, so we use non-nullable kInt
    // instead.
    return TypeFactory::GetType(kInt /* TypeID */,
                                false /* nullable */);
  }

  /**
   * @brief Returns a concretized predicate in the Quickstep execution
   *        expression system with AttributeReferences replaced by
   *        CatalogAttribute references provided in \p substitution_map.
   * @note In the Quickstep execution expression system, Predicate is not Scalar
           *type. We do not use concretize() for predicate concretization.
   *
   * @param substitution_map Map from ExprId to CatalogAttribute for use in
   *                         replacing AttributeReference.
   * @param left_expr_ids The ExprIds from the left hand side.
   * @param right_expr_ids The ExprIds from the right hand side.
   * @return A concretized predicate for evaluation.
   */
  virtual ::quickstep::Predicate* concretize(
      const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map,
      const std::unordered_set<ExprId> &left_expr_ids = std::unordered_set<ExprId>(),
      const std::unordered_set<ExprId> &right_expr_ids = std::unordered_set<ExprId>()) const = 0;

 protected:
  Predicate() {}

 private:
  DISALLOW_COPY_AND_ASSIGN(Predicate);
};

/** @} */

}  // namespace expressions
}  // namespace optimizer
}  // namespace quickstep

#endif /* QUICKSTEP_QUERY_OPTIMIZER_EXPRESSIONS_PREDICATE_HPP_ */


text:
/**
 * @fileoverview Report when a DOM element is using both children and dangerouslySetInnerHTML
 * @author David Petersen
 */
'use strict';

var find = require('array.prototype.find');
var variableUtil = require('../util/variable');

// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------
module.exports = {
  meta: {
    docs: {
      description: 'Report when a DOM element is using both children and dangerouslySetInnerHTML',
      category: '',
      recommended: false
    },
    schema: [] // no options
  },
  create: function(context) {
    function findSpreadVariable(name) {
      return find(variableUtil.variablesInScope(context), function (item) {
        return item.name === name;
      });
    }
    /**
     * Takes a ObjectExpression and returns the value of the prop if it has it
     * @param {object} node - ObjectExpression node
     * @param {string} propName - name of the prop to look for
     */
    function findObjectProp(node, propName) {
      if (!node.properties) {
        return false;
      }
      return find(node.properties, function(prop) {
        if (prop.type === 'Property') {
          return prop.key.name === propName;
        } else if (prop.type === 'ExperimentalSpreadProperty') {
          var variable = findSpreadVariable(prop.argument.name);
          if (variable && variable.defs[0].node.init) {
            return findObjectProp(variable.defs[0].node.init, propName);
          }
        }
        return false;
      });
    }

    /**
     * Takes a JSXElement and returns the value of the prop if it has it
     * @param {object} node - JSXElement node
     * @param {string} propName - name of the prop to look for
     */
    function findJsxProp(node, propName) {
      var attributes = node.openingElement.attributes;
      return find(attributes, function (attribute) {
        if (attribute.type === 'JSXSpreadAttribute') {
          var variable = findSpreadVariable(attribute.argument.name);
          if (variable && variable.defs.length && variable.defs[0].node.init) {
            return findObjectProp(variable.defs[0].node.init, propName);
          }
        }
        return attribute.name && attribute.name.name === propName;
      });
    }

    return {
      JSXElement: function (node) {
        var hasChildren = false;

        if (node.children.length) {
          hasChildren = true;
        } else if (findJsxProp(node, 'children')) {
          hasChildren = true;
        }

        if (
          node.openingElement.attributes
          && hasChildren
          && findJsxProp(node, 'dangerouslySetInnerHTML')
        ) {
          context.report(node, 'Only set one of `children` or `props.dangerouslySetInnerHTML`');
        }
      },
      CallExpression: function (node) {
        if (
          node.callee
          && node.callee.type === 'MemberExpression'
          && node.callee.property.name === 'createElement'
          && node.arguments.length > 1
        ) {
          var hasChildren = false;

          var props = node.arguments[1];

          if (props.type === 'Identifier') {
            var variable = find(variableUtil.variablesInScope(context), function (item) {
              return item.name === props.name;
            });
            if (variable && variable.defs[0].node.init) {
              props = variable.defs[0].node.init;
            }
          }

          var dangerously = findObjectProp(props, 'dangerouslySetInnerHTML');

          if (node.arguments.length === 2) {
            if (findObjectProp(props, 'children')) {
              hasChildren = true;
            }
          } else {
            hasChildren = true;
          }

          if (dangerously && hasChildren) {
            context.report(node, 'Only set one of `children` or `props.dangerouslySetInnerHTML`');
          }
        }
      }
    };
  }
};


text:
<?php
/**
 * Vainyl
 *
 * PHP Version 7
 *
 * @package   Http
 * @license   https://opensource.org/licenses/MIT MIT License
 * @link      https://vainyl.com
 */
declare(strict_types=1);

namespace Vainyl\Http\Factory;

use Vainyl\Core\IdentifiableInterface;
use Vainyl\Http\HeaderInterface;

/**
 * Interface HeaderFactoryInterface
 *
 * @author Taras P. Girnyk <taras.p.gyrnik@gmail.com>
 */
interface HeaderFactoryInterface extends IdentifiableInterface
{
    /**
     * @param string $name
     * @param mixed  $values
     *
     * @return HeaderInterface
     */
    public function createHeader(string $name, $values): HeaderInterface;
}


text:
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import {
  IPropertyPaneConfiguration,
  PropertyPaneTextField
} from '@microsoft/sp-property-pane';

import * as strings from 'GraphReportsWebPartStrings';
import GraphReports from './components/GraphReports';
import { IGraphReportsProps } from './components/IGraphReportsProps';

export interface IGraphReportsWebPartProps {
  description: string;
}

export default class GraphReportsWebPart extends BaseClientSideWebPart<IGraphReportsWebPartProps> {

  public render(): void {
    const element: React.ReactElement<IGraphReportsProps > = React.createElement(
      GraphReports,
      {
        customServiceScope: this.context.serviceScope
      }
    );

    ReactDom.render(element, this.domElement);
  }

  protected onDispose(): void {
    ReactDom.unmountComponentAtNode(this.domElement);
  }

  protected get dataVersion(): Version {
    return Version.parse('1.0');
  }

  protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
    return {
      pages: [
        {
          header: {
            description: strings.PropertyPaneDescription
          },
          groups: [
            {
              groupName: strings.BasicGroupName,
              groupFields: [
                PropertyPaneTextField('description', {
                  label: strings.DescriptionFieldLabel
                })
              ]
            }
          ]
        }
      ]
    };
  }
}


text:
from flask import Flask, render_template, request
import logging
import call
import queue
import cdr
import time
from contextlib import contextmanager
import argparse

INCOMING_NAME = "incoming"
INCOMING_NUM_THREAD = 30
OUTGOING_NAME = "outgoing"
OUTGOING_NUM_THREAD = 300
CDR_NAME = "cdr"
CDR_NUM_THREAD = 5

TIME_MULTIPLIER = 1.0

now = lambda: int(round(time.time() * 1000))

app = Flask(__name__)

@contextmanager
def timed(action, count=0, object="", objects=""):
    start = now()
    yield
    duration = now() - start
    message = action
    if object and count:
        objs = objects if objects else object + 's'
        if count == 1:
            obj = object
        else:
            obj = objs
        speed = "at "
        if duration == 0:
            speed += "a gazillion {}/sec".format(objs)
        else:
            speed += "{} {}/sec".format(1000 * count / duration, obj)
        message += " {} {} in {}ms {}".format(count, obj, duration, speed)
    else:
        message += " in {}ms".format(duration)

    logging.info(message)

@app.route('/')
def home():
    stats = {
        'cdrs': cdr_machine.stats(),
        'cdr queue': cdr_queue_machine.stats(),
        'incoming queue': incoming_queue_machine.stats(),
        'outgoing queue': outgoing_queue_machine.stats(),
        'incoming calls': incoming_call_machine.stats(),
        'outgoing calls': outgoing_call_machine.stats(),
    }
    return render_template('index.html', stats=stats)

def enqueue_inbound(count):
    with timed('enqueued', count, 'incoming message'):
        for i in range(count):
            #todo randomize
            phone_number = "12065551212"
            incoming_queue_machine.put({'from': phone_number})

    return "{}".format(count)

def is_int(s):
    try:
        int(s)
        return True
    except ValueError:
        return False

@app.route('/out')
def mock_outbound():
    errors = []
    if 'to' not in request.args:
        errors.append("missing 'to' argument")
    if len(errors) > 0:
        return render_template('400.html', errors=errors), 400

    payload = {
        'to': request.args['to'],
    }
    outgoing_queue_machine.put(payload)

    if args.verbose:
        return str(payload)
    else:
        return "OK"

def incoming_queue_worker(q):
    while True:
        payload = q.get()
        logging.debug("Getting payload {} from '{}' queue".format(payload, INCOMING_NAME))
        incoming_call_machine.call(payload)
        q.task_done()

def outgoing_queue_worker(q):
    while True:
        payload = q.get()
        logging.debug("Getting payload {} from '{}' queue".format(payload, OUTGOING_NAME))
        outgoing_call_machine.call(payload)
        q.task_done()

def cdr_queue_worker(q):
    while True:
        payload = q.get()
        logging.debug("Getting payload {} from '{}' queue".format(payload, CDR_NAME))
        cdr_machine.send(payload)
        q.task_done()

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("-s", "--server", help="url of the Motech server",
                        default="http://localhost:8080/motech-platform-server")
    parser.add_argument("-i", "--influx", help="url of the influx database server")
    parser.add_argument("-c", "--config", help="name of the ivr config", default="config")
    parser.add_argument("-t", "--template", help="name of the vxml template", default="template")
    parser.add_argument("-n", "--num", help="number of inbound phone calls to mock (must use with -u)", type=int)
    # TODO add more arguments to vary the type of mock inbound call
    parser.add_argument("-v", "--verbose", help="increase output verbosity", action="store_true")
    args = parser.parse_args()

    #debug
    #print "args={}".format(args)

    template_url = "{}/module/ivr/template/{}/{}".format(args.server, args.config, args.template)
    cdr_url = "{}/module/ivr/status/{}".format(args.server, args.config)
    if args.verbose:
        print "VXML template URL: {}".format(template_url)
        print "CDR template URL: {}".format(cdr_url)

    logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO)
    logging.getLogger('werkzeug').setLevel(logging.WARNING)
    logging.getLogger('requests.packages.urllib3.connectionpool').setLevel(logging.WARNING)

    cdr_machine = cdr.CDRMachine()
    cdr_queue_machine = queue.QueueMachine(CDR_NAME, CDR_NUM_THREAD, cdr_queue_worker, args.influx)

    incoming_call_types = [call.SUCCESS, call.NO_ANSWER, call.PHONE_OFF, call.NOT_DELIVERED]
    incoming_queue_machine = queue.QueueMachine(INCOMING_NAME, INCOMING_NUM_THREAD, incoming_queue_worker, args.influx)
    incoming_call_machine = call.CallMachine(INCOMING_NAME, cdr_url, template_url, TIME_MULTIPLIER, incoming_call_types,
                                             cdr_queue_machine)

    outgoing_call_types = [call.SUCCESS, call.NO_ANSWER, call.PHONE_OFF, call.NOT_DELIVERED]
    outgoing_queue_machine = queue.QueueMachine(OUTGOING_NAME, OUTGOING_NUM_THREAD, outgoing_queue_worker, args.influx)
    outgoing_call_machine = call.CallMachine(OUTGOING_NAME, cdr_url, template_url, TIME_MULTIPLIER, outgoing_call_types,
                                             cdr_queue_machine)

    if args.num:
        enqueue_inbound(args.num)

    app.run(host='0.0.0.0')


text:
<?php
Class ShopProduct {
    public $title = "default production";
    public $producerMainName = "main name";
    public $producerFirstName = "first name";
    public $price;

    function __construct() {
        echo "���췽��"."<br/>";
    }

    function getProducer() {
        return "{$this->producerMainName}".
            " {$this->producerFirstName}";
    }
}

$producer1 = new ShopProduct();
$producer1->producerMainName = "allsmy";
$producer1->producerFirstName = "liu";

echo $producer1->getProducer();


text:
import java.util.*;

//http://codeforces.com/contest/230/A
public class Game {

    public static void main(String[] args){
        Scanner s = new Scanner(System.in);

        Player kito = new Player();
        kito.strength = s.nextInt();

        int dragons_count = s.nextInt();
        Dragon[] dragons = new Dragon[dragons_count];

        for (int i = 0; i < dragons_count; i++) {
            Dragon dragon = new Dragon();
            dragon.strength = s.nextInt();
            dragon.bonus = s.nextInt();
            dragons[i] = dragon;
        }

        Arrays.sort(dragons);

        for (int i = 0; i < dragons_count; i++) {
            if (kito.strength > dragons[i].strength) {
                kito.strength += dragons[i].bonus;
            }
            else {
                System.out.println("NO");
                System.exit(0);
            }
        }

        System.out.println("YES");
    }

    private static class Player {
        public Integer strength;
    }

    private static class Dragon implements Comparable<Dragon>{

        public Integer strength;
        public Integer bonus;

        @Override
        public int compareTo(Dragon dragon) {
            return strength.compareTo(dragon.strength);
        }
    }
}


text:
// <copyright file="NullReporter.cs" company="Nic Jansma">
// Copyright (c) 2014 Nic Jansma All Right Reserved
// </copyright>
// <author>Nic Jansma</author>
namespace ChecksumVerifier
{
    using System.Collections.Generic;
    using System.Collections.ObjectModel;

    /// <summary>
    /// A null output Engine reporter
    /// </summary>
    public class NullReporter : IEngineReporter
    {
        /// <inheritdoc />
        public void LoadingDatabaseFromFile()
        {
        }

        /// <inheritdoc />
        public void LoadingDatabaseFromFileCompleted(int fileCount)
        {
        }

        /// <inheritdoc />
        public void UpdatingChecksums(int fileCount)
        {
        }

        /// <inheritdoc />
        public void UpdatingChecksumsCompleted(bool hadChanges)
        {
        }

        /// <inheritdoc />
        public void AddingFile(string fileName)
        {
        }

        /// <inheritdoc />
        public void AddingFileCompleted(string fileName, string checksum)
        {
        }

        /// <inheritdoc />
        public void RemovedFile(string fileName)
        {
        }

        /// <inheritdoc />
        public void WritingDatabase(string xmlFileName)
        {
        }

        /// <inheritdoc />
        public void WritingDatabaseCompleted()
        {
        }

        /// <inheritdoc />
        public void VerifyingChecksums(int fileCount)
        {
        }

        /// <inheritdoc />
        public void VerifyingFile(int current, int max, string fileName)
        {
        }

        /// <inheritdoc />
        public void VerifyingChecksumsCompleted(ReadOnlyCollection<BadFile> badFiles)
        {
        }

        /// <inheritdoc />
        public void UpdatedFile(string filePath)
        {
        }
    }
}


text:
function Test-DbaDiskAllocation {
    <#
    .SYNOPSIS
        Checks all disks on a computer to see if they are formatted with allocation units of 64KB.

    .DESCRIPTION
        Checks all disks on a computer for disk allocation units that match best practice recommendations. If one server is checked, only $true or $false is returned. If multiple servers are checked, each server's name and an IsBestPractice field are returned.

        References:
        https://technet.microsoft.com/en-us/library/dd758814(v=sql.100).aspx - "The performance question here is usually not one of correlation per the formula, but whether the cluster size has been explicitly defined at 64 KB, which is a best practice for SQL Server."

    .PARAMETER ComputerName
        The server(s) to check disk configuration on.

    .PARAMETER NoSqlCheck
        If this switch is enabled, the disk(s) will not be checked for SQL Server data or log files.

    .PARAMETER SqlCredential
        Login to the target instance using alternative credentials. Accepts PowerShell credentials (Get-Credential).

        Windows Authentication, SQL Server Authentication, Active Directory - Password, and Active Directory - Integrated are all supported.

        For MFA support, please use Connect-DbaInstance.

    .PARAMETER Credential
        Specifies an alternate Windows account to use when enumerating drives on the server. May require Administrator privileges. To use:

        $cred = Get-Credential, then pass $cred object to the -Credential parameter.

    .PARAMETER WhatIf
        If this switch is enabled, no actions are performed but informational messages will be displayed that explain what would happen if the command were to run.

    .PARAMETER Confirm
        If this switch is enabled, you will be prompted for confirmation before executing any operations that change state.

    .PARAMETER EnableException
        By default, when something goes wrong we try to catch it, interpret it and give you a friendly warning message.
        This avoids overwhelming you with "sea of red" exceptions, but is inconvenient because it basically disables advanced scripting.
        Using this switch turns this "nice by default" feature off and enables you to catch exceptions with your own try/catch.

    .NOTES
        Tags: CIM, Storage
        Author: Chrissy LeMaire (@cl), netnerds.net

        Website: https://dbatools.io
        Copyright: (c) 2018 by dbatools, licensed under MIT
        License: MIT https://opensource.org/licenses/MIT

    .LINK
        https://dbatools.io/Test-DbaDiskAllocation

    .EXAMPLE
        PS C:\> Test-DbaDiskAllocation -ComputerName sqlserver2014a

        Scans all disks on server sqlserver2014a for best practice allocation unit size.

    .EXAMPLE
        PS C:\> Test-DbaDiskAllocation -ComputerName sqlserver2014 | Select-Output *

        Scans all disks on server sqlserver2014a for allocation unit size and returns detailed results for each.

    .EXAMPLE
        PS C:\> Test-DbaDiskAllocation -ComputerName sqlserver2014a -NoSqlCheck

        Scans all disks not hosting SQL Server data or log files on server sqlserver2014a for best practice allocation unit size.

    #>
    [CmdletBinding(SupportsShouldProcess)]
    [OutputType("System.Collections.ArrayList", "System.Boolean")]
    param (
        [parameter(Mandatory, ValueFromPipeline)]
        [object[]]$ComputerName,
        [switch]$NoSqlCheck,
        [PSCredential]$SqlCredential,
        [PSCredential]$Credential,
        [switch]$EnableException
    )

    begin {
        $sessionoptions = New-CimSessionOption -Protocol DCOM

        function Get-AllDiskAllocation {
            $alldisks = @()
            $SqlInstances = @()

            try {
                Write-Message -Level Verbose -Message "Getting disk information from $computer."

                # $query = "Select Label, BlockSize, Name from Win32_Volume WHERE FileSystem='NTFS'"
                # $disks = Get-WmiObject -ComputerName $ipaddr -Query $query | Sort-Object -Property Name
                $disks = Get-CimInstance -CimSession $CIMsession -ClassName win32_volume -Filter "FileSystem='NTFS'" -ErrorAction Stop | Sort-Object -Property Name
            } catch {
                Stop-Function -Message "Can't connect to WMI on $computer."
                return
            }

            if ($NoSqlCheck -eq $false) {
                Write-Message -Level Verbose -Message "Checking for SQL Services"
                $sqlservices = Get-Service -ComputerName $ipaddr | Where-Object { $_.DisplayName -like 'SQL Server (*' }
                foreach ($service in $sqlservices) {
                    $instance = $service.DisplayName.Replace('SQL Server (', '')
                    $instance = $instance.TrimEnd(')')

                    $instancename = $instance.Replace("MSSQLSERVER", "Default")
                    Write-Message -Level Verbose -Message "Found instance $instancename."

                    if ($instance -eq 'MSSQLSERVER') {
                        $SqlInstances += $ipaddr
                    } else {
                        $SqlInstances += "$ipaddr\$instance"
                    }
                }
                $sqlcount = $SqlInstances.Count

                Write-Message -Level Verbose -Message "$sqlcount instance(s) found."
            }

            foreach ($disk in $disks) {
                if (!$disk.name.StartsWith("\\")) {
                    $diskname = $disk.Name

                    if ($NoSqlCheck -eq $false) {
                        $sqldisk = $false

                        foreach ($SqlInstance in $SqlInstances) {
                            try {
                                $smoserver = Connect-SqlInstance -SqlInstance $SqlInstance -SqlCredential $SqlCredential
                                $sql = "Select count(*) as Count from sys.master_files where physical_name like '$diskname%'"
                                $sqlcount = $smoserver.Databases['master'].ExecuteWithResults($sql).Tables[0].Count
                                if ($sqlcount -gt 0) {
                                    $sqldisk = $true
                                    break
                                }
                            } catch {
                                Stop-Function -Message "Error occurred while establishing connection to $instance" -Category ConnectionError -ErrorRecord $_ -Target $instance -Continue
                                continue
                            }
                        }
                    }

                    if ($disk.BlockSize -eq 65536) {
                        $IsBestPractice = $true
                    } else {
                        $IsBestPractice = $false
                    }

                    $windowsdrive = "$env:SystemDrive\"

                    if ($diskname -eq $windowsdrive) {
                        $IsBestPractice = $false
                    }

                    if ($NoSqlCheck -eq $false) {
                        $alldisks += [PSCustomObject]@{
                            Server         = $computer
                            Name           = $diskname
                            Label          = $disk.Label
                            BlockSize      = $disk.BlockSize
                            IsSqlDisk      = $sqldisk
                            IsBestPractice = $IsBestPractice
                        }
                    } else {
                        $alldisks += [PSCustomObject]@{
                            Server         = $computer
                            Name           = $diskname
                            Label          = $disk.Label
                            BlockSize      = $disk.BlockSize
                            IsBestPractice = $IsBestPractice
                        }
                    }
                }
            }
            return $alldisks
        }
    }

    process {
        # uses cim commands

        foreach ($computer in $ComputerName) {

            $computer = Resolve-DbaNetworkName -ComputerName $computer -Credential $Credential
            $ipaddr = $computer.IpAddress
            $Computer = $computer.FullComputerName

            if (!$Computer) {
                Stop-Function -Message "Couldn't resolve hostname. Skipping." -Continue
            }

            Write-Message -Level Verbose -Message "Creating CimSession on $computer over WSMan."

            if (!$Credential) {
                $cimsession = New-CimSession -ComputerName $Computer -ErrorAction SilentlyContinue
            } else {
                $cimsession = New-CimSession -ComputerName $Computer -ErrorAction SilentlyContinue -Credential $Credential
            }

            if ($null -eq $cimsession.id) {
                Write-Message -Level Verbose -Message "Creating CimSession on $computer over WSMan failed. Creating CimSession on $computer over DCOM."

                if (!$Credential) {
                    $cimsession = New-CimSession -ComputerName $Computer -SessionOption $sessionoptions -ErrorAction SilentlyContinue
                } else {
                    $cimsession = New-CimSession -ComputerName $Computer -SessionOption $sessionoptions -ErrorAction SilentlyContinue -Credential $Credential
                }
            }

            if ($null -eq $cimsession.id) {
                Stop-Function -Message "Can't create CimSession on $computer" -Target $Computer
            }

            Write-Message -Level Verbose -Message "Getting Power Plan information from $Computer"

            if ($PScmdlet.ShouldProcess("$computer", "Getting Disk Allocation")) {
                $data = Get-AllDiskAllocation $computer

                if ($data.Count -gt 1) {
                    $data.GetEnumerator()
                } else {
                    $data
                }
            }
        }
    }
}


text:
var biojsvisboxplot;
var general_setup = require('./general.js');
var axis = require('./axis.js');
var features = require('./features.js');
var barlinebox = require('./box_bar_line.js');
var ref_type = "probeID";

module.exports = biojsvisboxplot = function (init_options)
{
   // Sorts the sorted probe types by second_sort_by state if necesary so that they can
    // be grouped by both second_sort_by state and probe on the x axis
    // http://bl.ocks.org/phoebebright/raw/3176159/ for sorting
    sort_x_by_probe_and_second_sort_by = function(graph) {
        options = graph.options;
        //Check if there is an order given for the second_sort_by states, if none given order by dataset
        if (options.sortByOption.split(",").length != 1) {
            order_types = options.sortByOption.split(",");
            sample_type_order = options.sample_type_order.split(',');
            nested_values = d3.nest()
                .key(function(d) {
                    return d.Probe;
                })
                .sortKeys(function(a, b) {
                    return probe_order.indexOf(a) - probe_order.indexOf(b);
                })
                .key(function (d) {
                  value = order_types[0]//options.sortByOption[0]
                    return d[value];
                })
                .key(function(d) {
                    return d.Sample_Type;
                })
                .sortKeys(function(a,b){
                  return sample_type_order.indexOf(a) - sample_type_order.indexOf(b);})
                .entries(options.data);
        } else {
            sample_type_order = options.sample_type_order.split(',');
            nested_values = d3.nest()
                .key(function(d) {
                    return d.Probe;
                })
                .key(function(d) {
                    return d.second_sort_by;
                })
                .key(function(d) {
                    return d.Sample_Type;
                })
               .sortKeys(function(a,b){return sample_type_order.indexOf(a) - sample_type_order.indexOf(b);})
               .entries(options.data);
        }
        graph.nested_values = nested_values;
        return graph;
    }

    /* Sorts the probes on a given order or default is by the dataset */
    sort_x_by_probe = function(graph) {
        options = graph.options;
        //Check no probe order has been given, if none given order by dataset

        if (options.probe_order != "none") { //changes done by Isha
          if (options.sortByOption.split(",").length != 1) {
                order_types = options.sortByOption.split(",");
                var probe_order = options.probe_order;
                var sample_type_order = options.sample_type_order.split(',');
                nested_values = d3.nest()
                    .key(function(d) {
                        return d.Probe;
                    })
                    .sortKeys(function(a, b) {
                        return probe_order.indexOf(a) - probe_order.indexOf(b);
                    })
                    .key(function (d) {
                      value = order_types[0]
                        return d[value];
                    })
                    .key(function(d) {
                        return d.Sample_Type;
                    })
                    .sortKeys(function(a,b){return sample_type_order.indexOf(a) - sample_type_order.indexOf(b);})
                    .entries(options.data);
          }
          else {
                if(options.sortByOption == "Sample_Type") {
                    var probe_order = options.probe_order;
                    var sample_type_order = options.sample_type_order;
                    nested_values = d3.nest()
                        .key(function(d) {
                            return d.Probe;
                        })
                        .sortKeys(function(a, b) {
                          // change sdone by ISha to correct probe order
                            return probe_order.indexOf(a) - probe_order.indexOf(b);
                        })
                        .key(function(d) {
                            return d.Sample_Type;
                        })
                        .sortKeys(function(a,b){return sample_type_order.indexOf(a) - sample_type_order.indexOf(b);})
                        .entries(options.data);
                }
                else if(options.sortByOption != "null") {
                  var probe_order = options.probe_order;
                  var second_sort_by_order = options.legend_list.list;
                     nested_values = d3.nest()
                             .key(function(d) {
                                 return d.Probe;
                             })
                             .sortKeys(function(a, b) {
                               // change sdone by ISha to correct probe order
                                 return probe_order.indexOf(a) - probe_order.indexOf(b);
                             })
                             .key(function (d) {
                               value = options.sortByOption
                                 return d[value];
                             })
                             .sortKeys(function(a,b){
                               return second_sort_by_order.indexOf(a) - second_sort_by_order.indexOf(b);
                             })
                             .entries(options.data);
               }
          }
        } else {
          sample_type_order = options.sample_type_order.split(',');
            nested_values = d3.nest()
                .key(function(d) {
                    return d.Probe;
                })
                .key(function(d) {
                    return d.Sample_Type;
                })
               .sortKeys(function(a,b){return sample_type_order.indexOf(a) - sample_type_order.indexOf(b);})
               .entries(options.data);

        }
        graph.nested_values = nested_values;
        return graph;
    }

 /*------------------------------Box plot Calculations--------------------------------------*/
    /* Sets up the box plot */
    setup_box_plot = function(graph) {
        sample_types_with_colour = {}
        colour_count = 0;
        options = graph.options;
        nested_values = graph.nested_values;
        second_sort_by = "";
        sample_type_list = [];
        var colour_array = options.colour_array;
        id = 1; //  NOTE CHANGE THISLATER
         for (probe in nested_values) {
            row = nested_values[probe];
            values = row.values;
            probe_name = row.key;
            if (options.sortByOption.split(",").length != 1) { // changes done by Isha
                number_sample_types = options.sample_type_order.split(",").length; //There will be a second key which is the second_sort_by stat
                for (second_sort_bys in values) {
                    row = values[second_sort_bys];
                    second_sort_by_values = row.values;
                    second_sort_by = row.key;
                    // These are the expression values for a specific sample grouped by the probe
                    // then the second_sort_by type so now we need to append all the expression values for this
                    // group then calculate the box plot and draw the values
                    for (sample_types in second_sort_by_values) {
                        sample_row = second_sort_by_values[sample_types];
                        var nan_counter = 0;
                        sample_values = sample_row.values;
                        sample_type = sample_row.key;
                        if($.inArray(sample_type, sample_type_list) == -1) {
                            sample_type_list.push(sample_type);
                        }
                        expression_values = [];
                        //At the level of the xcel file now
                        for (x in sample_values) {
                          if(sample_values[x].Expression_Value == sample_values[x].Expression_Value){
                            expression_values.push(sample_values[x].Expression_Value);
                          }
                          else{
                            nan_counter ++;
                          }
                        }
                        //Now have all the expression values for a specific sample type so we create box
                        //plot and calculate the values
                        if(expression_values.length != 0) {
                              if (options.bar_graph == "yes") {
                              box_plot_vals = calculate_box_plot_vals_bar(expression_values);
                            } else {
                                box_plot_vals = calculate_box_plot_vals(expression_values);
                            }// Actually draw the box plot on the graph
                            graph = draw_box_plot(expression_values, graph, box_plot_vals, probe_name, sample_type, second_sort_by,nan_counter);
                        }
                    }
                }
            } else {
                number_sample_types = values.length;
                for(sample_types in values) {
                    sample_row = values[sample_types];
                    sample_values = sample_row.values;
                    sample_type = sample_row.key;
                    if($.inArray(sample_type, sample_type_list) == -1) {
                        sample_type_list.push(sample_type);
                    }
                    expression_values = [];
                    second_sort_bys = [];
                    second_sort_by_names = "";
                    //At the level of the xcel file now
                    for (x in sample_values) {
                        expression_values.push(sample_values[x].Expression_Value);
                        if ($.inArray(sample_type, second_sort_bys) == -1) {
                            second_sort_bys.push(sample_type);
                        }
                    } /*
                    This is commented out as we now set up the colours before hand

                    for(j=0; j<sample_type_list.length; j++ ) {
                      if(!sample_types_with_colour[sample_type_list[j]])
                      {sample_types_with_colour[sample_type_list[j]] = options.colour[colour_count];
                      if(colour_count < options.colour.length) {colour_count++;}
                      else {colour_count = 0;}}
                    }*/
                    for (second_sort_by in second_sort_bys) {
                        second_sort_by_names = second_sort_bys[second_sort_by] + " " + second_sort_by_names;
                    }
                    //Now have all the expression values for a specific sample type so we create box
                    //plot and calculate the values
                    var nan_counter = 0;
                    expression_values = expression_values.filter(function(v) {if(v==v){
                                                            return true;}
                                                            else{
                                                              nan_counter ++;
                                                              return false;
                                                          }});
                    // changes done by Isha
                    if(expression_values.length != 0) {
                      if (options.bar_graph == "yes") {
                          box_plot_vals = calculate_box_plot_vals_bar(expression_values);
                      } else {
                          box_plot_vals = calculate_box_plot_vals(expression_values);
                      }
                      // Actually draw the box plot on the graph
                      graph = draw_box_plot(expression_values, graph, box_plot_vals, probe_name, sample_type, second_sort_by_names, nan_counter);
                    }

                }
            }
        }
        graph.sample_type_list = sample_type_list;
        return graph;
    }

    add_scatter_to_box = function(svg, graph, scatter_values, median_line, sample_type, colour, colour_stroke) {
        options = graph.options;
        radius = options.radius;
        svg.selectAll(".dot") // class of .dot
            .data(scatter_values) // use the options.data and connect it to the elements that have .dot css
            .enter() // this will create any new data points for anything that is missing.
            .append("circle") // append an object circle
            .attr("class", function(d) {
                    //adds the sample type as the class so that when the sample type is overered over
                    //on the x label, the dots become highlighted
                    return "sample-type-" + sample_type})
            .attr("r", radius) //radius 3.5
            .attr("cx", median_line)
            .attr("cy", function(d) {
                // set the y position as based off y_column
                // ensure that you put these on separate lines to make it easier to troubleshoot
                var cy =  scaleY(d);
                return cy;
            })
            .style("stroke", colour_stroke)
            .style("stroke-width","1px")
            .style("fill", colour)
            .attr("opacity", 0.8)
           .on('mouseover', tooltip_box.show)
           .on('mouseout', tooltip_box.hide);

            return svg;
    }

    make_box_tooltip = function(probe, sample_type, second_sort_by,nan_counter) {
        var tooltip_box = d3.tip()
            .attr('class', 'd3-tip')
            .offset([0, +110])
            .html(function(d) {
               if(nan_counter == 0){
                 temp =
                    "Probe: " + probe + "
" +
                    "Sample Type: " + sample_type +"
"
                  if(options.sortByOption.split(",").length != 1) {
                    temp = temp +  "State: " + second_sort_by +"
"
                  }
                }
                else {
                  temp =
                       "Probe: " + probe + "
" +
                       "Sample Type: " + sample_type +"
" +
                       nan_counter +" Sample Removed Due to Floored Values " + "
"

                   if(options.sortByOption.split(",").length != 1) {
                     temp = temp +  "State: " + second_sort_by +"
"
                   }
                }
                return temp;
            });
        return tooltip_box;
    }

    draw_box = function (svg, graph, box_plot_vals, x_buffer, sample_type_name) {
        var options = graph.options;
        var scaleY = graph.scaleY;
        svg.append("rect")
            .attr('width', box_width)
            .attr('x', x_buffer)
            .attr('id', id)
            .attr('y', function(d) {
                    if (options.bar_graph == "yes") {
                      // changes done By Isha to handle bar on negative axis
                        temp = scaleY(Math.max(0,box_plot_vals[1]));
                    } else {
                        temp = scaleY(box_plot_vals[3]);
                    }
                    return temp;
            })
            .attr('height', function(d) {
                    if (options.bar_graph == "yes") {
                        temp = Math.abs(scaleY(0) - scaleY(box_plot_vals[1]));
                    } else {
                        temp = scaleY(box_plot_vals[1]) - scaleY(box_plot_vals[3]);
                    }
                    if(temp == 0) {temp = 2;}
                return temp;
                })
            .attr("fill", function() {
              if((options.sortByOption.split(',')[0] == 'Sample_Type' || options.sortByOption.split(',')[1] == 'Sample_Type'))
                {return options.colour[sample_type_name];}
              else
                {return options.colour_array[sample_type_name]}
            })
            .attr("opacity", opacity)
            .on("mouseover", tooltip_box.show)
            .on("mouseout", tooltip_box.hide);
	return svg;
    }

    /* Draw box plot draws the box and wiskers onto the graph and also if it is a bar graph this is drawn on too */
    draw_box_plot = function(samples, graph, box_plot_vals, probe_name, sample_type_name, second_sort_by_name, nan_counter) {
        var svg = graph.svg;
        scaleY = graph.scaleY;
        scaleX = graph.scaleX;
        options = graph.options;
        tooltip_box = make_box_tooltip(probe_name, sample_type_name, second_sort_by_name,nan_counter);
        jitter = options.jitter;
        svg.call(tooltip_box);
        box_width = 50;//options.box_width;
        var map = graph.name_mapping;
        // Scale x for the layered x axis
        var box_scale = graph.multi_scaleX;
        var radius = options.radius;
        //Make a group so the whole box can be scaled if need be and add the
        //box to the group
        var median_percent = 0.9; //Means that the median line covers this amount of the box plot
        if((box_width*options.num_sample_types * options.probe_count) > options.width) {
            box_width = options.width / (options.num_sample_types * options.probe_count);
        }
        if(options.sortByOption.split(",").length != 1) {
          for(i=0; i<nested_values[0].values.length; i++) {
            //box_width = Math.min(box_width, (graph.size_of_second_sort_by_collumn / nested_values[0].values[i].values.length))
          }
            var id = remove_chars(probe_name + "-" + sample_type_name + "-" + second_sort_by_name);
            var name = map[id];
            x_buffer = box_scale(name) - box_width/2;
        } else {
            var id = remove_chars(probe_name + "-" + sample_type_name);
            var name = map[id];
            x_buffer = box_scale(name) - box_width/2;
        }
        var group_scale = scale_group_width(graph, x_buffer, box_width, box_scale(name - 1), box_scale(name + 1));
        var box_group = svg.append('g')
                        .attr("id", "group-" + id);
        box_width = box_width * group_scale;
        box_width_wiskers =options.box_width_wiskers; //assumes box width > box_width wiskers
        if (box_width_wiskers * 2 > box_width) {
            box_width_wiskers = box_width/2;
        }
        // Scale the drawing elements
        box_width = box_width * group_scale;
        box_width_wiskers = box_width_wiskers * group_scale;
        stroke_width = options.stroke_width_num * group_scale;
        radius = radius * group_scale;
        if (radius < options.mins.radius) {
            radius = options.mins.radius;
        }
        if (box_width < options.mins.box_width) {
            box_width = options.mins.box_width;
            box_width_wiskers = options.mins.box_width * 0.75;
        }
        if (stroke_width < options.mins.stroke) {
            stroke_width = options.mins.stroke;
        }
        stroke_width = stroke_width + "px";
        // changes done by Isha
        // colour_box = sample_types_with_colour[sample_type_name];
        // colour_box = options.colour_array[sample_type_name];
        if(options.whiskers_needed == true) {
          if((options.sortByOption.split(',')[0] == 'Sample_Type' || options.sortByOption.split(',')[1] == 'Sample_Type'))
            {colour_wiskers = options.colour[sample_type_name];
            colour_box = options.colour[sample_type_name]} // this is when sample type is legend and colour is gradient
          else
            {colour_wiskers = options.colour_array[sample_type_name];
            colour_box = options.colour[sample_type_name]} // this when tissue, gender etc is present and we do not need gradient
        }
        else {
          colour_wiskers = undefined;
          colour_box = options.colour[sample_type_name]
        }
        colour_median = "white";
        id = probe_name + "-" + sample_type_name + "-" + second_sort_by_name;
        //Add vertical lline
        if (options.probe_count == 1 && options.sortByOption.split(",").length == 1 && options.bar_graph == "yes") {
            opacity = 0.4;
            box_group = add_vertical_line_to_box(options.stroke_width, x_buffer + box_width*0.5,
                    box_plot_vals[0], box_plot_vals[2], box_group, scaleY,colour_wiskers, graph);
        }
        else if (options.bar_graph == "yes") {
            opacity = 0.4;
            box_group = add_vertical_line_to_box(options.stroke_width, x_buffer+ box_width*0.5,
                    box_plot_vals[0], box_plot_vals[2], box_group, scaleY,
                colour_wiskers, graph);
        } else {
            opacity = 1;
            box_group = add_vertical_line_to_box(options.stroke_width, x_buffer
                + box_width*0.5, box_plot_vals[0], box_plot_vals[4], box_group, scaleY,
                colour_wiskers, graph);
        }

        //---Want to add the correct tooltip -> this is taken as the first data point in the box ---------------------//
        var data = options.data[probe * second_sort_by];
        //Add box
        box_group = draw_box(box_group, graph, box_plot_vals, x_buffer, sample_type_name);
        //Add min line
        if (options.bar_graph == "yes") {
              if(box_width < 8){
                if (box_plot_vals[0] != box_plot_vals[2]){
                  //Add min line
                  box_group = add_line_to_box(options.stroke_width, x_buffer, box_width, box_plot_vals[0], box_group, scaleY, colour_wiskers, box_width_wiskers,"no", graph);
                  //Add max line
                  box_group = add_line_to_box(options.stroke_width, x_buffer,box_width,
                      box_plot_vals[2], box_group, scaleY, colour_wiskers, box_width_wiskers,
                      "no",graph);
                }
              }
              else {
                //Add min line
                box_group = add_line_to_box(options.stroke_width, x_buffer
                    , box_width, box_plot_vals[0], box_group, scaleY, colour_wiskers, box_width_wiskers,
                    "yes", graph);
                //Add max line
                box_group = add_line_to_box(options.stroke_width, x_buffer
                    , box_width, box_plot_vals[2], box_group, scaleY, colour_wiskers, box_width_wiskers,
                    "yes", graph);
              }
              //Add median lines
              box_group = add_line_to_box(options.stroke_width, x_buffer, box_width,
                    box_plot_vals[1], box_group, scaleY, colour_box, box_width_wiskers,"yes", graph);

            //Add outside lines
            box_group = add_vertical_line_to_box(options.stroke_width, x_buffer, 0,
                box_plot_vals[1], box_group, scaleY, colour_box, graph);
            box_group = add_vertical_line_to_box(options.stroke_width, x_buffer
                + box_width, 0, box_plot_vals[1], box_group, scaleY, colour_box, graph);
        } else {
          if(box_width < 8){
            //Add max line
             box_group = add_line_to_box(options.stroke_width, x_buffer, box_width,
                 box_plot_vals[0], box_group, scaleY, colour_wiskers, box_width_wiskers,"no", graph);
             //Add max line
             box_group = add_line_to_box(options.stroke_width, x_buffer, box_width,
                 box_plot_vals[4], box_group, scaleY, colour_wiskers, box_width_wiskers,"no", graph);
          }
          else {
            //Add max line
             box_group = add_line_to_box(options.stroke_width, x_buffer, box_width,
                 box_plot_vals[0], box_group, scaleY, colour_wiskers, box_width_wiskers,"yes", graph);
             //Add median line
             box_group = add_line_to_box(options.stroke_width, x_buffer
                 , box_width, box_plot_vals[2], box_group, scaleY, colour_median,
                 (box_width/2.0)*median_percent,"yes", graph);
             //Add max line
             box_group = add_line_to_box(options.stroke_width, x_buffer, box_width,
                 box_plot_vals[4], box_group, scaleY, colour_wiskers, box_width_wiskers,"yes", graph);
          }
        }
        //Option to allow the user to test their values
        if (options.test == "yes") {
            test_values(second_sort_by_name + " " + probe_name + "|" + sample_type_name, box_plot_vals, graph, options);
        }
        if (options.draw_scatter_on_box == "yes" && jitter != "yes") {
            box_group = add_scatter_to_box(box_group, graph, samples, x_buffer + box_width/2, sample_type, "white", "black", radius);
        } else if (options.draw_scatter_on_box == "yes" && jitter == "yes") {
            box_group = draw_jitter_scatter(svg, graph, samples, x_buffer + (box_width/4), box_width, sample_type, "white", colour_wiskers, radius);
        }
        graph.svg = svg;
        return graph;
    }

    draw_jitter_scatter = function(svg, graph, samples, x, box_width, sample_type, colour, colour_stroke, radius) {
        scaleXBox = d3.scale.ordinal()
            .rangePoints([x, x + box_width]);
        options = graph.options;
        scaleXBox.domain(samples);
        scale = (box_width/2) / samples.length;
        svg.selectAll(".dot") // class of .dot
            .data(samples) // use the options.data and connect it to the elements that have .dot css
            .enter() // this will create any new data points for anything that is missing.
            .append("circle") // append an object circle
            .attr("class", function(d) {
                    //adds the sample type as the class so that when the sample type is overered over
                    //on the x label, the dots become highlighted
                    return "sample-type-" + sample_type})
            .attr("r", radius) //radius 3.5
            .attr("cx", function(d, i) {
                    cx = x + (scale * i);
                    return cx;
                    })
            .attr("cy", function(d) {
                // set the y position as based off y_column
                // ensure that you put these on separate lines to make it easier to troubleshoot
                var cy =  scaleY(d);
                return cy;
            })
            .style("stroke", colour_stroke)
            .style("stroke-width","1px")
            .style("fill", colour)
            .attr("opacity", 0.8);
           // .on('mouseover', tooltip.show)
           // .on('mouseout', tooltip.hide);

            return svg;

    }

    /* A small function to test the values from the computed values
     * Checks values from graphs downloaded from stemformatics */
    test_values = function(name, box_plot_vals, graph, options) {
        //var fs = require('fs');
        //name in format as saved by stemformatics: name, average. standard deviation, min, max, median, Q1, Q3
        row = name + "," + 0 + "," + 0 + "," + box_plot_vals[0] + "," + box_plot_vals[4] + "," + box_plot_vals[2] + "," + box_plot_vals[1] + "," + box_plot_vals[3];
        if (options.bar_graph == "yes") {
            row = name + "," + box_plot_vals[1] + "," + 0 + "," + box_plot_vals[0] + "," + box_plot_vals[2] + "," + 0 + "," + 0 + "," + 0;
        }
        //console.log(row);
        /*fs.writeFile(options.test_path, row, function(err) {
            if(err) {
                return console.log(err);
            }
            console.log("The file was saved!");
        }); */
    }

	get_mean_value = function(values) {
		sum = 0;
        for (i in values) {
            sum += values[i];
        }
        mean = sum / values.length;
        return mean;
	}

    /* Takes the array of samples for a specific sample type
     * already ordered */
    calculate_box_plot_vals_bar = function(values) {
        min_max_vals = return_min_max_vals(values);
        var mean = get_mean_value(values);
        sum = 0;
        numbers_meaned = [];
        for (x in values) {
            numbers_meaned.push(Math.abs(values[x] - mean));
        }
        standard_deviation = get_mean_value(numbers_meaned);
        min = min_max_vals[0];
        max = min_max_vals[1];
        return [mean - standard_deviation, mean, mean + standard_deviation];
    }

    /* Takes the array of samples for a specific sample type
     * already ordered */
    calculate_box_plot_vals = function(values) {
      // http://thiruvikramangovindarajan.blogspot.com.au/2014/10/calculate-quartile-q1-q3-and-median-q2.html
        values.sort(function(a, b) {return a-b});
        min_max_vals = return_min_max_vals(values);
        var median = get_median_value(values,0.50);
        max_quartile = [];
        min_quartile = [];
        min_quartile = (values.length % 2 == 0) ? values.slice(0, (values.length / 2) + 1) : values.slice(0, Math.floor(values.length / 2) + 1);
        max_quartile = (values.length % 2 == 0) ? values.slice( (values.length/2) - 1, values.length) : values.slice(Math.ceil(values.length / 2) - 1, values.length);
        min_quartile_median = get_median_value(values, 0.25);
        max_quartile_median = get_median_value(values, 0.75);
        min = min_max_vals[0];
        max = min_max_vals[1];
        return [min, min_quartile_median, median, max_quartile_median, max];
    }

    //Returns the max and minimum values from the daa set
    return_min_max_vals = function(values) {
      // changes done by Isha for caculating box plot for negative values
        max_val = -50;
        min_val = 100;

        for (sample_value in values) {
            if (values[sample_value] < min_val) {
                min_val = values[sample_value];
            }
            if (values[sample_value] > max_val) {
                max_val = values[sample_value];
            }
        }
        return [min_val, max_val];
    }

	//Returns the median value from a set of values
	//https://gist.github.com/caseyjustus/1166258
	get_median_value = function(values, percent) {
    // count = values.length;
    // median = (count % 2 == 0) ? (values[(values.length/2) - 1] + values[(values.length / 2)]) / 2:values[Math.floor(values.length / 2)];
    k = (values.length - 1) * percent;
    f = Math.floor(k);
    c = Math.ceil(k);
    if( f == c) {
      return values[k]
    }
    else {
      d0 = values[f] * ( c-k);
      d1 = values[c] * (k-f);
      return d0+d1;
    }
	}

	/* Gets the 3 important values for the box plot
	 * Median
	 * Lower median value
	 * upper median value
	 */
	get_box_plot_values = function(graph) {
		options = graph.options;
		expression_values = [];
		lwr_half_of_Expresssion_vals = [];
		upr_half_of_expression_vals = [];

		get_expression_values = d3.extent(options.data, function(d) {
			expression_values.append(d.Expression_Value);
			return d.Expression_Value;
		});
		get_expression_values.sort(function(a, b) {return a-b});
		median_val = get_median_value(expression_values);
		for(val in expression_values) {
			if (val < median_val) {
				lwr_half_of_expresssion_vals.append(val);
			} else if (val > median_val) {
				upr_half_of_expression_vals.append(val);
			}
		}
		third_quartile = get_median_value(lwr_half_of_expresssion_vals);
		first_quartile = get_median_value(upr_half_of_expression_vals);
		graph.median_val = median_val;
		graph.third_quartile = third_quartile;
		graph.first_quartile = first_quartile;
		return graph;
	}

    /*------------------------End of box plot calculations -----------------------------------*/

 /** --------------------------- ADDED to make modular ----------------------------- */

    /**
     * gets a particular type -> this is used to mae the code more modular
     * Allows us to have probes as main type and samples for others
     */
    get_type = function (data_point) {
        return data_point.probe;
    }

    /*  Setting up the graph including y and x axes */
    setup_graph = function(graph){
        // setup all the graph elements
	    graph.graph_type = "Box Plot";
        options = graph.options;
        var label_padding = options.x_axis_label_padding;
        temp_val = 0;
        diff_val = 0;
        padding_val = 0;
        var x_axis_position = "bottom";
        var class_name = ".probe_text";
        var collective_name = ".probe-";
        var class_name_for_legend = ".sample_text";
        var collective_name_for_legend = ".sample-";
        graph = setup_margins(graph);
        //graph = setup_size_options(graph);
        graph = setup_svg(graph);
        // Check if it is also being sorted by the second_sort_by state on the x axis
        if (options.include_second_sort_by_x_axis == "yes") {
            graph = sort_x_by_probe_and_second_sort_by(graph);
        } else {
            graph = sort_x_by_probe(graph);
        }
        graph = setup_data_for_x_axis(graph);
        graph = setup_x_axis(graph, graph.probe_list);
        graph = setup_x_axis_labels(graph, null, label_padding, class_name_for_legend, collective_name_for_legend, 3, x_axis_position);
        label_padding += 120;
     	if (options.sortByOption.split(",").length != 1) {
		    graph = setup_x_axis_labels(graph, null, label_padding, class_name, collective_name, 2, x_axis_position);
            // Add extra padding to the label
            label_padding += 80;
        }
	    graph = setup_x_axis_labels(graph, null, label_padding, class_name, collective_name, 1, x_axis_position);
        graph = setup_y_axis(graph);
        graph = setup_box_plot(graph);
        graph =  setup_watermark(graph);
        if (options.display.legend  === "yes") {
             graph = setup_D3_legend(graph, options.legend_list);
        }
        //graph = setup_vertical_lines(graph);

	    // Only display the vertical lines if the user chooses so
        if (options.display.vertical_lines == "yes") {
            graph = setup_vertical_lines(graph, graph.sample_id_list, 1);
            graph = setup_vertical_lines(graph, graph.sample_id_list, 2);
        }
        if (options.display.horizontal_lines == "yes") {
            graph = setup_horizontal_lines(graph);
        }
        return graph;

    }  // end setup_graph

    // run this right at the start of the initialisation of the class
    init = function(init_options){
        var options = default_options();
        options = init_options;
        page_options = {}; // was new Object() but jshint wanted me to change this
        var graph = {}; // this is a new object
        graph.options = options;
        graph = preprocess_lines(graph);
        graph = setup_graph(graph);
        var target = $(options.target);
        target.addClass('box_plot');

        svg = graph.svg;
    }

    // constructor to run right at the start
    init(init_options);
}


text:
<!DOCTYPE HTML>
<html>
<head>
	<title>phaser.js - a new beginning</title>
	<?php
		require('js.php');
	?>
</head>
<body>

<script type="text/javascript">

(function () {

	var game = new Phaser.Game(800, 600, Phaser.CANVAS, '', { create: create, update: update, render: render });
	var s;

	function create() {

		var text = "--- phaser ---\nwith a sprinkle of\npixi dust";
		var style = { font: "bold 40pt Arial", fill: "#ffffff", align: "center", stroke: "#258acc", strokeThickness: 8 };

		s = game.add.text(game.world.centerX, game.world.centerY, text, style);
		s.anchor.setTo(0.5, 0.5);

	}

	function update() {
		s.angle += 1;
	}

	function render() {
		game.debug.renderSpriteCorners(s, true, true);
	}

})();

</script>

</body>
</html>


text:
require_relative "../../lib/cinchcli"

parsed_cli_args = CinchCliBuilder.new("../json_files/unparsable.json",ARGV)


text:
package br.com.aurum.astrea.service;

import com.google.appengine.api.datastore.Query.FilterOperator;

public class ContactField {

	public enum Field {
		NAME("filterName", "name"),
		EMAIL("emails", "email"),
		CPF("cpf", "cpf");

		private String fieldName;
		private String paramName;

		private Field(String fieldName, String paramName) {
			this.fieldName = fieldName;
			this.paramName = paramName;
		}

		public String getFieldName() {
			return this.fieldName;
		}

		public static Field getFieldByParamName(String paramName) {
			for (Field field : Field.values()) {
				if (paramName.equals(field.paramName)) {
					return field;
				}
			}

			return null;
		}
	}

	private Field field;

	private String value;

	private FilterOperator filterOperator;

	public String getValue() {
		return this.value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public FilterOperator getFilterOperator() {
		return this.filterOperator;
	}

	public void setFilterOperator(FilterOperator filterOperator) {
		this.filterOperator = filterOperator;
	}

	public Field getField() {
		return this.field;
	}

	public void setField(Field field) {
		this.field = field;
	}
}


text:
layout: post
title:  "Enabling CORS in Rails Apps"
date:   2014-10-27 23:52:00
categories: jekyll update
number: 4
---

header['Access-Control-Allow-Origin'] = '*'
header['Access-Control-Methods'] = 'GET, POST, OPTIONS'
skip_before_filter: :verify_authenticity_token


text:
using Observable.ObservableValue;
using System;

namespace Observable.Binding
{
    /// <summary>
    /// Binding of a generic value, computed by a user given logic and dependencies.
    /// </summary>
    public class ObjectBinding<T> : ObjectExpression<T>
    {
        public ObjectBinding(Func<T> compute, params IObservableValue[] dependencies)
        {
            foreach (IObservableValue dep in dependencies)
            {
                dep.PropertyChanged += (s, e) =>
                {
                    Value = compute();
                };
            }
        }
    }
}


text:
<?php

use Amostajo\WPPluginCore\Config;

/**
 * This file will load configuration file and init Main class.
 *
 * @author Alejandro Mostajo
 * @license MIT
 * @package Amostajo\WPDevTemplates
 * @version 1.0.2
 */

/**
 * Moved from plugin.php
 * @since 1.0.2
 */
require_once( plugin_dir_path( __FILE__ ) . '/../vendor/autoload.php' );

// --

$config = include( plugin_dir_path( __FILE__ ) . '../config/plugin.php' );

$plugin_namespace = $config['namespace'];

$plugin_name = strtolower( explode( '\\' , $plugin_namespace )[0] );

$plugin_class = $plugin_namespace . '\Main';

$plugin_reflection = new ReflectionClass( get_parent_class( $plugin_class ) );

/**
 * Core version check.
 * @since 1.0.2
 */
if ( $plugin_reflection->hasMethod( 'add_hooks' ) ) {

    $$plugin_name = new $plugin_class( new Amostajo\WPPluginCore\Config( $config ) );

    //--- INIT
    /**
     * Autoload init to support addons.
     * @since 1.0.1
     */
    $$plugin_name->autoload_init();

    //--- ON ADMIN
    if ( is_admin() ) {
        /**
         * Autoload on admin to support addons.
         * @since 1.0.1
         */
        $$plugin_name->autoload_on_admin();
    }

    /**
     * WPPluginCore hooks support.
     * @since 1.0.2
     */
    $$plugin_name->add_hooks();

} else {
    $plugin_error = $plugin_reflection;
    add_action( 'admin_notices', 'wdt_hooks_error' );
}

/**
 * Version notice.
 * @since 1.0.2
 */
if ( ! function_exists( 'wdt_hooks_error' )  ) {
    /**
     * Displayes wordpress admin notice for missing hooks function.
     * @since 1.0.2
     */
    function wdt_hooks_error()
    {
        global $plugin_error;
        ?>

            <?php printf(
                'One or more plugins/themes using %s is not updated to the latest version, this will affect those who are update.
%s can not be used.
File that needs update %s.
Please notify the developer of this package.',
                'WP Dev Templates',
                'add_hooks()',
                $plugin_error->getFileName()
            ) ?>

        <?php
        unset($plugin_error);
    }
}

// Unset
unset($plugin_reflection);
unset($config);
unset($plugin_namespace);
unset($plugin_name);
unset($plugin_class);


text:
list(APPEND RUBY_CONFIGURE_CMD env)
list(APPEND RUBY_CONFIGURE_CMD <SOURCE_DIR>/configure)
list(APPEND RUBY_CONFIGURE_CMD --prefix=${INSTALL_PREFIX_EMBEDDED})
list(APPEND RUBY_CONFIGURE_CMD --enable-load-relative)
list(APPEND RUBY_CONFIGURE_CMD --disable-rpath)
list(APPEND RUBY_CONFIGURE_CMD --disable-install-doc)

ExternalProject_Add(
  ruby
  URL https://cache.ruby-lang.org/pub/ruby/ruby-${RUBY_VERSION}.tar.bz2
  URL_HASH SHA256=${RUBY_HASH}
  CONFIGURE_COMMAND rm -rf <BINARY_DIR> && mkdir -p <BINARY_DIR> # Clean across version upgrades
    COMMAND ${RUBY_CONFIGURE_CMD}
  INSTALL_COMMAND make install DESTDIR=${STAGE_DIR}
)

ExternalProject_Add(
  rubygems
  DEPENDS ruby
  URL https://rubygems.org/downloads/rubygems-update-${RUBYGEMS_VERSION}.gem
  URL_HASH SHA256=${RUBYGEMS_HASH}
  DOWNLOAD_NO_EXTRACT 1
  CONFIGURE_COMMAND ""
  BUILD_COMMAND ""
  INSTALL_COMMAND env PATH=${STAGE_EMBEDDED_DIR}/bin:$ENV{PATH} gem update --system ${RUBYGEMS_VERSION} --no-document
)

ExternalProject_Add(
  bundler
  DEPENDS rubygems
  URL https://rubygems.org/downloads/bundler-${BUNDLER_VERSION}.gem
  URL_HASH SHA256=${BUNDLER_HASH}
  DOWNLOAD_NO_EXTRACT 1
  CONFIGURE_COMMAND ""
  BUILD_COMMAND ""
  INSTALL_COMMAND env PATH=${STAGE_EMBEDDED_DIR}/bin:$ENV{PATH} gem install <DOWNLOADED_FILE> --no-document --env-shebang --local --force
)


text:
<?php

namespace App\Domain\Entity\AutoWhiteList\DomainAutoWhiteList;

use App\Domain\AutoWhiteList\DomainAutoWhiteList\Validator\UniqueEntry;
use DateTimeImmutable;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer;
use Symfony\Component\Validator\Constraints as Assert;
use Webmozart\Assert\Assert as WebAssert;

#[ORM\Entity(repositoryClass: DomainAutoWhiteListRepository::class)]
#[ORM\Table(name: 'domain_awl')]
#[Serializer\ExclusionPolicy(Serializer\ExclusionPolicy::ALL)]
#[Serializer\ReadOnlyProperty]
#[UniqueEntry]
class DomainAutoWhiteList
{
    #[ORM\Id]
    #[ORM\Column(name: 'sender_domain', type: 'string', length: 128, nullable: false)]
    #[Assert\Type('string')]
    #[Assert\Length(max: 128)]
    #[Assert\NotBlank]
    #[Serializer\Expose]
    #[Serializer\Type('string')]
    public string $domain = '';

    #[ORM\Id]
    #[ORM\Column(name: 'src', type: 'string', length: 128, nullable: false)]
    #[Assert\Type('string')]
    #[Assert\Length(max: 128)]
    #[Assert\NotBlank]
    #[Serializer\Expose]
    #[Serializer\Type('string')]
    public string $source = '';

    #[ORM\Column(name: "first_seen", type: "datetime_immutable")]
    #[Serializer\Expose]
    #[Serializer\Type(DateTimeImmutable::class . '<\'Y-m-d H:i:s\'>')]
    public ?DateTimeImmutable $firstSeen = null;

    #[ORM\Column(name: "last_seen", type: "datetime_immutable")]
    #[Serializer\Expose]
    #[Serializer\Type(DateTimeImmutable::class . '<\'Y-m-d H:i:s\'>')]
    public ?DateTimeImmutable $lastSeen = null;

    public static function create(
        string $domain,
        string $source,
        ?DateTimeImmutable $firstSeen = null,
        ?DateTimeImmutable $lastSeen = null,
    ): self
    {
        return new self($domain, $source, $firstSeen, $lastSeen);
    }

    private function __construct(string $domain, string $source,
        ?DateTimeImmutable $firstSeen = null,
        ?DateTimeImmutable $lastSeen = null)
    {
        $this->setDomain($domain)
            ->setSource($source)
            ->setFirstSeen($firstSeen)
            ->setLastSeen($lastSeen);
    }

    public function getDomain(): string
    {
        return $this->domain;
    }

    public function setDomain(string $domain): self
    {
        WebAssert::lengthBetween($domain, 1, 128);
        $this->domain = $domain;
        return $this;
    }

    public function getSource(): string
    {
        return $this->source;
    }

    public function setSource(string $source): self
    {
        WebAssert::lengthBetween($source, 1, 128);
        $this->source = $source;
        return $this;
    }

    public function getFirstSeen(): DateTimeImmutable
    {
        return $this->firstSeen;
    }

    public function setFirstSeen(?DateTimeImmutable $firstSeen = null): self
    {
        $this->firstSeen = $firstSeen ?: new DateTimeImmutable('now');
        return $this;
    }

    public function getLastSeen(): DateTimeImmutable
    {
        return $this->lastSeen;
    }

    public function setLastSeen(?DateTimeImmutable $lastSeen = null): self
    {
        $this->lastSeen = $lastSeen ?: new DateTimeImmutable('now');
        return $this;
    }
}


text:
const shiftDownBlock = (state) => {
  const flags = new Array(10).fill(false);

  return state
      .set('world', state.get('world').map((row, y) => row.set(
          'blocks',
          row.get('blocks').map((block, x) => {
            const prevFlag = flags[x];
            flags[x] = block.get('value') === 2;

            if (flags[x]) return block.set('value', prevFlag ? 2 : 0);

            return prevFlag ? block.set('value', 2) : block;
          })
      )))
      .setIn(
          ['currentDetail', 'pointY'],
          state.getIn(['currentDetail', 'pointY']) + 1
      );
};

export default shiftDownBlock;


text:
package org.neptunepowered.vanilla.mixin.core.util;

import net.canarymod.api.chat.ChatComponent;
import net.minecraft.util.ChatComponentStyle;
import net.minecraft.util.ChatComponentText;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;

@Mixin(ChatComponentText.class)
public abstract class MixinChatComponentText extends ChatComponentStyle {

    @Shadow private String text;

    public ChatComponent setText(final String text) {
        this.text = text;
        return (ChatComponent) this;
    }

}


text:
namespace cc {
class PrioritizedTile;

class RasterTilePriorityQueueRequired : public RasterTilePriorityQueue {
 public:
  RasterTilePriorityQueueRequired();
  ~RasterTilePriorityQueueRequired() override;

  bool IsEmpty() const override;
  const PrioritizedTile& Top() const override;
  void Pop() override;

 private:
  friend class RasterTilePriorityQueue;

  void Build(const std::vector<PictureLayerImpl*>& active_layers,
             const std::vector<PictureLayerImpl*>& pending_layers,
             Type type);
  void BuildRequiredForDraw(
      const std::vector<PictureLayerImpl*>& active_layers);
  void BuildRequiredForActivation(
      const std::vector<PictureLayerImpl*>& active_layers,
      const std::vector<PictureLayerImpl*>& pending_layers);

  ScopedPtrVector<TilingSetRasterQueueRequired> tiling_set_queues_;

  DISALLOW_COPY_AND_ASSIGN(RasterTilePriorityQueueRequired);
};

}  // namespace cc

#endif  // CC_TILES_RASTER_TILE_PRIORITY_QUEUE_REQUIRED_H_


text:
typedef struct {
    int capacity;
    int length;
    char data[];
} text_buffer;

text_buffer * text_buffer_new(int);
void text_buffer_destroy(text_buffer *);
text_buffer * text_buffer_add(text_buffer *, const char *, int);
const char * text_buffer_data(const text_buffer *);
void text_buffer_clear(text_buffer *);
void text_buffer_remove(text_buffer *, int);
int text_buffer_length(const text_buffer *);

#endif


text:
//
//  DTImageCache.m
//  PL
//
//  Created by Oliver Drobnik on 29.11.13.
//  Copyright (c) 2013 Cocoanetics. All rights reserved.
//

#import "DTImageCache.h"
#import "DTManagedImage.h"
#import "DTLog.h"

#import "NSString+DTPaths.h"
#import "UIImage+DTFoundation.h"
#import "DTCachedFile.h"
#import "DTCoreGraphicsUtils.h"

#import <CoreData/CoreData.h>

static DTImageCache *_sharedInstance = nil;

@implementation DTImageCache
{
	NSManagedObjectModel *_managedObjectModel;
	NSPersistentStoreCoordinator *_persistentStoreCoordinator;
	NSManagedObjectContext *_writerContext;
	NSManagedObjectContext *_workerContext;
}

+ (DTImageCache *)sharedCache
{
	static dispatch_once_t onceToken;

	dispatch_once(&onceToken, ^{
		_sharedInstance = [[DTImageCache alloc] init];
	});

	return _sharedInstance;
}

- (instancetype)init
{
	self = [super init];

	if (self)
	{
		[self _setupCoreDataStack];
	}

	return self;
}

#pragma mark - Internal Helpers

// returned objects can only be used from the same context
- (DTManagedImage *)_mangedImageForUniqueIdentifier:(NSString *)uniqueIdentifier variantIdentifier:(NSString *)variantIdentifier inContext:(NSManagedObjectContext *)context
{
	NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"DTManagedImage"];

	if (variantIdentifier)
	{
		request.predicate = [NSPredicate predicateWithFormat:@"uniqueIdentifier == %@ AND variantIdentifier == %@", uniqueIdentifier, variantIdentifier];
	}
	else
	{
		request.predicate = [NSPredicate predicateWithFormat:@"uniqueIdentifier == %@ AND variantIdentifier == nil", uniqueIdentifier];
	}
	request.fetchLimit = 1;

	NSError *error;
	NSArray *results = [context executeFetchRequest:request error:&error];

	if (!results)
	{
		NSLog(@"error occured fetching %@", [error localizedDescription]);
	}

   return [results lastObject];
}

- (void)_commit
{
	NSError *error;
	if (![_workerContext save:&error])
	{
		DTLogError(@"Unable to save worker context: %@", [error localizedDescription]);
	}

	[_writerContext performBlock:^{

		NSError *error;
		if (![_writerContext save:&error])
		{
			DTLogError(@"Unable to save writer context: %@", [error localizedDescription]);
		}
	}];
}

#pragma mark - Public API

- (void)addImage:(UIImage *)image forUniqueIdentifier:(NSString *)uniqueIdentifier variantIdentifier:(NSString *)variantIdentifier
{
	NSParameterAssert(uniqueIdentifier);
	NSParameterAssert(image);

	[_workerContext performBlock:^{

		DTManagedImage *managedImage = [self _mangedImageForUniqueIdentifier:uniqueIdentifier variantIdentifier:variantIdentifier inContext:_workerContext];

		if (managedImage)
		{
			DTLogInfo(@"Managed Image already exists in cache");
			return;
		}

		managedImage = (DTManagedImage *)[NSEntityDescription insertNewObjectForEntityForName:@"DTManagedImage" inManagedObjectContext:_workerContext];

		NSData *imageData = UIImagePNGRepresentation(image);

		managedImage.uniqueIdentifier = uniqueIdentifier;
		managedImage.variantIdentifier = variantIdentifier;
		managedImage.fileSize = @(imageData.length);
		managedImage.lastAccessDate = [NSDate date];
		managedImage.fileData = imageData;
		managedImage.imageSize = image.size;

		[self _commit];

	}];
}

- (UIImage *)imageForUniqueIdentifier:(NSString *)uniqueIdentifier variantIdentifier:(NSString *)variantIdentifier
{
	__block UIImage *image = nil;

	NSParameterAssert(uniqueIdentifier);

	[_workerContext performBlockAndWait:^{

		DTManagedImage *managedImage = [self _mangedImageForUniqueIdentifier:uniqueIdentifier variantIdentifier:variantIdentifier inContext:_workerContext];

		if (managedImage.fileData)
		{
			image = [UIImage imageWithData:managedImage.fileData];
		}

		managedImage.lastAccessDate = [NSDate date];
		[self _commit];
	}];

	return image;
}

#pragma mark - Core Data Stack

- (NSManagedObjectModel *)_model
{
	NSManagedObjectModel *model = [[NSManagedObjectModel alloc] init];

	// create the entity
	NSEntityDescription *entity = [[NSEntityDescription alloc] init];
	[entity setName:@"DTManagedImage"];
	[entity setManagedObjectClassName:@"DTManagedImage"];

	// create the attributes
	NSMutableArray *properties = [NSMutableArray array];

	NSAttributeDescription *uniqueIdentifierAttribute = [[NSAttributeDescription alloc] init];
	[uniqueIdentifierAttribute setName:@"uniqueIdentifier"];
	[uniqueIdentifierAttribute setAttributeType:NSStringAttributeType];
	[uniqueIdentifierAttribute setOptional:NO];
	[uniqueIdentifierAttribute setIndexed:YES];
	[properties addObject:uniqueIdentifierAttribute];

	NSAttributeDescription *variantIdentifierAttribute = [[NSAttributeDescription alloc] init];
	[variantIdentifierAttribute setName:@"variantIdentifier"];
	[variantIdentifierAttribute setAttributeType:NSStringAttributeType];
	[variantIdentifierAttribute setOptional:YES];
	[variantIdentifierAttribute setIndexed:YES];
	[properties addObject:variantIdentifierAttribute];

	NSAttributeDescription *fileDataAttribute = [[NSAttributeDescription alloc] init];
	[fileDataAttribute setName:@"fileData"];
	[fileDataAttribute setAttributeType:NSBinaryDataAttributeType];
	[fileDataAttribute setOptional:YES];
	[fileDataAttribute setAllowsExternalBinaryDataStorage:YES];
	[properties addObject:fileDataAttribute];

	NSAttributeDescription *lastAccessDateAttribute = [[NSAttributeDescription alloc] init];
	[lastAccessDateAttribute setName:@"lastAccessDate"];
	[lastAccessDateAttribute setAttributeType:NSDateAttributeType];
	[lastAccessDateAttribute setOptional:NO];
	[properties addObject:lastAccessDateAttribute];

	NSAttributeDescription *fileSizeAttribute = [[NSAttributeDescription alloc] init];
	[fileSizeAttribute setName:@"fileSize"];
	[fileSizeAttribute setAttributeType:NSInteger32AttributeType];
	[fileSizeAttribute setOptional:YES];
	[properties addObject:fileSizeAttribute];

	NSAttributeDescription *imageSizeWidthAttribute = [[NSAttributeDescription alloc] init];
	[imageSizeWidthAttribute setName:@"imageSizeWidth"];
	[imageSizeWidthAttribute setAttributeType:NSInteger32AttributeType];
	[imageSizeWidthAttribute setOptional:NO];
	[properties addObject:imageSizeWidthAttribute];

	NSAttributeDescription *imageSizeHeightAttribute = [[NSAttributeDescription alloc] init];
	[imageSizeHeightAttribute setName:@"imageSizeHeight"];
	[imageSizeHeightAttribute setAttributeType:NSInteger32AttributeType];
	[imageSizeHeightAttribute setOptional:NO];
	[properties addObject:imageSizeHeightAttribute];

	// add attributes to entity
	[entity setProperties:properties];

	// add entity to model
	[model setEntities:[NSArray arrayWithObject:entity]];

	return model;
}

- (void)_setupCoreDataStack
{
	// setup managed object model

	/*
     NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"DTDownloadCache" withExtension:@"momd"];
     _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
	 */

	// in code
    _managedObjectModel = [self _model];

	// setup persistent store coordinator
	NSURL *storeURL = [NSURL fileURLWithPath:[[NSString cachesPath] stringByAppendingPathComponent:@"DTImageCache.cache"]];

	NSError *error = nil;
	_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:_managedObjectModel];

	if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
	{
		DTLogWarning(@"Inconsistent %@ Store, attempting to fix by removing it", NSStringFromClass([self class]));

		// inconsistent model/store
		[[NSFileManager defaultManager] removeItemAtURL:storeURL error:NULL];

		// retry once
		if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
		{
			NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
			abort();
		}
	}

    // create writer MOC
    _writerContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
	[_writerContext setPersistentStoreCoordinator:_persistentStoreCoordinator];

    // create worker MOC for background operations
    _workerContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    _workerContext.parentContext = _writerContext;
}

@end