text:
<?php

namespace Bigcommerce\Api;

use \Exception as Exception;
use Firebase\JWT\JWT;

/**
 * Bigcommerce API Client.
 */
class Client
{
    /**
     * Full Store URL to connect to
     *
     * @var string
     */
    static private $store_url;

    /**
     * Username to connect to the store API with
     *
     * @var string
     */
    static private $username;

    /**
     * API key
     *
     * @var string
     */
    static private $api_key;

    /**
     * Connection instance
     *
     * @var Connection
     */
    static private $connection;

    /**
     * Resource class name
     *
     * @var string
     */
    static private $resource;

    /**
     * API path prefix to be added to store URL for requests
     *
     * @var string
     */
    static private $path_prefix = '/api/v2';

    /**
     * Full URL path to the configured store API.
     *
     * @var string
     */
    static public $api_path;
    static private $client_id;
    static private $store_hash;
    static private $auth_token;
    static private $client_secret;
    static private $stores_prefix = '/stores/%s/v2';
    static private $api_url = 'https://api.bigcommerce.com';
    static private $login_url = 'https://login.bigcommerce.com';

    /**
     * Configure the API client with the required settings to access
     * the API for a store.
     *
     * Accepts OAuth and (for now!) Basic Auth credentials
     *
     * @param array $settings
     */
    public static function configure($settings)
    {
        if (isset($settings['client_id'])) {
            self::configureOAuth($settings);
        } else {
            self::configureBasicAuth($settings);
        }
    }

    /**
     * Configure the API client with the required OAuth credentials.
     *
     * Requires a settings array to be passed in with the following keys:
     *
     * - client_id
     * - auth_token
     * - store_hash
     *
     * @param array $settings
     * @throws \Exception
     */
    public static function configureOAuth($settings)
    {
        if (!isset($settings['auth_token'])) {
            throw new Exception("'auth_token' must be provided");
        }

        if (!isset($settings['store_hash'])) {
            throw new Exception("'store_hash' must be provided");
        }

        self::$client_id = $settings['client_id'];
        self::$auth_token = $settings['auth_token'];
        self::$store_hash = $settings['store_hash'];

        self::$client_secret = isset($settings['client_secret']) ? $settings['client_secret'] : null;

        self::$api_path = self::$api_url . sprintf(self::$stores_prefix, self::$store_hash);
        self::$connection = false;
    }

    /**
     * Configure the API client with the required credentials.
     *
     * Requires a settings array to be passed in with the following keys:
     *
     * - store_url
     * - username
     * - api_key
     *
     * @param array $settings
     * @throws \Exception
     */
    public static function configureBasicAuth(array $settings)
    {
        if (!isset($settings['store_url'])) {
            throw new Exception("'store_url' must be provided");
        }

        if (!isset($settings['username'])) {
            throw new Exception("'username' must be provided");
        }

        if (!isset($settings['api_key'])) {
            throw new Exception("'api_key' must be provided");
        }

        self::$username = $settings['username'];
        self::$api_key = $settings['api_key'];
        self::$store_url = rtrim($settings['store_url'], '/');
        self::$api_path = self::$store_url . self::$path_prefix;
        self::$connection = false;
    }

    /**
     * Configure the API client to throw exceptions when HTTP errors occur.
     *
     * Note that network faults will always cause an exception to be thrown.
     *
     * @param bool $option sets the value of this flag
     */
    public static function failOnError($option = true)
    {
        self::connection()->failOnError($option);
    }

    /**
     * Return XML strings from the API instead of building objects.
     */
    public static function useXml()
    {
        self::connection()->useXml();
    }

    /**
     * Return JSON objects from the API instead of XML Strings.
     * This is the default behavior.
     */
    public static function useJson()
    {
        self::connection()->useXml(false);
    }

    /**
     * Switch SSL certificate verification on requests.
     *
     * @param bool $option sets the value of this flag
     */
    public static function verifyPeer($option = false)
    {
        self::connection()->verifyPeer($option);
    }

    /**
     * Connect to the internet through a proxy server.
     *
     * @param string $host host server
     * @param int|bool $port port number to use, or false
     */
    public static function useProxy($host, $port = false)
    {
        self::connection()->useProxy($host, $port);
    }

    /**
     * Get error message returned from the last API request if
     * failOnError is false (default).
     *
     * @return string
     */
    public static function getLastError()
    {
        return self::connection()->getLastError();
    }

    /**
     * Get an instance of the HTTP connection object. Initializes
     * the connection if it is not already active.
     *
     * @return Connection
     */
    private static function connection()
    {
        if (!self::$connection) {
            self::$connection = new Connection();
            if (self::$client_id) {
                self::$connection->authenticateOauth(self::$client_id, self::$auth_token);
            } else {
                self::$connection->authenticateBasic(self::$username, self::$api_key);
            }
        }

        return self::$connection;
    }

    /**
     * Convenience method to return instance of the connection
     *
     * @return Connection
     */
    public static function getConnection()
    {
        return self::connection();
    }

    /**
     * Set the HTTP connection object. DANGER: This can screw up your Client!
     *
     * @param Connection $connection The connection to use
     */
    public static function setConnection(Connection $connection = null)
    {
        self::$connection = $connection;
    }

    /**
     * Get a collection result from the specified endpoint.
     *
     * @param string $path api endpoint
     * @param string $resource resource class to map individual items
     * @return mixed array|string mapped collection or XML string if useXml is true
     */
    public static function getCollection($path, $resource = 'Resource')
    {
        $response = self::connection()->get(self::$api_path . $path);

        return self::mapCollection($resource, $response);
    }

    /**
     * Get a resource entity from the specified endpoint.
     *
     * @param string $path api endpoint
     * @param string $resource resource class to map individual items
     * @return mixed Resource|string resource object or XML string if useXml is true
     */
    public static function getResource($path, $resource = 'Resource')
    {
        $response = self::connection()->get(self::$api_path . $path);

        return self::mapResource($resource, $response);
    }

    /**
     * Get a count value from the specified endpoint.
     *
     * @param string $path api endpoint
     * @return mixed int|string count value or XML string if useXml is true
     */
    public static function getCount($path)
    {
        $response = self::connection()->get(self::$api_path . $path);

        if ($response == false || is_string($response)) {
            return $response;
        }

        return $response->count;
    }

    /**
     * Send a post request to create a resource on the specified collection.
     *
     * @param string $path api endpoint
     * @param mixed $object object or XML string to create
     * @return mixed
     */
    public static function createResource($path, $object)
    {
        if (is_array($object)) {
            $object = (object)$object;
        }

        return self::connection()->post(self::$api_path . $path, $object);
    }

    /**
     * Send a put request to update the specified resource.
     *
     * @param string $path api endpoint
     * @param mixed $object object or XML string to update
     * @return mixed
     */
    public static function updateResource($path, $object)
    {
        if (is_array($object)) {
            $object = (object)$object;
        }

        return self::connection()->put(self::$api_path . $path, $object);
    }

    /**
     * Send a delete request to remove the specified resource.
     *
     * @param string $path api endpoint
     * @return mixed
     */
    public static function deleteResource($path)
    {
        return self::connection()->delete(self::$api_path . $path);
    }

    /**
     * Internal method to wrap items in a collection to resource classes.
     *
     * @param string $resource name of the resource class
     * @param array $object object collection
     * @return array
     */
    private static function mapCollection($resource, $object)
    {
        if ($object == false || is_string($object)) {
            return $object;
        }

        $baseResource = __NAMESPACE__ . '\\' . $resource;
        self::$resource = (class_exists($baseResource)) ? $baseResource : 'Bigcommerce\\Api\\Resources\\' . $resource;

        return array_map(array('self', 'mapCollectionObject'), $object);
    }

    /**
     * Callback for mapping collection objects resource classes.
     *
     * @param \stdClass $object
     * @return Resource
     */
    private static function mapCollectionObject($object)
    {
        $class = self::$resource;

        return new $class($object);
    }

    /**
     * Map a single object to a resource class.
     *
     * @param string $resource name of the resource class
     * @param \stdClass $object
     * @return Resource
     */
    private static function mapResource($resource, $object)
    {
        if ($object == false || is_string($object)) {
            return $object;
        }

        $baseResource = __NAMESPACE__ . '\\' . $resource;
        $class = (class_exists($baseResource)) ? $baseResource : 'Bigcommerce\\Api\\Resources\\' . $resource;

        return new $class($object);
    }

    /**
     * Map object representing a count to an integer value.
     *
     * @param \stdClass $object
     * @return int
     */
    private static function mapCount($object)
    {
        if ($object == false || is_string($object)) {
            return $object;
        }

        return $object->count;
    }

    /**
     * Swaps a temporary access code for a long expiry auth token.
     *
     * @param \stdClass $object
     * @return \stdClass
     */
    public static function getAuthToken($object)
    {
        $context = array_merge(array('grant_type' => 'authorization_code'), (array)$object);
        $connection = new Connection();

        return $connection->post(self::$login_url . '/oauth2/token', $context);
    }

    public static function getCustomerLoginToken($id, $redirectUrl = '', $requestIp = '')
    {
        if (empty(self::$client_secret)) {
            throw new Exception('Cannot sign customer login tokens without a client secret');
        }

        $payload = array(
            'iss' => self::$client_id,
            'iat' => time(),
            'jti' => bin2hex(random_bytes(32)),
            'operation' => 'customer_login',
            'store_hash' => self::$store_hash,
            'customer_id' => $id
        );

        if (!empty($redirectUrl)) {
            $payload['redirect_to'] = $redirectUrl;
        }

        if (!empty($requestIp)) {
            $payload['request_ip'] = $requestIp;
        }

        return JWT::encode($payload, self::$client_secret, 'HS256');
    }

    /**
     * Pings the time endpoint to test the connection to a store.
     *
     * @return \DateTime
     */
    public static function getTime()
    {
        $response = self::connection()->get(self::$api_path . '/time');

        if ($response == false || is_string($response)) {
            return $response;
        }

        return new \DateTime("@{$response->time}");
    }

    /**
     * Returns the default collection of products.
     *
     * @param array $filter
     * @return mixed array|string list of products or XML string if useXml is true
     */
    public static function getProducts($filter = array())
    {
        $filter = Filter::create($filter);
        return self::getCollection('/products' . $filter->toQuery(), 'Product');
    }

    /**
     * Gets collection of images for a product.
     *
     * @param int $id product id
     * @return mixed array|string list of products or XML string if useXml is true
     */
    public static function getProductImages($id)
    {
        return self::getCollection('/products/' . $id . '/images/', 'ProductImage');
    }

    /**
     * Gets collection of custom fields for a product.
     *
     * @param int $id product ID
     * @return array|string list of products or XML string if useXml is true
     */
    public static function getProductCustomFields($id)
    {
        return self::getCollection('/products/' . $id . '/customfields/', 'ProductCustomField');
    }

    /**
     * Returns a single custom field by given id
     * @param  int $product_id product id
     * @param  int $id custom field id
     * @return Resources\ProductCustomField|bool Returns ProductCustomField if exists, false if not exists
     */
    public static function getProductCustomField($product_id, $id)
    {
        return self::getResource('/products/' . $product_id . '/customfields/' . $id, 'ProductCustomField');
    }

    /**
     * Create a new custom field for a given product.
     *
     * @param int $product_id product id
     * @param mixed $object fields to create
     * @return Object Object with `id`, `product_id`, `name` and `text` keys
     */
    public static function createProductCustomField($product_id, $object)
    {
        return self::createResource('/products/' . $product_id . '/customfields', $object);
    }

    /**
     * Gets collection of reviews for a product.
     *
     * @param $id
     * @return mixed
     */
    public static function getProductReviews($id)
    {
        return self::getCollection('/products/' . $id . '/reviews/', 'ProductReview');
    }

    /**
     * Update the given custom field.
     *
     * @param int $product_id product id
     * @param int $id custom field id
     * @param mixed $object custom field to update
     * @return mixed
     */
    public static function updateProductCustomField($product_id, $id, $object)
    {
        return self::updateResource('/products/' . $product_id . '/customfields/' . $id, $object);
    }

    /**
     * Delete the given custom field.
     *
     * @param int $product_id product id
     * @param int $id custom field id
     * @return mixed
     */
    public static function deleteProductCustomField($product_id, $id)
    {
        return self::deleteResource('/products/' . $product_id . '/customfields/' . $id);
    }

    /**
     * Returns the total number of products in the collection.
     *
     * @param array $filter
     * @return int|string number of products or XML string if useXml is true
     */
    public static function getProductsCount($filter = array())
    {
        $filter = Filter::create($filter);
        return self::getCount('/products/count' . $filter->toQuery());
    }

    /**
     * Returns a single product resource by the given id.
     *
     * @param int $id product id
     * @return Resources\Product|string
     */
    public static function getProduct($id)
    {
        return self::getResource('/products/' . $id, 'Product');
    }

    /**
     * Create a new product.
     *
     * @param mixed $object fields to create
     * @return mixed
     */
    public static function createProduct($object)
    {
        return self::createResource('/products', $object);
    }

    /**
     * Update the given product.
     *
     * @param int $id product id
     * @param mixed $object fields to update
     * @return mixed
     */
    public static function updateProduct($id, $object)
    {
        return self::updateResource('/products/' . $id, $object);
    }

    /**
     * Delete the given product.
     *
     * @param int $id product id
     * @return mixed
     */
    public static function deleteProduct($id)
    {
        return self::deleteResource('/products/' . $id);
    }

    /**
     * Delete all products.
     *
     * @return mixed
     */
    public static function deleteAllProducts()
    {
        return self::deleteResource('/products');
    }

    /**
     * Return the collection of options.
     *
     * @param array $filter
     * @return array
     */
    public static function getOptions($filter = array())
    {
        $filter = Filter::create($filter);
        return self::getCollection('/options' . $filter->toQuery(), 'Option');
    }

    /**
     * Create Options
     * @param $object
     * @return mixed
     */
    public static function createOption($object)
    {
        return self::createResource('/options', $object);
    }

    /**
     * Update the given option.
     *
     * @param int $id category id
     * @param mixed $object
     * @return mixed
     */
    public static function updateOption($id, $object)
    {
        return self::updateResource('/options/' . $id, $object);
    }

    /**
     * Return the number of options in the collection
     *
     * @return int
     */
    public static function getOptionsCount()
    {
        return self::getCount('/options/count');
    }

    /**
     * Return a single option by given id.
     *
     * @param int $id option id
     * @return Resources\Option
     */
    public static function getOption($id)
    {
        return self::getResource('/options/' . $id, 'Option');
    }

    /**
     * Delete the given option.
     *
     * @param int $id option id
     * @return mixed
     */
    public static function deleteOption($id)
    {
        return self::deleteResource('/options/' . $id);
    }

    /**
     * Return a single value for an option.
     *
     * @param int $option_id option id
     * @param int $id value id
     * @return Resources\OptionValue
     */
    public static function getOptionValue($option_id, $id)
    {
        return self::getResource('/options/' . $option_id . '/values/' . $id, 'OptionValue');
    }

    /**
     * Return the collection of all option values.
     *
     * @param array $filter
     * @return array
     */
    public static function getOptionValues($filter = array())
    {
        $filter = Filter::create($filter);
        return self::getCollection('/options/values' . $filter->toQuery(), 'OptionValue');
    }

    /**
     * The collection of categories.
     *
     * @param array $filter
     * @return array
     */
    public static function getCategories($filter = array())
    {
        $filter = Filter::create($filter);
        return self::getCollection('/categories' . $filter->toQuery(), 'Category');
    }

    /**
     * The number of categories in the collection.
     *
     * @param array $filter
     * @return int
     */
    public static function getCategoriesCount($filter = array())
    {
        $filter = Filter::create($filter);
        return self::getCount('/categories/count' . $filter->toQuery());
    }

    /**
     * A single category by given id.
     *
     * @param int $id category id
     * @return Resources\Category
     */
    public static function getCategory($id)
    {
        return self::getResource('/categories/' . $id, 'Category');
    }

    /**
     * Create a new category from the given data.
     *
     * @param mixed $object
     * @return mixed
     */
    public static function createCategory($object)
    {
        return self::createResource('/categories', $object);
    }

    /**
     * Update the given category.
     *
     * @param int $id category id
     * @param mixed $object
     * @return mixed
     */
    public static function updateCategory($id, $object)
    {
        return self::updateResource('/categories/' . $id, $object);
    }

    /**
     * Delete the given category.
     *
     * @param int $id category id
     * @return mixed
     */
    public static function deleteCategory($id)
    {
        return self::deleteResource('/categories/' . $id);
    }

    /**
     * Delete all categories.
     *
     * @return mixed
     */
    public static function deleteAllCategories()
    {
        return self::deleteResource('/categories');
    }

    /**
     * The collection of brands.
     *
     * @param array $filter
     * @return array
     */
    public static function getBrands($filter = array())
    {
        $filter = Filter::create($filter);
        return self::getCollection('/brands' . $filter->toQuery(), 'Brand');
    }

    /**
     * The total number of brands in the collection.
     *
     * @param array $filter
     * @return int
     */
    public static function getBrandsCount($filter = array())
    {
        $filter = Filter::create($filter);
        return self::getCount('/brands/count' . $filter->toQuery());
    }

    /**
     * A single brand by given id.
     *
     * @param int $id brand id
     * @return Resources\Brand
     */
    public static function getBrand($id)
    {
        return self::getResource('/brands/' . $id, 'Brand');
    }

    /**
     * Create a new brand from the given data.
     *
     * @param mixed $object
     * @return mixed
     */
    public static function createBrand($object)
    {
        return self::createResource('/brands', $object);
    }

    /**
     * Update the given brand.
     *
     * @param int $id brand id
     * @param mixed $object
     * @return mixed
     */
    public static function updateBrand($id, $object)
    {
        return self::updateResource('/brands/' . $id, $object);
    }

    /**
     * Delete the given brand.
     *
     * @param int $id brand id
     * @return mixed
     */
    public static function deleteBrand($id)
    {
        return self::deleteResource('/brands/' . $id);
    }

    /**
     * Delete all brands.
     *
     * @return mixed
     */
    public static function deleteAllBrands()
    {
        return self::deleteResource('/brands');
    }

    /**
     * The collection of orders.
     *
     * @param array $filter
     * @return array
     */
    public static function getOrders($filter = array())
    {
        $filter = Filter::create($filter);
        return self::getCollection('/orders' . $filter->toQuery(), 'Order');
    }

    /**
     * The number of orders in the collection.
     *
     * @param array $filter
     * @return int
     */
    public static function getOrdersCount($filter = array())
    {
        $filter = Filter::create($filter);
        return self::getCount('/orders/count' . $filter->toQuery());
    }

    /**
     * The order count grouped by order status
     *
     * @param array $filter
     * @return Resources\OrderStatus
     */
    public static function getOrderStatusesWithCounts($filter = array())
    {
        $filter = Filter::create($filter);
        $resource = self::getResource('/orders/count' . $filter->toQuery(), "OrderStatus");
        return $resource->statuses;
    }

    /**
     * A single order.
     *
     * @param int $id order id
     * @return Resources\Order
     */
    public static function getOrder($id)
    {
        return self::getResource('/orders/' . $id, 'Order');
    }

    /**
     * @param $orderID
     * @return mixed
     */
    public static function getOrderProducts($orderID)
    {
        return self::getCollection('/orders/' . $orderID . '/products', 'OrderProduct');
    }

    /**
     * The total number of order products in the collection.
     *
     * @param $orderID
     * @param array $filter
     * @return mixed
     */
    public static function getOrderProductsCount($orderID, $filter = array())
    {
        $filter = Filter::create($filter);
        return self::getCount('/orders/' . $orderID . '/products/count' . $filter->toQuery());
    }

    /**
     * Delete the given order (unlike in the Control Panel, this will permanently
     * delete the order).
     *
     * @param int $id order id
     * @return mixed
     */
    public static function deleteOrder($id)
    {
        return self::deleteResource('/orders/' . $id);
    }

    /**
     * Delete all orders.
     *
     * @return mixed
     */
    public static function deleteAllOrders()
    {
        return self::deleteResource('/orders');
    }

    /**
     * Create an order
     *
     * @param $object
     * @return mixed
     */
    public static function createOrder($object)
    {
        return self::createResource('/orders', $object);
    }

    /**
     * Update the given order.
     *
     * @param int $id order id
     * @param mixed $object fields to update
     * @return mixed
     */
    public static function updateOrder($id, $object)
    {
        return self::updateResource('/orders/' . $id, $object);
    }

    /**
     * The list of customers.
     *
     * @param array $filter
     * @return array
     */
    public static function getCustomers($filter = array())
    {
        $filter = Filter::create($filter);
        return self::getCollection('/customers' . $filter->toQuery(), 'Customer');
    }

    /**
     * The total number of customers in the collection.
     *
     * @param array $filter
     * @return int
     */
    public static function getCustomersCount($filter = array())
    {
        $filter = Filter::create($filter);
        return self::getCount('/customers/count' . $filter->toQuery());
    }

    /**
     * Bulk delete customers.
     *
     * @param array $filter
     * @return array
     */
    public static function deleteCustomers($filter = array())
    {
        $filter = Filter::create($filter);
        return self::deleteResource('/customers' . $filter->toQuery());
    }

    /**
     * A single customer by given id.
     *
     * @param int $id customer id
     * @return Resources\Customer
     */
    public static function getCustomer($id)
    {
        return self::getResource('/customers/' . $id, 'Customer');
    }

    /**
     * Create a new customer from the given data.
     *
     * @param mixed $object
     * @return mixed
     */
    public static function createCustomer($object)
    {
        return self::createResource('/customers', $object);
    }

    /**
     * Update the given customer.
     *
     * @param int $id customer id
     * @param mixed $object
     * @return mixed
     */
    public static function updateCustomer($id, $object)
    {
        return self::updateResource('/customers/' . $id, $object);
    }

    /**
     * Delete the given customer.
     *
     * @param int $id customer id
     * @return mixed
     */
    public static function deleteCustomer($id)
    {
        return self::deleteResource('/customers/' . $id);
    }

    /**
     * A list of addresses belonging to the given customer.
     *
     * @param int $id customer id
     * @return array
     */
    public static function getCustomerAddresses($id)
    {
        return self::getCollection('/customers/' . $id . '/addresses', 'Address');
    }

    /**
     * Returns the collection of option sets.
     *
     * @param array $filter
     * @return array
     */
    public static function getOptionSets($filter = array())
    {
        $filter = Filter::create($filter);
        return self::getCollection('/optionsets' . $filter->toQuery(), 'OptionSet');
    }

    /**
     * Create Optionsets
     *
     * @param $object
     * @return mixed
     */
    public static function createOptionSet($object)
    {
        return self::createResource('/optionsets', $object);
    }

    /**
     * Create Option Set Options
     *
     * @param $object
     * @param $id
     * @return mixed
     */
    public static function createOptionSetOption($object, $id)
    {
        return self::createResource('/optionsets/' . $id . '/options', $object);
    }

    /**
     * Returns the total number of option sets in the collection.
     *
     * @return int
     */
    public static function getOptionSetsCount()
    {
        return self::getCount('/optionsets/count');
    }

    /**
     * A single option set by given id.
     *
     * @param int $id option set id
     * @return Resources\OptionSet
     */
    public static function getOptionSet($id)
    {
        return self::getResource('/optionsets/' . $id, 'OptionSet');
    }

    /**
     * Update the given option set.
     *
     * @param int $id option set id
     * @param mixed $object
     * @return mixed
     */
    public static function updateOptionSet($id, $object)
    {
        return self::updateResource('/optionsets/' . $id, $object);
    }

    /**
     * Delete the given option set.
     *
     * @param int $id option id
     * @return mixed
     */
    public static function deleteOptionSet($id)
    {
        Client::deleteResource('/optionsets/' . $id);
    }

    /**
     * Status code used to represent the state of an order.
     *
     * @param int $id order status id
     *
     * @return mixed
     */
    public static function getOrderStatus($id)
    {
        return self::getResource('/order_statuses/' . $id, 'OrderStatus');
    }

    /**
     * Status codes used to represent the state of an order.
     *
     * @return array
     */
    public static function getOrderStatuses()
    {
        return self::getCollection('/order_statuses', 'OrderStatus');
    }

    /**
     * Get collection of product skus
     *
     * @param array $filter
     * @return mixed
     */
    public static function getSkus($filter = array())
    {
        $filter = Filter::create($filter);
        return self::getCollection('/products/skus' . $filter->toQuery(), 'Sku');
    }

    /**
     * Create a SKU
     *
     * @param $productId
     * @param $object
     * @return mixed
     */
    public static function createSku($productId, $object)
    {
        return self::createResource('/products/' . $productId . '/skus', $object);
    }

    /**
     * Update sku
     *
     * @param $id
     * @param $object
     * @return mixed
     */
    public static function updateSku($id, $object)
    {
        return self::updateResource('/product/skus/' . $id, $object);
    }

    /**
     * Returns the total number of SKUs in the collection.
     *
     * @return int
     */
    public static function getSkusCount()
    {
        return self::getCount('/products/skus/count');
    }

    /**
     * Get a single coupon by given id.
     *
     * @param int $id customer id
     * @return Resources\Coupon
     */
    public static function getCoupon($id)
    {
        return self::getResource('/coupons/' . $id, 'Coupon');
    }

    /**
     * Get coupons
     *
     * @param array $filter
     * @return mixed
     */
    public static function getCoupons($filter = array())
    {
        $filter = Filter::create($filter);
        return self::getCollection('/coupons' . $filter->toQuery(), 'Coupon');
    }

    /**
     * Create coupon
     *
     * @param $object
     * @return mixed
     */
    public static function createCoupon($object)
    {
        return self::createResource('/coupons', $object);
    }

    /**
     * Update coupon
     *
     * @param $id
     * @param $object
     * @return mixed
     */
    public static function updateCoupon($id, $object)
    {
        return self::updateResource('/coupons/' . $id, $object);
    }

    /**
     * Delete the given coupon.
     *
     * @param int $id coupon id
     * @return mixed
     */
    public static function deleteCoupon($id)
    {
        return self::deleteResource('/coupons/' . $id);
    }

    /**
     * Delete all Coupons.
     *
     * @return mixed
     */
    public static function deleteAllCoupons()
    {
        return self::deleteResource('/coupons');
    }

    /**
     * Return the number of coupons
     *
     * @return int
     */
    public static function getCouponsCount()
    {
        return self::getCount('/coupons/count');
    }

    /**
     * The request logs with usage history statistics.
     */
    public static function getRequestLogs()
    {
        return self::getCollection('/requestlogs', 'RequestLog');
    }

    public static function getStore()
    {
        $response = self::connection()->get(self::$api_path . '/store');
        return $response;
    }

    /**
     * The number of requests remaining at the current time. Based on the
     * last request that was fetched within the current script. If no
     * requests have been made, pings the time endpoint to get the value.
     *
     * @return int
     */
    public static function getRequestsRemaining()
    {
        $limit = self::connection()->getHeader('X-BC-ApiLimit-Remaining');

        if (!$limit) {
            $result = self::getTime();

            if (!$result) {
                return false;
            }

            $limit = self::connection()->getHeader('X-BC-ApiLimit-Remaining');
        }

        return (int)$limit;
    }

    /**
     * Get a single shipment by given id.
     *
     * @param $orderID
     * @param $shipmentID
     * @return mixed
     */
    public static function getShipment($orderID, $shipmentID)
    {
        return self::getResource('/orders/' . $orderID . '/shipments/' . $shipmentID, 'Shipment');
    }

    /**
     * Get shipments for a given order
     *
     * @param $orderID
     * @param array $filter
     * @return mixed
     */
    public static function getShipments($orderID, $filter = array())
    {
        $filter = Filter::create($filter);
        return self::getCollection('/orders/' . $orderID . '/shipments' . $filter->toQuery(), 'Shipment');
    }

    /**
     * Create shipment
     *
     * @param $orderID
     * @param $object
     * @return mixed
     */
    public static function createShipment($orderID, $object)
    {
        return self::createResource('/orders/' . $orderID . '/shipments', $object);
    }

    /**
     * Update shipment
     *
     * @param $orderID
     * @param $shipmentID
     * @param $object
     * @return mixed
     */
    public static function updateShipment($orderID, $shipmentID, $object)
    {
        return self::updateResource('/orders/' . $orderID . '/shipments/' . $shipmentID, $object);
    }

    /**
     * Delete the given shipment.
     *
     * @param $orderID
     * @param $shipmentID
     * @return mixed
     */
    public static function deleteShipment($orderID, $shipmentID)
    {
        return self::deleteResource('/orders/' . $orderID . '/shipments/' . $shipmentID);
    }

    /**
     * Delete all Shipments for the given order.
     *
     * @param $orderID
     * @return mixed
     */
    public static function deleteAllShipmentsForOrder($orderID)
    {
        return self::deleteResource('/orders/' . $orderID . '/shipments');
    }

    /**
     * Get a single order shipping address by given order and order shipping address id.
     *
     * @param $orderID
     * @param $orderShippingAddressID
     * @return mixed
     */
    public static function getOrderShippingAddress($orderID, $orderShippingAddressID)
    {
        return self::getResource('/orders/' . $orderID . '/shipping_addresses/' . $orderShippingAddressID, 'Address');
    }

    /**
     * Get order shipping addresses for a given order
     *
     * @param $orderID
     * @param array $filter
     * @return mixed
     */
    public static function getOrderShippingAddresses($orderID, $filter = array())
    {
        $filter = Filter::create($filter);
        return self::getCollection('/orders/' . $orderID . '/shipping_addresses' . $filter->toQuery(), 'Address');
    }

    /**
     * Create a new currency.
     *
     * @param mixed $object fields to create
     * @return mixed
     */
    public static function createCurrency($object)
    {
        return self::createResource('/currencies', $object);
    }

    /**
     * Returns a single currency resource by the given id.
     *
     * @param int $id currency id
     * @return Resources\Currency|string
     */
    public static function getCurrency($id)
    {
        return self::getResource('/currencies/' . $id, 'Currency');
    }

    /**
     * Update the given currency.
     *
     * @param int $id currency id
     * @param mixed $object fields to update
     * @return mixed
     */
    public static function updateCurrency($id, $object)
    {
        return self::updateResource('/currencies/' . $id, $object);
    }

    /**
     * Delete the given currency.
     *
     * @param int $id currency id
     * @return mixed
     */
    public static function deleteCurrency($id)
    {
        return self::deleteResource('/currencies/' . $id);
    }

    /**
     * Returns the default collection of currencies.
     *
     * @param array $filter
     * @return mixed array|string list of currencies or XML string if useXml is true
     */
    public static function getCurrencies($filter = array())
    {
        $filter = Filter::create($filter);
        return self::getCollection('/currencies' . $filter->toQuery(), 'Currency');
    }

    /**
     * Create a new product image.
     *
     * @param string $productId
     * @param mixed $object
     * @return mixed
     */
    public static function createProductImage($productId, $object)
    {
        return self::createResource('/products/' . $productId . '/images', $object);
    }

    /**
     * Update a product image.
     *
     * @param string $productId
     * @param string $imageId
     * @param mixed $object
     * @return mixed
     */
    public static function updateProductImage($productId, $imageId, $object)
    {
        return self::updateResource('/products/' . $productId . '/images/' . $imageId, $object);
    }

    /**
     * Returns a product image resource by the given product id.
     *
     * @param int $productId
     * @param int $imageId
     * @return Resources\ProductImage|string
     */
    public static function getProductImage($productId, $imageId)
    {
        return self::getResource('/products/' . $productId . '/images/' . $imageId, 'ProductImage');
    }

    /**
     * Delete the given product image.
     *
     * @param int $productId
     * @param int $imageId
     * @return mixed
     */
    public static function deleteProductImage($productId, $imageId)
    {
        return self::deleteResource('/products/' . $productId . '/images/' . $imageId);
    }

    /**
     * Get all content pages
     *
     * @return mixed
     */
    public static function getPages()
    {
        return self::getCollection('/pages', 'Page');
    }

    /**
     * Get single content pages
     *
     * @param int $pageId
     * @return mixed
     */
    public static function getPage($pageId)
    {
        return self::getResource('/pages/' . $pageId, 'Page');
    }

    /**
     * Create a new content pages
     *
     * @param $object
     * @return mixed
     */
    public static function createPage($object)
    {
        return self::createResource('/pages', $object);
    }

    /**
     * Update an existing content page
     *
     * @param int $pageId
     * @param $object
     * @return mixed
     */
    public static function updatePage($pageId, $object)
    {
        return self::updateResource('/pages/' . $pageId, $object);
    }

    /**
     * Delete an existing content page
     *
     * @param int $pageId
     * @return mixed
     */
    public static function deletePage($pageId)
    {
        return self::deleteResource('/pages/' . $pageId);
    }

    /**
     * Create a Gift Certificate
     *
     * @param array $object
     * @return mixed
     */
    public static function createGiftCertificate($object)
    {
        return self::createResource('/gift_certificates', $object);
    }

    /**
     * Get a Gift Certificate
     *
     * @param int $giftCertificateId
     * @return mixed
     */
    public static function getGiftCertificate($giftCertificateId)
    {
        return self::getResource('/gift_certificates/' . $giftCertificateId);
    }

    /**
     * Return the collection of all gift certificates.
     *
     * @param array $filter
     * @return mixed
     */
    public static function getGiftCertificates($filter = array())
    {
        $filter = Filter::create($filter);
        return self::getCollection('/gift_certificates' . $filter->toQuery());
    }

    /**
     * Update a Gift Certificate
     *
     * @param int $giftCertificateId
     * @param array $object
     * @return mixed
     */
    public static function updateGiftCertificate($giftCertificateId, $object)
    {
        return self::updateResource('/gift_certificates/' . $giftCertificateId, $object);
    }

    /**
     * Delete a Gift Certificate
     *
     * @param int $giftCertificateId
     * @return mixed
     */
    public static function deleteGiftCertificate($giftCertificateId)
    {
        return self::deleteResource('/gift_certificates/' . $giftCertificateId);
    }

    /**
     * Delete all Gift Certificates
     *
     * @return mixed
     */
    public static function deleteAllGiftCertificates()
    {
        return self::deleteResource('/gift_certificates');
    }

    /**
     * Create Product Review
     *
     * @param int $productId
     * @param array $object
     * @return mixed
     */
    public static function createProductReview($productId, $object)
    {
        return self::createResource('/products/' . $productId . '/reviews', $object);
    }

    /**
     * Create Product Bulk Discount rules
     *
     * @param string $productId
     * @param array $object
     * @return mixed
     */
    public static function createProductBulkPricingRules($productId, $object)
    {
        return self::createResource('/products/' . $productId . '/discount_rules', $object);
    }

    /**
     * Create a Marketing Banner
     *
     * @param array $object
     * @return mixed
     */
    public static function createMarketingBanner($object)
    {
        return self::createResource('/banners', $object);
    }

    /**
     * Get all Marketing Banners
     *
     * @return mixed
     */
    public static function getMarketingBanners()
    {
        return self::getCollection('/banners');
    }

    /**
     * Delete all Marketing Banners
     *
     * @return mixed
     */
    public static function deleteAllMarketingBanners()
    {
        return self::deleteResource('/banners');
    }

    /**
     * Delete a specific Marketing Banner
     *
     * @param int $bannerID
     * @return mixed
     */
    public static function deleteMarketingBanner($bannerID)
    {
        return self::deleteResource('/banners/' . $bannerID);
    }

    /**
     * Update an existing banner
     *
     * @param int $bannerID
     * @param array $object
     * @return mixed
     */
    public static function updateMarketingBanner($bannerID, $object)
    {
        return self::updateResource('/banners/' . $bannerID, $object);
    }

    /**
     * Add a address to the customer's address book.
     *
     * @param int $customerID
     * @param array $object
     * @return mixed
     */
    public static function createCustomerAddress($customerID, $object)
    {
        return self::createResource('/customers/' . $customerID . '/addresses', $object);
    }

    /**
     * Create a product rule
     *
     * @param int $productID
     * @param array $object
     * @return mixed
     */
    public static function createProductRule($productID, $object)
    {
        return self::createResource('/products/' . $productID . '/rules', $object);
    }

    /**
     * Create a customer group.
     *
     * @param array $object
     * @return mixed
     */
    public static function createCustomerGroup($object)
    {
        return self::createResource('/customer_groups', $object);
    }

    /**
     * Get list of customer groups
     *
     * @return mixed
     */
    public static function getCustomerGroups()
    {
        return self::getCollection('/customer_groups');
    }

    /**
     * Delete a customer group
     *
     * @param int $customerGroupId
     * @return mixed
     */
    public static function deleteCustomerGroup($customerGroupId)
    {
        return self::deleteResource('/customer_groups/' . $customerGroupId);
    }

    /**
     * Delete all customers
     *
     * @return mixed
     */
    public static function deleteAllCustomers()
    {
        return self::deleteResource('/customers');
    }

    /**
     * Delete all options
     *
     * @return mixed
     */
    public static function deleteAllOptions()
    {
        return self::deleteResource('/options');
    }

    /**
     * Return the collection of all option values for a given option.
     *
     * @param int $productId
     * @return mixed
     */
    public static function getProductOptions($productId)
    {
        return self::getCollection('/products/' . $productId . '/options');
    }

    /**
     * Return the collection of all option values for a given option.
     *
     * @param int $productId
     * @param int $productOptionId
     * @return mixed
     */
    public static function getProductOption($productId, $productOptionId)
    {
        return self::getResource('/products/' . $productId . '/options/' . $productOptionId);
    }

    /**
     * Return the collection of all option values for a given option.
     *
     * @param int $productId
     * @param int $productRuleId
     * @return mixed
     */
    public static function getProductRule($productId, $productRuleId)
    {
        return self::getResource('/products/' . $productId . '/rules/' . $productRuleId);
    }

    /**
     * Return the option value object that was created.
     *
     * @param int $optionId
     * @param array $object
     * @return mixed
     */
    public static function createOptionValue($optionId, $object)
    {
        return self::createResource('/options/' . $optionId . '/values', $object);
    }

    /**
     * Delete all option sets that were created.
     *
     * @return mixed
     */
    public static function deleteAllOptionSets()
    {
        return self::deleteResource('/optionsets');
    }

    /**
     * Return the option value object that was updated.
     *
     * @param int $optionId
     * @param int $optionValueId
     * @param array $object
     * @return mixed
     */
    public static function updateOptionValue($optionId, $optionValueId, $object)
    {
        return self::updateResource(
            '/options/' . $optionId . '/values/' . $optionValueId,
            $object
        );
    }

    /**
     * Returns all webhooks.
     *
     * @return mixed Resource|string resource object or XML string if useXml is true
     */
    public static function listWebhooks()
    {
        return self::getCollection('/hooks');
    }

    /**
     * Returns data for a specific web-hook.
     *
     * @param int $id
     * @return mixed Resource|string resource object or XML string if useXml is true
     */
    public static function getWebhook($id)
    {
        return self::getResource('/hooks/' . $id);
    }

    /**
     * Creates a web-hook.
     *
     * @param mixed $object object or XML string to create
     * @return mixed
     */
    public static function createWebhook($object)
    {
        return self::createResource('/hooks', $object);
    }

    /**
     * Updates the given webhook.
     *
     * @param int $id
     * @param mixed $object object or XML string to create
     * @return mixed
     */
    public static function updateWebhook($id, $object)
    {
        return self::updateResource('/hooks/' . $id, $object);
    }

    /**
     * Delete the given webhook.
     *
     * @param int $id
     * @return mixed
     */
    public static function deleteWebhook($id)
    {
        return self::deleteResource('/hooks/' . $id);
    }

    /**
     * Return a collection of shipping-zones
     *
     * @return mixed
     */
    public static function getShippingZones()
    {
        return self::getCollection('/shipping/zones/', 'ShippingZone');
    }

    /**
     * Return a shipping-zone by id
     *
     * @param int $id shipping-zone id
     * @return mixed
     */
    public static function getShippingZone($id)
    {
        return self::getResource('/shipping/zones/' . $id, 'ShippingZone');
    }

    /**
     * Delete the given shipping-zone
     *
     * @param int $id shipping-zone id
     * @return mixed
     */
    public static function deleteShippingZone($id)
    {
        return self::deleteResource('/shipping/zones/' . $id);
    }

    /**
     * Return a shipping-method by id
     *
     * @param $zoneId
     * @param $methodId
     * @return mixed
     */
    public static function getShippingMethod($zoneId, $methodId)
    {
        return self::getResource('/shipping/zones/'. $zoneId . '/methods/'. $methodId, 'ShippingMethod');
    }

    /**
     * Return a collection of shipping-methods
     *
     * @param $zoneId
     * @return mixed
     */
    public static function getShippingMethods($zoneId)
    {
        return self::getCollection('/shipping/zones/' . $zoneId . '/methods', 'ShippingMethod');
    }

    /**
     * Delete the given shipping-method by id
     *
     * @param $zoneId
     * @param $methodId
     * @return mixed
     */
    public static function deleteShippingMethod($zoneId, $methodId)
    {
        return self::deleteResource('/shipping/zones/'. $zoneId . '/methods/'. $methodId);
    }
}


text:
@interface UIImage (QDColor)

+ (UIImage *)imageWithColor:(UIColor *)color width:(double)width height:(double)height;

@end

redpajama_set_name: RedPajamaGithub


text:
<!-->
	<Recipe timeRequired="NUMBER" power="NUMBER">
		<input>
			<fluidStack>FLUID NAME SIZE</fluidStack>
			<itemStack>ITEM_NAME SIZE META</itemStack>
			<oreDict>OREDICT_NAME SIZE</oreDict>
        </input>
		<output>
			<fluidStack>FLUID_NAME SIZE</fluidStack>
			<itemStack>ITEM_NAME SIZE META</itemStack>
			<oreDict>OREDICT_NAME SIZE</oreDict>
		</output>
	</Recipe>

	Can have Multiple In/Outputs
	Some Machines can only Accept either Fluids or Items

	timeRequired="NUMBER"	how long a Recipe takes, Unit is in Ticks.
	power="NUMBER" how much Power the Recipes takes per Tick. Unit is in RF.

	The "useDefault" attribute will prevent loading of recipes if set to "false"
<!-->
<Recipes useDefault="true">
	<Recipe timeRequired="100" power ="1">
		<input>
			<oreDict>sheetIron</oreDict>
			<oreDict>sheetIron</oreDict>
		</input>
		<output>
			<itemStack>advancedRocketry:pressureTank</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="200" power ="2">
		<input>
			<oreDict>sheetSteel</oreDict>
			<oreDict>sheetSteel</oreDict>
		</input>
		<output>
			<itemStack>advancedRocketry:pressureTank 1 1</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="100" power ="1">
		<input>
			<oreDict>sheetAluminum</oreDict>
			<oreDict>sheetAluminum</oreDict>
		</input>
		<output>
			<itemStack>advancedRocketry:pressureTank 1 2</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="1000" power ="8">
		<input>
			<oreDict>sheetTitanium</oreDict>
			<oreDict>sheetTitanium</oreDict>
		</input>
		<output>
			<itemStack>advancedRocketry:pressureTank 1 3</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="200">
		<input>
			<oreDict>plateIron</oreDict>
		</input>
		<output>
			<itemStack>libVulpes:libVulpesproductsheet 1 1</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="200">
		<input>
			<oreDict>plateCopper</oreDict>
		</input>
		<output>
			<itemStack>libVulpes:libVulpesproductsheet 1 4</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="200">
		<input>
			<oreDict>plateSteel</oreDict>
		</input>
		<output>
			<itemStack>libVulpes:libVulpesproductsheet 1 6</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="200">
		<input>
			<oreDict>plateTitanium</oreDict>
		</input>
		<output>
			<itemStack>libVulpes:libVulpesproductsheet 1 7</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="200">
		<input>
			<oreDict>plateAluminum</oreDict>
		</input>
		<output>
			<itemStack>libVulpes:libVulpesproductsheet 1 9</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="200">
		<input>
			<oreDict>plateTitaniumAluminide</oreDict>
		</input>
		<output>
			<itemStack>advancedRocketry:advancedRocketryproductsheet</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="200">
		<input>
			<oreDict>plateTitaniumIridium</oreDict>
		</input>
		<output>
			<itemStack>advancedRocketry:advancedRocketryproductsheet 1 1</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotBatteryAlloy</oreDict>
		</input>
		<output>
			<itemStack>techreborn:plates 1 1</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotRedstoneAlloy</oreDict>
		</input>
		<output>
			<itemStack>techreborn:plates 1 24</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotAluminum</oreDict>
		</input>
		<output>
			<itemStack>libVulpes:libVulpesproductplate 1 9</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotObsidianSteel</oreDict>
		</input>
		<output>
			<itemStack>Techguns:TechgunsAmmo 1 65</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotTitanium</oreDict>
		</input>
		<output>
			<itemStack>libVulpes:libVulpesproductplate 1 7</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotCopper</oreDict>
		</input>
		<output>
			<itemStack>libVulpes:libVulpesproductplate 1 4</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotBronze</oreDict>
		</input>
		<output>
			<itemStack>IC2:itemPlates 1 2</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotGold</oreDict>
		</input>
		<output>
			<itemStack>libVulpes:libVulpesproductplate 1 2</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotAluminium</oreDict>
		</input>
		<output>
			<itemStack>techreborn:plates</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotSilver</oreDict>
		</input>
		<output>
			<itemStack>techreborn:plates 1 28</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotIridium</oreDict>
		</input>
		<output>
			<itemStack>libVulpes:libVulpesproductplate 1 10</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotMagnalium</oreDict>
		</input>
		<output>
			<itemStack>techreborn:plates 1 17</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotTungstensteel</oreDict>
		</input>
		<output>
			<itemStack>techreborn:plates 1 34</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotBrass 4</oreDict>
		</input>
		<output>
			<itemStack>techreborn:plates 1 2</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotIron</oreDict>
		</input>
		<output>
			<itemStack>libVulpes:libVulpesproductplate 1 1</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotPlatinum</oreDict>
		</input>
		<output>
			<itemStack>techreborn:plates 1 22</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotTungsten</oreDict>
		</input>
		<output>
			<itemStack>techreborn:plates 1 33</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotLead</oreDict>
		</input>
		<output>
			<itemStack>IC2:itemPlates 1 6</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotChrome</oreDict>
		</input>
		<output>
			<itemStack>techreborn:plates 1 5</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotSilicon</oreDict>
		</input>
		<output>
			<itemStack>libVulpes:libVulpesproductplate 1 3</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotTitaniumAluminide</oreDict>
		</input>
		<output>
			<itemStack>advancedRocketry:advancedRocketryproductplate</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotSteel</oreDict>
		</input>
		<output>
			<itemStack>libVulpes:libVulpesproductplate 1 6</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotAlloy</oreDict>
		</input>
		<output>
			<itemStack>Eln:Eln.sharedItem 1 7691</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotCarbon</oreDict>
		</input>
		<output>
			<itemStack>Techguns:TechgunsAmmo 1 62</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotElectrum</oreDict>
		</input>
		<output>
			<itemStack>techreborn:plates 1 9</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotOsmium</oreDict>
		</input>
		<output>
			<itemStack>techreborn:plates 1 20</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotZinc</oreDict>
		</input>
		<output>
			<itemStack>techreborn:plates 1 36</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotTin</oreDict>
		</input>
		<output>
			<itemStack>libVulpes:libVulpesproductplate 1 5</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotInvar</oreDict>
		</input>
		<output>
			<itemStack>techreborn:plates 1 12</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotNickel</oreDict>
		</input>
		<output>
			<itemStack>techreborn:plates 1 18</itemStack>
		</output>
	</Recipe>
	<Recipe timeRequired="300" power ="20">
		<input>
			<oreDict>ingotTitaniumIridium</oreDict>
		</input>
		<output>
			<itemStack>advancedRocketry:advancedRocketryproductplate 1 1</itemStack>
		</output>
	</Recipe>
</Recipes>


text:
############################################################################################################################################
#Script that allows to create a SharePoint Group in a SharePoint Online Site
# Required Parameters:
#  -> $sUserName: User Name to connect to the SharePoint Online Site Collection.
#  -> $sPassword: Password for the user.
#  -> $sSiteCollectionUrl: SharePoint Online Site
#  -> $sGroupToCreate: SPO Group to create
#  -> $sGroupToCreateDescription: SPO Group description
############################################################################################################################################

$host.Runspace.ThreadOptions = "ReuseThread"

#Definition of the function that allows to create a SharePoint Group in a SharePoint Online Site
function Create-SPOGroup
{
    param ($sSiteColUrl,$sUsername,$sPassword,$sGroupToCreate,$sGroupToCreateDescription)
    try
    {
        Write-Host "----------------------------------------------------------------------------"  -foregroundcolor Green
        Write-Host "Creating SharePoint Group $sGroupToCreate in $sSiteColUrl" -foregroundcolor Green
        Write-Host "----------------------------------------------------------------------------"  -foregroundcolor Green

        #Adding the Client OM Assemblies
        Add-Type -Path "<CSOM_Path>\Microsoft.SharePoint.Client.dll"
        Add-Type -Path "<CSOM_Path>\Microsoft.SharePoint.Client.Runtime.dll"

        #SPO Client Object Model Context
        $spoCtx = New-Object Microsoft.SharePoint.Client.ClientContext($sSiteColUrl)
        $spoCredentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($sUsername, $sPassword)
        $spoCtx.Credentials = $spoCredentials

        #Root Web Site
        $spoRootWebSite = $spoCtx.Web
        #Object for creating a new SPO Group
        $spoGroupCreationInfo=New-Object Microsoft.SharePoint.Client.GroupCreationInformation
        $spoGroupCreationInfo.Title=$sGroupToCreate
        $spoGroupCreationInfo.Description=$sGroupToCreateDescription
        $spoGroup=$spoRootWebSite.SiteGroups.Add($spoGroupCreationInfo)
        $spoCtx.ExecuteQuery()

        Write-Host "----------------------------------------------------------------------------"  -foregroundcolor Green
        Write-Host "SharePoint Group $sGroupToCreate in $sSiteColUrl created succesfully!!" -foregroundcolor Green
        Write-Host "----------------------------------------------------------------------------"  -foregroundcolor Green
        $spoCtx.Dispose()
    }
    catch [System.Exception]
    {
        write-host -f red $_.Exception.ToString()
    }
}

#Required Parameters
$sSiteColUrl = "https://<SPO_Site>/"
$sUsername = "<SPO_User>"
#$sPassword = Read-Host -Prompt "Enter your password: " -AsSecureString
$sPassword=convertto-securestring "<Password>" -asplaintext -force
$sGroupToCreate="CustomSPOGroup"
$sGroupToCreateDescription="Custom SPO Group"

Create-SPOGroup -sSiteColUrl $sSiteColUrl -sUsername $sUsername -sPassword $sPassword -sGroupToCreate $sGroupToCreate -sGroupToCreateDescription $sGroupToCreateDescription


text:
package it.av.youeat.service.impl;

import it.av.youeat.ocm.model.Activity;
import it.av.youeat.ocm.model.Eater;
import it.av.youeat.service.ActivityService;

import java.util.Collection;
import java.util.Date;

import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

/**
 * UserImpl Services class, Use this class to manage the {@link UserImpl}
 *
 * @author Alessandro Vincelli
 *
 */
@Transactional(readOnly = true)
@Repository
public class ActivityServiceHibernate extends ApplicationServiceHibernate<Activity> implements ActivityService {

    /**
     * {@inheritDoc}
     */
    @Override
    public Collection<Activity> findByDate(Date date) {
        Criterion crit = Restrictions.eq(Activity.DATE, date);
        return findByCriteria(crit);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Collection<Activity> findByUser(Eater user) {
        Criterion crit = Restrictions.eq(Activity.USER, user);
        return findByCriteria(crit);
    }
}


text:
title: "Painted joker smile"
excerpt: "PaperFaces portrait of @blumentoast drawn with Paper by 53 on an iPad."
image:
  path: &image /assets/images/paperfaces-blumentoast-twitter-lg.jpg
  feature: *image
  thumb: /assets/images/paperfaces-blumentoast-twitter-150.jpg
tags: [portrait, illustration, Paper by 53]
---

*Why so serious?* PaperFaces portrait of [@blumentoast](http://twitter.com/blumentoast).

{% include boilerplate/paperfaces.md %}


text:
package org.picketlink.rest;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.fluent.Form;
import org.apache.http.client.fluent.Request;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.picketlink.utils.ElementNotFound;
import org.picketlink.utils.IOUtils;

/**
 * @author Rodrigo Ramalho da Silva
 * 		   hodrigohamalho@gmail.com
 */
@Path("/")
public class PicketlinkRestAPI {

	private static final Logger log = Logger.getLogger(PicketlinkRestAPI.class.getName());
	private Header[] headers;
	private final String COOKIE = "cookie";
	private final String SAMLRequest = "SAMLRequest";
	private final String SAMLResponse = "SAMLResponse";
	private final String JSESSIONID_PREFIX = "JSESSIONID=";
	private final String SET_COOKIE = "set-cookie";

	@GET
	@Path("/auth/{context}")
	@Produces({ "text/html" })
	public String auth(@Context HttpServletRequest request, @PathParam("context") String context) {
		HttpSession session = ((HttpServletRequest) request).getSession();
		String IDPSessionID = getIDPSessionID(session);
		String html = "";

		try{
			 // Request to (SP) (context parameter)
			 String SPUrl = getUrl(request) + addDash(context);
			 Request req = Request.Get(SPUrl);

			 html = req.execute().handleResponse(new ResponseHandler<String>() {
				@Override
				public String handleResponse(HttpResponse httpResponse) throws ClientProtocolException, IOException {
					headers = httpResponse.getAllHeaders();
					return IOUtils.getStringFromInputStream(httpResponse.getEntity().getContent());
				}
			});

			// Check if auth is need and was processed by picketlink
			if (html.contains("HTTP Post Binding (Request)")){
				String setCookie = extractCookieFromHeader(getHeader(SET_COOKIE));
				String SAMLRequestValue = getAttributeValueFromHtml(html, SAMLRequest);
				String idpURL = getAttributeActionFromHtml(html);

				// Request to IDP with SAMLRequest attribute using IDP Session ID
				html = Request.Post(idpURL).addHeader(COOKIE, JSESSIONID_PREFIX+IDPSessionID).
						bodyForm(Form.form().add(SAMLRequest, SAMLRequestValue).build()).
						execute().returnContent().toString();

				String SAMLResponseValue = getAttributeValueFromHtml(html, SAMLResponse);

				// Request to SP with SAMLResponse parameter using JSESSIONID retrieved by the first request to SP
				// This POST return a 302 HTTP STATUS
				Request.Post(SPUrl).addHeader(COOKIE, JSESSIONID_PREFIX+setCookie).
						bodyForm(Form.form().add(SAMLResponse, SAMLResponseValue).build()).
						execute().discardContent();

				// Finally GET the SP content
				html = Request.Get(SPUrl).addHeader(COOKIE, JSESSIONID_PREFIX+setCookie).execute().returnContent().toString();
				if (html.contains("HTTP Post Binding (Request)")){
					log.info("Alguma coisa falhou na autenticação!: "+idpURL);
				}
			}else{
				log.info("Content requested without auth process!");
			}
		}catch(IOException io){
			io.printStackTrace();
		}

		return html;
	}

	private String addDash(String context) {
		if (context != null && !context.endsWith("/")){
			context += "/";
		}

		return context;
	}
}


text:
body
{
  font-family: "Trebuchet MS", Geneva, Arial, Helvetica, sans-serif;
  margin: 0;
  padding: 0;
  font-size: 80%;
  background-image: url(../images/bg_body.jpg);
  background-repeat: repeat-x;
  background-color: #E4D7C5;
  color: #81571F;
  text-align: center;
}

img
{
  border: none;
}

a
{
  color: #81571F;
  text-decoration: underline;
}

a:hover
{
  color: #CC0000;
  text-decoration: none;
}

code
{
  font-size:120%;
}

.sfTContainer
{
  position: relative;
  text-align: left;
  width: 515px;
    padding: 0;
    margin: 115px auto 0;
}

.sfTMessageContainer
{
  padding: 5px;
  margin-top: 25px;
  float: left;
  width: 515px;
}

.sfTMessage
{
  background-image: url(../images/bg_sfTMessage.jpg);
  background-repeat: repeat-x;
  background-color: #E8DDCF;
  border: 1px solid #FFFFFF;
  border-bottom-color: #C2AB8C;
  border-right-color: #C2AB8C;
}

.sfTAlert
{
  background-image: url(../images/bg_sfTAlert.jpg);
  background-repeat: repeat-x;
  background-color: #F8E1D1;
  border: 1px solid #FFFFFF;
  border-bottom-color: #F0B17C;
  border-right-color: #F0B17C;
}

.sfTLock
{
  background-image: url(../images/bg_sfTLock.jpg);
  background-repeat: repeat-x;
  background-color: #DEE8F2;
  border: 1px solid #FFFFFF;
  border-bottom-color: #B1C4EC;
  border-right-color: #B1C4EC;
}

.sfTMessageContainer .sfTMessageWrap
{
  float: left;
  width: 440px;
}

.sfTMessageContainer .sfTMessageWrap h1
{
  color: #503512;
  font-weight: normal;
  font-size: 165%;
    margin: 0;
  line-height: 100%;
    padding: 5px 0 0;
}

.sfTMessageContainer .sfTMessageWrap h5
{
  font-weight: normal;
  font-size: 100%;
  padding: 0;
  margin: 0;
}

.sfTMessageContainer img.sfTMessageIcon
{
  width: 48px;
  height: 48px;
  float: left;
  margin-right: 12px;
  margin-left: 5px;
}

.sfTMessageInfo
{
    padding: 0;
    margin: 15px 0 0;
    float: left;
  width: 440px;
}

.sfTMessageInfo dt
{
  font-weight: bolder;
  font-size: 115%;
  margin: 5px 0;
}

.sfTMessageInfo dd
{
  margin: 0;
  padding: 0;
}

.sfTIconList
{
  margin: 0;
  padding: 0;
  list-style: none;
}

.sfTIconList li
{
  clear: left;
  line-height: 170%;
  padding-left: 20px;
}

.sfTIconList li.sfTDatabaseMessage
{
  background: url(../images/icons/db16.png) no-repeat top left;
}

.sfTIconList li.sfTColorMessage
{
  background: url(../images/icons/colour16.png) no-repeat top left;
}

.sfTIconList li.sfTLinkMessage
{
  background: url(../images/icons/linkOut16.png) no-repeat top left;
}

.sfTIconList li.sfTDirectoryMessage
{
  background: url(../images/icons/folder16.png) no-repeat top left;
}

.sfTIconList li.sfTEditMessage
{
  background: url(../images/icons/edit16.png) no-repeat top left;
}

.sfTIconList li.sfTReloadMessage
{
  background: url(../images/icons/reload16.png) no-repeat top left;
}


text:
layout: post
title: ONs and OFFs
---
The question came up as to whether you can do beam nodding on a telescope that doesn't explicitly support beam nodding.  Under some assumptions, it seems possible to do it with the calibrated scans alone.  If we define $$N$$ to be the ON scan, $$F$$ to be the OFF scan then the usual calibration gives

$$
\left(\frac{N-F}{F}\right)T_{\mathrm{sys}} = T_{A,0}
$$

or equivalently

$$
\left(\frac{N}{F}-1\right)T_{\mathrm{sys}} = T_{A,0}.
$$

If the scans are made intentionally or otherwise so that the source is in the OFF position rather than ON position, this would give a different spectrum, where the emission would appear in absorption.  In this case, a new antenna temperature would be derived:

$$
\left(\frac{F-N}{N}\right)T_{\mathrm{sys}} = T_A.
$$

Given this, we'd like to restore the spectrum that would be seen under the "normal" circumstances:

$$
\begin{eqnarray}
\left(\frac{F}{N}-1\right)&=&\frac{T_A}{T_{\mathrm{sys}}} \\
\frac{F}{N} & = & 1+ \frac{T_A}{T_{\mathrm{sys}}}\\
\frac{N}{F} & = & \left(1+ \frac{T_A}{T_{\mathrm{sys}}}\right)^{-1} \\
T_{A,0} = \left(\frac{N}{F}-1\right) T_{\mathrm{sys}} & = &  T_{\mathrm{sys}}
\left(\frac{1}{1+\frac{T_A}{T_{\mathrm{sys}}}}-1\right).
\end{eqnarray}
$$

Thus, if $$T_{\mathrm{sys}}$$ for every scan is known, the intended antenna temperature measurements for each scan can be recovered if the emission is processed in the OFF component of the scan.  As such, an ad hoc observing strategy that uses an OFF position where the ON position can be used to recover the original spectrum and a second spectrum from the OFF.


text:
<?php

namespace Smt\OpenPopo\Reflection\Exception;

/**
 * Thrown on attempt to get non-existent method
 * @package Smt\OpenPopo\Reflection\Exception
 * @author Kirill Saksin <kirillsaksin@yandex.ru>
 * @api
 */
class NoSuchMethodException extends \LogicException
{
}


text:
@interface MPPacketDecoder : NSObject

+ (MPPacket *)decodePacketWithData:(NSData *)data;

@end


text:
//
// The MIT License(MIT)
//
// Copyright(c) 2014 Demonsaw LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include <boost/detail/endian.hpp>
#include <boost/endian/conversion.hpp>

#include "data/checksum_data.h"
#include "data/data_packer.h"
#include "data/header_data.h"
#include "data/transfer_data.h"
#include "data/version_data.h"

#include "data/request/browse_request_data.h"
#include "data/request/chat_request_data.h"
#include "data/request/file_request_data.h"
#include "data/request/search_request_data.h"

#include "data/response/browse_response_data.h"
//#include "data/response/chat_response_data.h"
#include "data/response/file_response_data.h"
#include "data/response/search_response_data.h"

#include "entity/entity.h"
#include "security/checksum/crc.h"
#include "security/filter/lz4.h"

namespace eja
{
	// Macro
	#define data_type_pack(type, class)									\
	case type:															\
	{																	\
		const auto request = std::static_pointer_cast<class>(data);		\
		packer.pack(request);											\
		break;															\
	}

	// Operator
	data_packer& data_packer::operator=(const data_packer& packer)
	{
		if (this != &packer)
		{
			entity_type::operator=(packer);
			data_list::operator=(packer);
		}

		return *this;
	}

	// Utility
	std::string data_packer::pack(const size_t size /*= 128*/) const
	{
		// Buffer
		std::string buffer;
		buffer.reserve(size);
		msgpack::packer<std::string> packer(buffer);

		// Checksum
		checksum_data checksum;
		packer.pack(checksum);
		const auto checksum_size = buffer.size();

		// Version
		version_data version;
		packer.pack(version);

		// Header
		header_data header;

		for (const auto& data : *this)
			header.push_back(data->get_type());

		packer.pack(header);

		// Data
		for (const auto& data : *this)
		{
			switch (data->get_type())
			{
				// Request/Response
				data_type_pack(data_type::transfer, transfer_data);

				// Request
				data_type_pack(data_type::browse_request, browse_request_data);
				data_type_pack(data_type::chat_request, chat_request_data);
				data_type_pack(data_type::file_request, file_request_data);
				data_type_pack(data_type::search_request, search_request_data);

				// Response
				data_type_pack(data_type::browse_response, browse_response_data);
				//data_type_pack(data_type::chat_response, chat_response_data);
				data_type_pack(data_type::file_response, file_response_data);
				data_type_pack(data_type::search_response, search_response_data);

				default:
				{
					assert(false);
					break;
				}
			}
		}

		// Checksum
		u32& crc_value = *reinterpret_cast<u32*>(const_cast<char*>(buffer.data()) + (checksum_size - sizeof(u32)));
		const auto crc_input = buffer.data() + checksum_size;
		const auto crc_input_size = buffer.size() - checksum_size;

		// Endianness
		BOOST_ENDIAN_LITTLE_ONLY(crc_value = boost::endian::endian_reverse(static_cast<u32>(crc32()(crc_input, crc_input_size)));)
		BOOST_ENDIAN_BIG_ONLY(crc_value = static_cast<u32>(crc32()(crc_input, crc_input_size));)

		// Compression
		return lz4::encode(buffer);
	}
}


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

@Component({
  selector: 'app-comp-3025',
  templateUrl: './comp-3025.component.html',
  styleUrls: ['./comp-3025.component.css']
})
export class Comp3025Component implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}


text:
'use strict';
var $ = require('../internals/export');
var ObjectIterator = require('../internals/object-iterator');

// `Object.iterateEntries` method
// https://github.com/tc39/proposal-object-iteration
$({ target: 'Object', stat: true }, {
  iterateEntries: function iterateEntries(object) {
    return new ObjectIterator(object, 'entries');
  }
});


text:
<?php

namespace DvsaCommon\ApiClient\Statistics\TesterPerformance;

use DvsaCommon\ApiClient\Statistics\TesterPerformance\Dto\NationalPerformanceReportDto;
use DvsaCommon\ApiClient\Statistics\TesterPerformance\Dto\SitePerformanceDto;
use DvsaCommon\Factory\AutoWire\AutoWireableInterface;
use DvsaCommon\HttpRestJson\AbstractApiResource;

class SitePerformanceApiResource extends AbstractApiResource implements AutoWireableInterface
{
    /**
     * @param int $siteId
     * @param int $numberOfLastMonths
     * @return SitePerformanceDto
     */
    public function getForMonthRange(int $siteId, int $numberOfLastMonths)
    {
        return $this->getSingle(
            SitePerformanceDto::class,
            sprintf('statistic/tester-performance/site/%d/%d', $siteId, $numberOfLastMonths)
        );
    }
}


text:
from occi_libs import occi_config
import occi

import pycurl
import re
import sys
if sys.version_info >= (3,):
    from StringIO import BytesIO
else:
    from StringIO import StringIO

# Helper callback function
header = []

def get_header2(buff):
    global header
    header.append(buff)

def get_header3(buff):
    global header
    header.append(buff.decode('iso-8859-1'))

def occi_curl(base_url=None, url='/-/', authtype=None, ignoressl=None, user=None, passwd=None, mimetype=None, headers=[], post='', custom_request=''):
    """Send HTTP request

    :param string base_url: OCCI server URL (default: from config)
    :param string url: path element of the URL
    :param string authtype: authentication type (default: from config)
    :param bool ignoressl: ignore SSL problems (default: from config)
    :param string user: user name for 'basic' auth (default: from config)
    :param string passwd: password for 'basic' auth (default: from config)
    :param string mimetype: accepted mimetype (empty string='\*/\*')
    :param string headers[]: HTTP Headers
    :param string post: HTTP Body
    :param string custom_request: HTTP Request type (default: 'GET' or 'POST')

    :return: [body, header, HTTP status, content type]
    :rtype: [string[], string[], string, string]
    """
    global header

    if base_url is None:
        base_url = occi_config['url']
    if authtype is None:
        authtype = occi_config['authtype']
    if ignoressl is None:
        ignoressl = occi_config['ignoressl']
    if user is None:
        user = occi_config['user']
    if passwd is None:
        passwd = occi_config['passwd']
    if mimetype is None:
        mimetype = occi_config['mimetype']
    curlverbose = occi_config['curlverbose']

    if sys.version_info >= (3,):
        buffer = BytesIO()
    else:
        buffer = StringIO()
    curl = pycurl.Curl()
    curl.setopt(pycurl.URL, str(base_url + url))
    curl.setopt(pycurl.WRITEFUNCTION, buffer.write)

    # Disable check of SSL certificate
    if ignoressl:
        curl.setopt(pycurl.SSL_VERIFYPEER, 0)
        curl.setopt(pycurl.SSL_VERIFYHOST, 0)

    if 'capath' in occi_config and occi_config['capath']:
        curl.setopt(pycurl.CAPATH, occi_config['capath'])

    if 'cachain' in occi_config and occi_config['cachain']:
        curl.setopt(pycurl.CAINFO, occi_config['cachain'])

    # Name and password for basic auth (ONLY SUPPORTED YET)
    if authtype == "basic":
        curl.setopt(pycurl.HTTPAUTH, pycurl.HTTPAUTH_BASIC)
        curl.setopt(pycurl.USERPWD, "%s:%s" % (user, passwd))
    elif authtype == "x509":
        if 'cert' in occi_config and occi_config['cert']:
            curl.setopt(pycurl.SSLCERT, occi_config['cert'])
        if 'key' in occi_config and occi_config['key']:
            curl.setopt(pycurl.SSLKEY, occi_config['key'])
        if 'passphrase' in occi_config and occi_config['passphrase']:
            curl.setopt(pycurl.SSLCERTPASSWD, occi_config['passphrase'])

    # Verbose mode
    curl.setopt(pycurl.VERBOSE, curlverbose)

    curl.setopt(pycurl.CONNECTTIMEOUT, occi_config['connectiontimeout'])
    curl.setopt(pycurl.TIMEOUT, occi_config['timeout'])

    # Set appropriate mime type
    if mimetype:
        headers = ['Accept: %s' % mimetype] + headers
    else:
        headers = ['Accept: */*'] + headers

    # Set requested HTTP headers
    if headers:
        curl.setopt(pycurl.HTTPHEADER, headers)

    # HTTP header response
    if sys.version_info >= (3,):
        curl.setopt(pycurl.HEADERFUNCTION, get_header3)
    else:
        curl.setopt(pycurl.HEADERFUNCTION, get_header2)

    if post or custom_request == 'POST':
        curl.setopt(pycurl.POST, 1)
        if post:
            curl.setopt(pycurl.POSTFIELDS, post)
        else:
            curl.setopt(pycurl.POSTFIELDS, 'OK')
        if curlverbose:
            print "==== POST ==== "
            print post
            print "============== "

    if custom_request and custom_request != 'POST':
        curl.setopt(pycurl.CUSTOMREQUEST, custom_request)

    # DO IT!
    header = []
    try:
        curl.perform()
        curl.close()
    except pycurl.error as pe:
        raise occi.Error(pe)

    ## 'Server: Apache/2.2.22 (Debian)\r\n'
    h = {}
    for item in header:
        if re.match(r'.*:.*', item):
            key = re.sub(r':.*', r'', item.rstrip())
            value = re.sub(r'([^:]*):\s*(.*)', r'\2', item.rstrip())

            h[key] = value
        else:
            if re.match(r'^HTTP', item):
                http_status = item.rstrip()
    content_type = None
    if 'Content-Type' in h:
        content_type = re.split(';', h['Content-Type'])[0]

    body = buffer.getvalue()
    if sys.version_info >= (3,):
        encoding = 'iso-8859-1'
        if content_type:
            match = re.search(r';\s*charset=(\S+)', h['Content-Type'])
            if match:
                encoding = match.group(1)
        body = body.decode(encoding)

    return [body.splitlines(), header, http_status, content_type]