text:
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.IO;
using Soomla.Store;

public class EconomyBuilder : EditorWindow
{

	private Vector2 scrollPos = Vector2.zero;
	private SoomlaEditorData editorData;
	private bool inited = false;

	private enum screens
	{
		goods = 0,
		currencies,
		currencyPacks,
		categories,
	};

	//string[] goodTypeOptions = {"Add Virtual Good", "Single Use", "Lifetime", "Equippable", "Upgradable", "Single Use Pack"};
	//without upgradable
	private string[] goodTypeOptions = {"Add Virtual Good", "Single Use", "Lifetime", "Equippable", "Single Use Pack"};
	private int goodTypeIndex = 0;

	private string[] displayingModes = {"+-", "Expand All", "Collapse All"};
	private int displayingIndex = 0;

	private screens screenNumber = screens.goods;

	[MenuItem ("Window/Soomla/Economy Builder")]
	static void Init ()
	{
		EconomyBuilder window = (EconomyBuilder)EditorWindow.GetWindow(typeof (EconomyBuilder), false, "EconomyBuilder");
		window.InitSoomlaEditorData ();
	}

	void InitSoomlaEditorData()
	{
		editorData = new SoomlaEditorData ();
		editorData.ReadFromJSONFile ();
		editorData.updateSingleUseItems();
		inited = true;
	}

	public void OnGUI ()
	{
		if (!inited) {
			InitSoomlaEditorData();
		}

		EditorGUILayout.BeginHorizontal();
		{
			if (GUILayout.Toggle(screenNumber == screens.goods, "Goods", EditorStyles.toolbarButton))
				screenNumber = screens.goods;
			if (GUILayout.Toggle(screenNumber == screens.currencies, "Currencies", EditorStyles.toolbarButton))
				screenNumber = screens.currencies;
			if (GUILayout.Toggle(screenNumber == screens.currencyPacks, "Currency Packs", EditorStyles.toolbarButton))
				screenNumber = screens.currencyPacks;

//			if (GUILayout.Toggle(screenNumber == screens.categories, "Categories", EditorStyles.toolbarButton))
//			{
//				screenNumber = screens.categories;
//			}
		}
		EditorGUILayout.EndHorizontal();

		if(editorData != null)
			this.ShowData();
		else
			InitSoomlaEditorData();

	}

	void ShowData()
	{
		switch (screenNumber) {
			case screens.goods:
				ShowGoods ();
				break;
			case screens.currencies:
				ShowCurrencies ();
				break;
			case screens.currencyPacks:
				ShowCurrencyPacks ();
				break;
			case screens.categories:
				ShowCategories ();
				break;
			default:
				break;
		}
	}

	void ShowGoods()
	{
		EditorGUILayout.BeginHorizontal ();
		goodTypeIndex = EditorGUILayout.Popup(goodTypeIndex, goodTypeOptions, GUILayout.Width(100));

		if (goodTypeIndex > 0)
		{
			if (goodTypeIndex == 1) {
				editorData.AddGood(ZFGood.GoodType.SingleUseVG);
			}
			else if (goodTypeIndex == 2) {
				editorData.AddGood(ZFGood.GoodType.LifetimeVG);
			}
			else if (goodTypeIndex == 3) {
				editorData.AddGood(ZFGood.GoodType.EquippableVG);
			}
			/*else if (goodTypeIndex == 4) {
				editorData.AddGood(ZFGood.GoodType.UpgradeVG);
			}*/
			else if (goodTypeIndex == 4) {
				editorData.AddGood(ZFGood.GoodType.SingleUsePackVG);
			}

			editorData.updateSingleUseItems();

			goodTypeIndex = 0;
		}

		addGenerateButton();

		EditorGUILayout.EndHorizontal ();

		EditorGUILayout.BeginHorizontal ();
		addModesDisplaying(screens.goods);
		EditorGUILayout.EndHorizontal ();

        scrollPos = GUILayout.BeginScrollView (scrollPos);

		for (int i = 0; i < editorData.goods.Count; i++)
		{
			EditorGUILayout.BeginVertical(GUI.skin.box);
			ShowGood(i);
			EditorGUILayout.EndVertical();
		}

		GUILayout.EndScrollView ();

		EditorGUILayout.Space ();
		EditorGUILayout.Space ();
		EditorGUILayout.BeginHorizontal(GUI.skin.box);

		FileStream fs = new FileStream(Application.dataPath + @"/Soomla/Resources/soom_logo.png", FileMode.Open, FileAccess.Read);
		byte[] imageData = new byte[fs.Length];
		fs.Read(imageData, 0, (int)fs.Length);
		Texture2D soomlaLogoTexture = new Texture2D(300, 92);
		soomlaLogoTexture.LoadImage(imageData);

		GUIContent logoImgLabel = new GUIContent (soomlaLogoTexture);
		EditorGUILayout.LabelField(logoImgLabel, GUILayout.MaxHeight(70), GUILayout.ExpandWidth(true));
		EditorGUILayout.HelpBox ("Basic Instructions: navigate throught the goods, currencies and currency packs tabs.  In each tab you may add new definitions of items in your virtual economy as well as edit or delete existing ones.  The economy model is documented in detail in the SOOMLA knowledge base: http://know.soom.la/unity/store/store_model/.  The economy builder is in beta, any feedback is appreciated and can be sent to builder@soom.la.", MessageType.Info, true);
		GameObject.DestroyImmediate(soomlaLogoTexture);

		EditorGUILayout.EndHorizontal ();
	}

	void ShowGood(int goodIndex)
	{
		ZFGood good = editorData.goods [goodIndex];
		EditorGUILayout.BeginHorizontal();

		good.render = EditorGUILayout.Foldout(good.render, "<" + good.name +"> (" + good.goodType + ")");

		if (goodIndex != 0)
		{
			GUIContent btnMoveUp = new GUIContent (char.ConvertFromUtf32(8593), "Move Up");
			if(GUILayout.Button(btnMoveUp, EditorStyles.miniButton, GUILayout.Width(20f))) {
				editorData.goods[goodIndex] = editorData.goods[goodIndex-1];
				editorData.goods[goodIndex-1] = good;
			}
		}

		if (goodIndex != editorData.goods.Count-1)
		{
			GUIContent btnMoveDown = new GUIContent (char.ConvertFromUtf32(8595), "Move Down");
			if(GUILayout.Button(btnMoveDown, EditorStyles.miniButton, GUILayout.Width(20f))) {
				editorData.goods[goodIndex] = editorData.goods[goodIndex+1];
				editorData.goods[goodIndex+1] = good;
			}
		}

		GUIContent deleteButtonContent = new GUIContent ("X", "Delete");
		if(GUILayout.Button(deleteButtonContent, EditorStyles.miniButton, GUILayout.Width(20))) {
			editorData.DeleteGood(good);
		}

		EditorGUILayout.EndHorizontal();

		if (good.render) {
			EditorGUI.indentLevel++;
			good.ID = EditorGUILayout.TextField("Item ID ", good.ID);
			good.name = EditorGUILayout.TextField("Name", good.name);
			good.name = Regex.Replace(good.name, "\n", "");
			good.description = EditorGUILayout.TextField("Description", good.description);
			good.description = Regex.Replace(good.description, "\n", "");
			good.typePurchase = (ZFGood.PurchaseInfo)EditorGUILayout.EnumPopup("Purchase With", good.typePurchase);
			EditorGUI.indentLevel++;
            if (good.typePurchase == ZFGood.PurchaseInfo.Market) {
				good.marketInfo.price = EditorGUILayout.FloatField("Price", good.marketInfo.price);

				good.marketInfo.productId = EditorGUILayout.TextField("Product ID", good.marketInfo.productId);
            } else {
				if (editorData.currencies.Count > 0) {
					good.virtualInfo.pvi_amount = EditorGUILayout.IntField("Price", good.virtualInfo.pvi_amount);

					int indexInArray = 0;
					List <string> currencyNames = new List<string>();
					for (int i = 0; i < editorData.currencies.Count; i++)
					{
						currencyNames.Add(editorData.currencies[i].name);
						if (good.virtualInfo.pvi_itemId == null) {
							indexInArray = 0;
						}
						else if (editorData.currencies[i].ID == good.virtualInfo.pvi_itemId)
						{
							indexInArray = i;
						}
					}

					int index = EditorGUILayout.Popup("Item", indexInArray, currencyNames.ToArray());
					good.virtualInfo.pvi_itemId = editorData.currencies[index].ID;
				} else {
					EditorGUILayout.HelpBox("You have no defined currencies", MessageType.Warning, true);
				}
			}
			EditorGUI.indentLevel--;

            if (good.goodType == ZFGood.GoodType.SingleUsePackVG) {
				editorData.updateSingleUseItems();
				if (editorData.singleUseGoodsIDs.Count > 0) {
					int indexInArray = 0;
					if (editorData.singleUseGoodsIDs.Count != 0)
					{
						for (int i = 0; i < editorData.singleUseGoodsIDs.Count; i++)
						{
							if (editorData.singleUseGoodsIDs[i] == good.good_itemId)
                            {
                                indexInArray = i;
                            }
                        }
					}
					int index = EditorGUILayout.Popup("Single Use Item", indexInArray, editorData.singleUseGoodsIDs.ToArray());
					good.good_itemId = editorData.singleUseGoodsIDs[index];

					EditorGUI.indentLevel++;
					good.good_amount = EditorGUILayout.IntField("Amount", good.good_amount);
					EditorGUI.indentLevel--;
				} else {
					EditorGUILayout.HelpBox("You should define a Single Use Item before", MessageType.Warning, true);
                }
			}

		    EditorGUI.indentLevel--;
		}
	}

	void ShowCurrencies()
	{
		EditorGUILayout.BeginHorizontal();
		if (GUILayout.Button ("Add Currency", EditorStyles.miniButton, GUILayout.Width(100))) {
			editorData.AddCurrency();
		}

		addGenerateButton();
		EditorGUILayout.EndHorizontal();

		EditorGUILayout.BeginHorizontal();
		addModesDisplaying(screens.currencies);
		EditorGUILayout.EndHorizontal();

		scrollPos = GUILayout.BeginScrollView (scrollPos);

        for (int i = 0; i < editorData.currencies.Count; i++)
		{
			GUILayout.BeginVertical(GUI.skin.box);
			{
				this.ShowCurrency(i);
			}
			GUILayout.EndVertical();
		}

		GUILayout.EndScrollView();
	}

	void ShowCurrency(int currencyIndex)
	{
		ZFCurrency currency = editorData.currencies [currencyIndex];

		EditorGUILayout.BeginHorizontal();

		currency.render = EditorGUILayout.Foldout(currency.render, "<" + currency.name +"> (" + currency.ID + ")");

		if (currencyIndex != 0)
		{
			GUIContent btnMoveUp = new GUIContent (char.ConvertFromUtf32(8593), "Move Up");
			if(GUILayout.Button(btnMoveUp, EditorStyles.miniButton, GUILayout.Width(20f))) {
				editorData.currencies[currencyIndex] = editorData.currencies[currencyIndex-1];
				editorData.currencies[currencyIndex-1] = currency;
			}
		}

		if (currencyIndex != editorData.currencies.Count-1)
		{
			GUIContent btnMoveDown = new GUIContent (char.ConvertFromUtf32(8595), "Move Down");
			if(GUILayout.Button(btnMoveDown, EditorStyles.miniButton, GUILayout.Width(20f))) {
				editorData.currencies[currencyIndex] = editorData.currencies[currencyIndex+1];
				editorData.currencies[currencyIndex+1] = currency;
			}
		}

		GUIContent deleteButtonContent = new GUIContent ("X", "Delete");
		if(GUILayout.Button(deleteButtonContent, EditorStyles.miniButton, GUILayout.Width(20))) {
			editorData.DeleteCurrency(currency);
		}

		EditorGUILayout.EndHorizontal();

		if (currency.render) {
            EditorGUI.indentLevel++;
            currency.ID = EditorGUILayout.TextField("Item ID ", currency.ID);
			currency.name = EditorGUILayout.TextField("Name", currency.name);
			currency.name = Regex.Replace(currency.name, "\n", "");
			EditorGUI.indentLevel--;
		}
	}

	void ShowCurrencyPacks() {
		EditorGUILayout.BeginHorizontal();
		if (GUILayout.Button ("Add Currency Pack", EditorStyles.miniButton, GUILayout.Width(100)))  {
			editorData.AddCurrencyPack();
		}
		addGenerateButton();
		EditorGUILayout.EndHorizontal();

		EditorGUILayout.BeginHorizontal();
		addModesDisplaying(screens.currencyPacks);
		EditorGUILayout.EndHorizontal();

		scrollPos = GUILayout.BeginScrollView (scrollPos);
		for (int i = 0; i < editorData.currencyPacks.Count; i++)
		{
			GUILayout.BeginVertical(GUI.skin.box);
			{
				ShowCurrencyPack(i);
			}
			GUILayout.EndVertical();
		}
		GUILayout.EndScrollView();
	}

	void ShowCurrencyPack(int currencyPackIndex)
	{
		ZFCurrencyPack currencyPack = editorData.currencyPacks [currencyPackIndex];

		EditorGUILayout.BeginHorizontal();

		currencyPack.render = EditorGUILayout.Foldout(currencyPack.render, "<" + currencyPack.name +"> (" + currencyPack.ID + ")");

		if (currencyPackIndex != 0)
		{
			GUIContent btnMoveUp = new GUIContent (char.ConvertFromUtf32(8593), "Move Up");
			if(GUILayout.Button(btnMoveUp, EditorStyles.miniButton, GUILayout.Width(20f))) {
				editorData.currencyPacks[currencyPackIndex] = editorData.currencyPacks[currencyPackIndex-1];
				editorData.currencyPacks[currencyPackIndex-1] = currencyPack;
			}
		}

		if (currencyPackIndex != editorData.currencyPacks.Count-1)
		{
			GUIContent btnMoveDown = new GUIContent (char.ConvertFromUtf32(8595), "Move Down");
			if(GUILayout.Button(btnMoveDown, EditorStyles.miniButton, GUILayout.Width(20f))) {
				editorData.currencyPacks[currencyPackIndex] = editorData.currencyPacks[currencyPackIndex+1];
				editorData.currencyPacks[currencyPackIndex+1] = currencyPack;
			}
		}

		GUIContent deleteButtonContent = new GUIContent ("X", "Delete");
		if(GUILayout.Button(deleteButtonContent, EditorStyles.miniButton, GUILayout.Width(20))) {
			editorData.currencyPacks.Remove(currencyPack);
		}

		EditorGUILayout.EndHorizontal();

		if (currencyPack.render) {
			EditorGUI.indentLevel++;
			currencyPack.ID = EditorGUILayout.TextField("Item ID ", currencyPack.ID);
			currencyPack.name = EditorGUILayout.TextField("Name", currencyPack.name);
			currencyPack.name = Regex.Replace(currencyPack.name, "\n", "");
			currencyPack.description = EditorGUILayout.TextField("Description", currencyPack.description);
			currencyPack.description = Regex.Replace(currencyPack.description, "\n", "");

			// market info
			currencyPack.marketInfo.price = EditorGUILayout.FloatField("Price", currencyPack.marketInfo.price);

			currencyPack.marketInfo.productId = EditorGUILayout.TextField("Product ID", currencyPack.marketInfo.productId);

            // currency data
			if (editorData.currencies.Count > 0) {
				int indexInArray = 0;
				List <string> currencyNames = new List<string>();
				for (int i = 0; i < editorData.currencies.Count; i++)
				{
					currencyNames.Add(editorData.currencies[i].name);
					if (currencyPack.currency_itemId == null) {
						indexInArray = 0;
					}
					else if (editorData.currencies[i].ID == currencyPack.currency_itemId)
					{
						indexInArray = i;
					}
				}

				int index = EditorGUILayout.Popup("Currency", indexInArray, currencyNames.ToArray());
				currencyPack.currency_itemId = editorData.currencies[index].ID;
				EditorGUI.indentLevel++;
				currencyPack.currency_amount = EditorGUILayout.IntField("Amount", currencyPack.currency_amount);
				EditorGUI.indentLevel--;
			} else {
                EditorGUILayout.HelpBox("You have no defined currencies", MessageType.Warning, true);
            }

            EditorGUI.indentLevel--;
        }

	}

	void ShowCategories()
	{

	}

	private void addGenerateButton() {
		if(GUILayout.Button("Generate", EditorStyles.miniButton, GUILayout.Width(100)))
		{
			if(!editorData.areUniqueGoods() || !editorData.areUniqueCurrencies() || !editorData.areUniqueCurrencyPacks())
			{
				EditorUtility.DisplayDialog("ERROR", editorData.getResponseAboutSameItems(), "Ok");
			}
			else
			{
				editorData.WriteToJSONFile(editorData.toJSONObject());
				editorData.generateSoomlaAssets();
				EditorUtility.DisplayDialog("", "File has been saved to path:\nAssets/SoomlaAssets.cs", "Ok");
			}
		}
	}

	private void addModesDisplaying(screens scr)	{
		displayingIndex = EditorGUILayout.Popup (displayingIndex, displayingModes, GUILayout.Width(30));

		if (displayingIndex == 0) {
			displayingIndex = 0;
		}
		else if (displayingIndex == 1)	{
			editorData.expandAll((int)scr);
		}
		else if (displayingIndex == 2)	{
			editorData.collapseAll((int)scr);
		}
		displayingIndex = 0;
	}
}


text:
#include <vector>
#include <stdlib.h>

class V_XS_Treatment
{
public:
  V_XS_Treatment();
  virtual ~V_XS_Treatment();

  virtual void calculate_xs_at_integration_points(const std::vector<double>& xs_evaluations,
    std::vector<double>& xs_at_dfem_integration_points) = 0;
};

#endif

redpajama_set_name: RedPajamaGithub


text:
package graphic;

import graphic.powerup.Powerup;
import org.newdawn.slick.*;
import org.newdawn.slick.geom.Vector2f;

/**
 * User: Nick Meek
 * Date: 13/02/14
 * A class to display the animated windmills
 * Has a number of constructors so you cna adjust scale and color filter
 */
public class Cloud extends Powerup implements BalloonEffect {

    protected float scale;
    protected Color colour;
    protected int step; // the offset used in scrolling. Differs for each layer for parallex

    public Cloud() throws SlickException {
            super("data/image/cloud2.png");
         if(Math.random()>.5){
             this.setImage("data/image/cloud2.png");
         }else{
             this.setImage("data/image/cloud1.png");
         }

        this.scale = .8f + (int)(Math.random() * ((1.8 - .8) + 1));
        this.colour = null;
        this.step = -2;
    }

    @Override
    public void rotate() {
    }

    @Override
    public void onCollideWithBalloon(Balloon balloon) {

    }

    @Override
    public void move(int delta) {
        x += delta / 1000 + step;//To change body of overridden methods use File | Settings | File Templates.
    }

    @Override
    public void drawOnBalloon(Balloon balloon, Graphics graphics) {
    }

    @Override
    public boolean isDrawnOnFront() {
        return false;
    }

    @Override
    public boolean isReadyForDisposal() {
        return (x < - image.getWidth()- 100);
    }
}


text:
@implementation FlxlPinchGestureRecognizer{
    NSUInteger _totalTouchCount;
}
#pragma mark -
#pragma mark Init Methods

#pragma mark -
#pragma mark Private Methods

#pragma mark -
#pragma mark Protocol Methods

#pragma mark -
#pragma mark Properties

#pragma mark -
#pragma mark Standard Methods

#pragma mark -
#pragma mark Overridden Methods
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    [super touchesBegan:touches withEvent:event];
    if (self.state != UIGestureRecognizerStateFailed)
        _totalTouchCount = event.allTouches.count;
}
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    _totalTouchCount = event.allTouches.count;
    [super touchesMoved:touches withEvent:event];
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    _totalTouchCount = event.allTouches.count;
    [super touchesEnded:touches withEvent:event];
}
- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{
    _totalTouchCount = event.allTouches.count;
    [super touchesCancelled:touches withEvent:event];
}

@end


text:
package bazooka.server.context

import bazooka.server.persistence._
import bazooka.server.servlet._

import com.google.inject._

import com.wideplay.warp.persist._

class BazookaContext(persistenceModule: PersistenceModule) {

  val injector = Guice.createInjector(
    new BazookaServletModule,
    persistenceModule,
    PersistenceService.usingJpa.across(UnitOfWork.TRANSACTION).buildModule)

  def this() = this(new PersistenceModule("bazooka"))

  def getInjector() = injector
}


text:
@implementation Solution

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

        LinkedNode *head = [[LinkedNode alloc] init];
        head.value = 1;

        LinkedNode *lastNode = head;
        for (int i = 2; i < 10; i++) {
            LinkedNode *node = [[LinkedNode alloc] init];
            node.value = i;

            lastNode.next = node;

            lastNode = node;
        }

        BinaryTreeNode *bstHead = [self sortLinkedNodeToBST:head withEnd:nil];
        NSLog(@"%@",[bstHead printTree]);

    }

    return self;
}

- (BinaryTreeNode*)sortLinkedNodeToBST:(LinkedNode*)head withEnd:(LinkedNode*)endNode{
    if (head == endNode) {
        return nil;
    }
    LinkedNode *fastRunner = head;
    LinkedNode *slowRunner = head;

    while (fastRunner != endNode && fastRunner.next != endNode) {
        fastRunner = fastRunner.next.next;
        slowRunner = slowRunner.next;
    }

    BinaryTreeNode *rootNode = [[BinaryTreeNode alloc] init];
    rootNode.value = slowRunner.value;
    rootNode.left = [self sortLinkedNodeToBST:head withEnd:slowRunner];
    rootNode.right = [self sortLinkedNodeToBST:slowRunner.next withEnd:endNode];

    return rootNode;
}

@end


text:
class CharacterSheet < ApplicationRecord
  store :data_fields, coder: JSON

  has_one :shareable_link, dependent: :destroy
  belongs_to :user, optional: true

  def self.system_fields_file_storage_name
    if const_defined?(:SYSTEM_NAME)
      "#{self::SYSTEM_NAME}.yml"
    else
      ""
    end
  end

  def self.fields_map
    field_mappings_path = Rails.root.join('config', 'field_mappings', system_fields_file_storage_name)
    return {} unless File.exists?(field_mappings_path)
    @fields_map ||= YAML.load(File.read(field_mappings_path))
  end
end


text:
namespace NuGetGallery.Migrations
{
    using System;
    using System.Data.Entity.Migrations;

    public partial class PackagesPerCuratedFeed : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "dbo.CuratedPackageVersions",
                c => new
                    {
                        CuratedPackageRegistrationKey = c.Int(nullable: false),
                        PackageKey = c.Int(nullable: false),
                    })
                .PrimaryKey(t => new { t.CuratedPackageRegistrationKey, t.PackageKey })
                .ForeignKey("dbo.CuratedPackages", t => t.CuratedPackageRegistrationKey, cascadeDelete: true)
                .ForeignKey("dbo.Packages", t => t.PackageKey, cascadeDelete: true)
                .Index(t => t.CuratedPackageRegistrationKey)
                .Index(t => t.PackageKey);

        }

        public override void Down()
        {
            DropIndex("dbo.CuratedPackageVersions", new[] { "PackageKey" });
            DropIndex("dbo.CuratedPackageVersions", new[] { "CuratedPackageRegistrationKey" });
            DropForeignKey("dbo.CuratedPackageVersions", "PackageKey", "dbo.Packages");
            DropForeignKey("dbo.CuratedPackageVersions", "CuratedPackageRegistrationKey", "dbo.CuratedPackages");
            DropTable("dbo.CuratedPackageVersions");
        }
    }
}


text:
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta content="history" name="save" />
    <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5" />
    <title>PopServerLockedException Class</title>
    <xml>
    </xml>
    <link rel="stylesheet" type="text/css" href="MSDN.css" />

            OpenPop.NET POP3 Library Documentation

PopServerLockedException Class

 Thrown when the user mailbox is locked or in-use.

                For a list of all members of this type, see PopServerLockedException Members
                .

        System.Object

   Exception
      PopClientException
         PopServerLockedException

public class PopServerLockedException : PopClientException

Thread Safety

					Public static (Shared in Visual Basic) members of this type are
					safe for multithreaded operations. Instance members are not guaranteed to be
					thread-safe.

Remarks

 The mail boxes are locked when an existing session is open on the POP3 server.
 Only one POP3 client can use a POP3 account at a time.

Requirements

        Namespace:
        OpenPop.Pop3.Exceptions

        Assembly: OpenPop (in OpenPop.dll)

See Also

        PopServerLockedException Members | OpenPop.Pop3.Exceptions Namespace

      <object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e" viewastext="true" style="display: none;">
        <param name="Keyword" value="PopServerLockedException class, about PopServerLockedException class">
        </param>
      </object>

          Send comments on this topic.

          Public Domain Dedication

Generated from assembly OpenPop [2.0.4.369] by NDoc3


text:
void Set_FKeys2( unsigned int p1 );
void Set_FKeys1( unsigned int p1, unsigned int*P2 );
void PRGM_GetKey_OS( unsigned char*p );
int GetKey(int*key);
int GetKeyWait_OS(int*column, int*row, int type_of_waiting, int timeout_period, int menu, unsigned short*keycode );


text:
<?php
declare(strict_types=1);

namespace bovigo\assert\predicate;
use bovigo\assert\AssertionFailure;
use PHPUnit\Framework\TestCase;

use function bovigo\assert\assertThat;
use function bovigo\assert\expect;
use function bovigo\assert\predicate\isArray;
use function bovigo\assert\predicate\isNotAnArray;

/**
 * Test for bovigo\assert\assert\predicate\isArray() and bovigo\assert\assert\predicate\isNotAnArray().
 *
 * @group  predicate
 */
class IsArrayTest extends TestCase
{
    /**
     * @return  array<string,array<array<mixed>>>
     */
    public function validArrays(): array
    {
        return [
            'empty array'       => [[]],
            'normal array'      => [[1, 2, 3]],
            'associative array' => [['one' => 1, 'two' => 2, 'three' => 3]]
        ];
    }

    /**
     * @return  array<string,array<mixed>>
     */
    public function invalidArrays(): array
    {
        return [
            'string' => ['foo'],
            'number' => [303],
            'object' => [new \stdClass()]
        ];
    }

    /**
     * @param  array<mixed>  $value
     * @test
     * @dataProvider  validArrays
     */
    public function validArraysAreRecognized(array $value): void
    {
        assertThat($value, isArray());
    }

    /**
     * @param  mixed  $value
     * @test
     * @dataProvider  invalidArrays
     */
    public function invalidArraysAreRejected($value): void
    {
        expect(function() use($value) { assertThat($value, isArray()); })
            ->throws(AssertionFailure::class);
    }

    /**
     * @param  mixed  $value
     * @test
     * @dataProvider  invalidArrays
     */
    public function invalidArraysAreRecognizedOnNegation($value): void
    {
        assertThat($value, isNotAnArray());
    }

    /**
     * @param  array<mixed>  $value
     * @test
     * @dataProvider  validArrays
     */
    public function validArraysAreRejectedOnNegation(array $value): void
    {
        expect(function() use($value) { assertThat($value, isNotAnArray()); })
            ->throws(AssertionFailure::class);
    }
}


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

    <parent>
        <groupId>com.bazaarvoice.commons</groupId>
        <artifactId>bv-opensource-super-pom</artifactId>
        <version>1.5</version>
        <relativePath />
    </parent>

    <groupId>com.bazaarvoice.awslocal</groupId>
    <artifactId>parent</artifactId>
    <version>2.1-SNAPSHOT</version>
    <packaging>pom</packaging>

    <properties>
        <java.minimum.version>1.8</java.minimum.version>
        <aws.version>1.11.537</aws.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.amazonaws</groupId>
                <artifactId>aws-java-sdk-sqs</artifactId>
                <version>${aws.version}</version>
            </dependency>
            <dependency>
                <groupId>com.amazonaws</groupId>
                <artifactId>aws-java-sdk-sns</artifactId>
                <version>${aws.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>3.1</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.26</version>
            </dependency>

            <dependency>
                <groupId>org.testng</groupId>
                <artifactId>testng</artifactId>
                <version>6.8.5</version>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>1.0.12</version>
            </dependency>
            <dependency>
                <groupId>javax.validation</groupId>
                <artifactId>validation-api</artifactId>
                <version>1.0.0.GA</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>


text:
#pragma once
#include <aws/redshift/Redshift_EXPORTS.h>
#include <aws/redshift/RedshiftRequest.h>
#include <aws/core/utils/memory/stl/AWSString.h>
#include <aws/redshift/model/DataShareStatusForConsumer.h>
#include <utility>

namespace Aws
{
namespace Redshift
{
namespace Model
{

  /**
   */
  class AWS_REDSHIFT_API DescribeDataSharesForConsumerRequest : public RedshiftRequest
  {
  public:
    DescribeDataSharesForConsumerRequest();

    // Service request name is the Operation name which will send this request out,
    // each operation should has unique request name, so that we can get operation's name from this request.
    // Note: this is not true for response, multiple operations may have the same response name,
    // so we can not get operation's name from response.
    inline virtual const char* GetServiceRequestName() const override { return "DescribeDataSharesForConsumer"; }

    Aws::String SerializePayload() const override;

  protected:
    void DumpBodyToUrl(Aws::Http::URI& uri ) const override;

  public:

    /**
     *
The Amazon Resource Name (ARN) of the consumer that returns in the list of
     * datashares.

     */
    inline const Aws::String& GetConsumerArn() const{ return m_consumerArn; }

    /**
     *
The Amazon Resource Name (ARN) of the consumer that returns in the list of
     * datashares.

     */
    inline bool ConsumerArnHasBeenSet() const { return m_consumerArnHasBeenSet; }

    /**
     *
The Amazon Resource Name (ARN) of the consumer that returns in the list of
     * datashares.

     */
    inline void SetConsumerArn(const Aws::String& value) { m_consumerArnHasBeenSet = true; m_consumerArn = value; }

    /**
     *
The Amazon Resource Name (ARN) of the consumer that returns in the list of
     * datashares.

     */
    inline void SetConsumerArn(Aws::String&& value) { m_consumerArnHasBeenSet = true; m_consumerArn = std::move(value); }

    /**
     *
The Amazon Resource Name (ARN) of the consumer that returns in the list of
     * datashares.

     */
    inline void SetConsumerArn(const char* value) { m_consumerArnHasBeenSet = true; m_consumerArn.assign(value); }

    /**
     *
The Amazon Resource Name (ARN) of the consumer that returns in the list of
     * datashares.

     */
    inline DescribeDataSharesForConsumerRequest& WithConsumerArn(const Aws::String& value) { SetConsumerArn(value); return *this;}

    /**
     *
The Amazon Resource Name (ARN) of the consumer that returns in the list of
     * datashares.

     */
    inline DescribeDataSharesForConsumerRequest& WithConsumerArn(Aws::String&& value) { SetConsumerArn(std::move(value)); return *this;}

    /**
     *
The Amazon Resource Name (ARN) of the consumer that returns in the list of
     * datashares.

     */
    inline DescribeDataSharesForConsumerRequest& WithConsumerArn(const char* value) { SetConsumerArn(value); return *this;}

    /**
     *
An identifier giving the status of a datashare in the consumer cluster. If
     * this field is specified, Amazon Redshift returns the list of datashares that
     * have the specified status.

     */
    inline const DataShareStatusForConsumer& GetStatus() const{ return m_status; }

    /**
     *
An identifier giving the status of a datashare in the consumer cluster. If
     * this field is specified, Amazon Redshift returns the list of datashares that
     * have the specified status.

     */
    inline bool StatusHasBeenSet() const { return m_statusHasBeenSet; }

    /**
     *
An identifier giving the status of a datashare in the consumer cluster. If
     * this field is specified, Amazon Redshift returns the list of datashares that
     * have the specified status.

     */
    inline void SetStatus(const DataShareStatusForConsumer& value) { m_statusHasBeenSet = true; m_status = value; }

    /**
     *
An identifier giving the status of a datashare in the consumer cluster. If
     * this field is specified, Amazon Redshift returns the list of datashares that
     * have the specified status.

     */
    inline void SetStatus(DataShareStatusForConsumer&& value) { m_statusHasBeenSet = true; m_status = std::move(value); }

    /**
     *
An identifier giving the status of a datashare in the consumer cluster. If
     * this field is specified, Amazon Redshift returns the list of datashares that
     * have the specified status.

     */
    inline DescribeDataSharesForConsumerRequest& WithStatus(const DataShareStatusForConsumer& value) { SetStatus(value); return *this;}

    /**
     *
An identifier giving the status of a datashare in the consumer cluster. If
     * this field is specified, Amazon Redshift returns the list of datashares that
     * have the specified status.

     */
    inline DescribeDataSharesForConsumerRequest& WithStatus(DataShareStatusForConsumer&& value) { SetStatus(std::move(value)); return *this;}

    /**
     *
The maximum number of response records to return in each call. If the number
     * of remaining response records exceeds the specified MaxRecords
     * value, a value is returned in a marker field of the response. You
     * can retrieve the next set of records by retrying the command with the returned
     * marker value.

     */
    inline int GetMaxRecords() const{ return m_maxRecords; }

    /**
     *
The maximum number of response records to return in each call. If the number
     * of remaining response records exceeds the specified MaxRecords
     * value, a value is returned in a marker field of the response. You
     * can retrieve the next set of records by retrying the command with the returned
     * marker value.

     */
    inline bool MaxRecordsHasBeenSet() const { return m_maxRecordsHasBeenSet; }

    /**
     *
The maximum number of response records to return in each call. If the number
     * of remaining response records exceeds the specified MaxRecords
     * value, a value is returned in a marker field of the response. You
     * can retrieve the next set of records by retrying the command with the returned
     * marker value.

     */
    inline void SetMaxRecords(int value) { m_maxRecordsHasBeenSet = true; m_maxRecords = value; }

    /**
     *
The maximum number of response records to return in each call. If the number
     * of remaining response records exceeds the specified MaxRecords
     * value, a value is returned in a marker field of the response. You
     * can retrieve the next set of records by retrying the command with the returned
     * marker value.

     */
    inline DescribeDataSharesForConsumerRequest& WithMaxRecords(int value) { SetMaxRecords(value); return *this;}

    /**
     *
An optional parameter that specifies the starting point to return a set of
     * response records. When the results of a DescribeDataSharesForConsumer
     * request exceed the value specified in MaxRecords, AWS returns a
     * value in the Marker field of the response. You can retrieve the
     * next set of response records by providing the returned marker value in the
     * Marker parameter and retrying the request.

     */
    inline const Aws::String& GetMarker() const{ return m_marker; }

    /**
     *
An optional parameter that specifies the starting point to return a set of
     * response records. When the results of a DescribeDataSharesForConsumer
     * request exceed the value specified in MaxRecords, AWS returns a
     * value in the Marker field of the response. You can retrieve the
     * next set of response records by providing the returned marker value in the
     * Marker parameter and retrying the request.

     */
    inline bool MarkerHasBeenSet() const { return m_markerHasBeenSet; }

    /**
     *
An optional parameter that specifies the starting point to return a set of
     * response records. When the results of a DescribeDataSharesForConsumer
     * request exceed the value specified in MaxRecords, AWS returns a
     * value in the Marker field of the response. You can retrieve the
     * next set of response records by providing the returned marker value in the
     * Marker parameter and retrying the request.

     */
    inline void SetMarker(const Aws::String& value) { m_markerHasBeenSet = true; m_marker = value; }

    /**
     *
An optional parameter that specifies the starting point to return a set of
     * response records. When the results of a DescribeDataSharesForConsumer
     * request exceed the value specified in MaxRecords, AWS returns a
     * value in the Marker field of the response. You can retrieve the
     * next set of response records by providing the returned marker value in the
     * Marker parameter and retrying the request.

     */
    inline void SetMarker(Aws::String&& value) { m_markerHasBeenSet = true; m_marker = std::move(value); }

    /**
     *
An optional parameter that specifies the starting point to return a set of
     * response records. When the results of a DescribeDataSharesForConsumer
     * request exceed the value specified in MaxRecords, AWS returns a
     * value in the Marker field of the response. You can retrieve the
     * next set of response records by providing the returned marker value in the
     * Marker parameter and retrying the request.

     */
    inline void SetMarker(const char* value) { m_markerHasBeenSet = true; m_marker.assign(value); }

    /**
     *
An optional parameter that specifies the starting point to return a set of
     * response records. When the results of a DescribeDataSharesForConsumer
     * request exceed the value specified in MaxRecords, AWS returns a
     * value in the Marker field of the response. You can retrieve the
     * next set of response records by providing the returned marker value in the
     * Marker parameter and retrying the request.

     */
    inline DescribeDataSharesForConsumerRequest& WithMarker(const Aws::String& value) { SetMarker(value); return *this;}

    /**
     *
An optional parameter that specifies the starting point to return a set of
     * response records. When the results of a DescribeDataSharesForConsumer
     * request exceed the value specified in MaxRecords, AWS returns a
     * value in the Marker field of the response. You can retrieve the
     * next set of response records by providing the returned marker value in the
     * Marker parameter and retrying the request.

     */
    inline DescribeDataSharesForConsumerRequest& WithMarker(Aws::String&& value) { SetMarker(std::move(value)); return *this;}

    /**
     *
An optional parameter that specifies the starting point to return a set of
     * response records. When the results of a DescribeDataSharesForConsumer
     * request exceed the value specified in MaxRecords, AWS returns a
     * value in the Marker field of the response. You can retrieve the
     * next set of response records by providing the returned marker value in the
     * Marker parameter and retrying the request.

     */
    inline DescribeDataSharesForConsumerRequest& WithMarker(const char* value) { SetMarker(value); return *this;}

  private:

    Aws::String m_consumerArn;
    bool m_consumerArnHasBeenSet;

    DataShareStatusForConsumer m_status;
    bool m_statusHasBeenSet;

    int m_maxRecords;
    bool m_maxRecordsHasBeenSet;

    Aws::String m_marker;
    bool m_markerHasBeenSet;
  };

} // namespace Model
} // namespace Redshift
} // namespace Aws


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>
Uses of Class org.quartz.JobDataMap (Quartz Enterprise Job Scheduler 2.2.0 API)
</TITLE>

<META NAME="date" CONTENT="2013-06-29">

<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">

      Overview
      Package
      Class
    Use
      Tree
      Deprecated
      Index
      Help

 PREV
 NEXT

  FRAMES
 NO FRAMES

  All Classes

Uses of Class
org.quartz.JobDataMap

Packages that use JobDataMap

org.quartz
The main package of Quartz, containing the client-side interfaces.

org.quartz.core
Contains the core classes and interfaces for the Quartz job scheduler.

org.quartz.core.jmx

org.quartz.impl
Contains implementations of the SchedulerFactory, JobStore, ThreadPool, and
other interfaces required by the org.quartz.core.QuartzScheduler.

org.quartz.impl.jdbcjobstore

org.quartz.impl.triggers
This package contains Trigger implementations that ship with Quartz.

org.quartz.jobs.ee.ejb

org.quartz.jobs.ee.jms

org.quartz.jobs.ee.mail

org.quartz.simpl
Contains simple / light-weight implementations (with no dependencies on
external libraries) of interfaces required by the
org.quartz.core.QuartzScheduler.

org.quartz.spi
Contains Service Provider Interfaces that can be implemented by those
wishing to create and use custom versions of Quartz back-end/behind-the-scenes
services.

org.terracotta.quartz.wrappers

Uses of JobDataMap in org.quartz

Methods in org.quartz that return JobDataMap

 JobDataMap
Trigger.getJobDataMap()

          Get the JobDataMap that is associated with the
 Trigger.

 JobDataMap
JobDetail.getJobDataMap()

 Get the JobDataMap that is associated with the Job.

 JobDataMap
JobExecutionContext.getMergedJobDataMap()

 Get the convenience JobDataMap of this execution context.

Methods in org.quartz with parameters of type JobDataMap

 JobBuilder
JobBuilder.setJobData(JobDataMap newJobDataMap)

          Replace the JobDetail's JobDataMap with the
 given JobDataMap.

 void
Scheduler.triggerJob(JobKey jobKey,
           JobDataMap data)

          Trigger the identified JobDetail
 (execute it now).

 TriggerBuilder<T>
TriggerBuilder.usingJobData(JobDataMap newJobDataMap)

          Set the Trigger's JobDataMap, adding any values to it
 that were already set on this TriggerBuilder using any of the
 other 'usingJobData' methods.

 JobBuilder
JobBuilder.usingJobData(JobDataMap newJobDataMap)

          Add all the data from the given JobDataMap to the
 JobDetail's JobDataMap.

Uses of JobDataMap in org.quartz.core

Methods in org.quartz.core with parameters of type JobDataMap

 void
RemotableQuartzScheduler.triggerJob(JobKey jobKey,
           JobDataMap data)

 void
QuartzScheduler.triggerJob(JobKey jobKey,
           JobDataMap data)

 Trigger the identified Job (execute it
 now) - with a non-volatile trigger.

Uses of JobDataMap in org.quartz.core.jmx

Methods in org.quartz.core.jmx that return JobDataMap

static JobDataMap
JobDataMapSupport.newJobDataMap(Map<String,Object> map)

static JobDataMap
JobDataMapSupport.newJobDataMap(TabularData tabularData)

Methods in org.quartz.core.jmx with parameters of type JobDataMap

static TabularData
JobDataMapSupport.toTabularData(JobDataMap jobDataMap)

Uses of JobDataMap in org.quartz.impl

Methods in org.quartz.impl that return JobDataMap

 JobDataMap
JobDetailImpl.getJobDataMap()

 JobDataMap
JobExecutionContextImpl.getMergedJobDataMap()

 Get the convenience JobDataMap of this execution context.

Methods in org.quartz.impl with parameters of type JobDataMap

 void
JobDetailImpl.setJobDataMap(JobDataMap jobDataMap)

 Set the JobDataMap to be associated with the Job.

 void
StdScheduler.triggerJob(JobKey jobKey,
           JobDataMap data)

 Calls the equivalent method on the 'proxied' QuartzScheduler.

 void
RemoteScheduler.triggerJob(JobKey jobKey,
           JobDataMap data)

 Calls the equivalent method on the 'proxied' QuartzScheduler.

 void
RemoteMBeanScheduler.triggerJob(JobKey jobKey,
           JobDataMap data)

 Calls the equivalent method on the 'proxied' QuartzScheduler,
 passing the SchedulingContext associated with this
 instance.

Uses of JobDataMap in org.quartz.impl.jdbcjobstore

Methods in org.quartz.impl.jdbcjobstore that return JobDataMap

 JobDataMap
StdJDBCDelegate.selectTriggerJobDataMap(Connection conn,
                        String triggerName,
                        String groupName)

 Select a trigger's JobDataMap.

 JobDataMap
DriverDelegate.selectTriggerJobDataMap(Connection conn,
                        String triggerName,
                        String groupName)

 Select a trigger's JobDataMap.

Methods in org.quartz.impl.jdbcjobstore with parameters of type JobDataMap

protected  ByteArrayOutputStream
StdJDBCDelegate.serializeJobData(JobDataMap data)

 Remove the transient data from and then create a serialized java.util.ByteArrayOutputStream
 version of a JobDataMap.

Uses of JobDataMap in org.quartz.impl.triggers

Methods in org.quartz.impl.triggers that return JobDataMap

 JobDataMap
AbstractTrigger.getJobDataMap()

 Get the JobDataMap that is associated with the
 Trigger.

Methods in org.quartz.impl.triggers with parameters of type JobDataMap

 void
AbstractTrigger.setJobDataMap(JobDataMap jobDataMap)

 Set the JobDataMap to be associated with the
 Trigger.

Uses of JobDataMap in org.quartz.jobs.ee.ejb

Methods in org.quartz.jobs.ee.ejb with parameters of type JobDataMap

protected  InitialContext
EJBInvokerJob.getInitialContext(JobDataMap jobDataMap)

Uses of JobDataMap in org.quartz.jobs.ee.jms

Methods in org.quartz.jobs.ee.jms with parameters of type JobDataMap

 Message
JmsMessageFactory.createMessage(JobDataMap jobDataMap,
              Session session)

          Creates a javax.jms.Message.

static InitialContext
JmsHelper.getInitialContext(JobDataMap dataMap)

static boolean
JmsHelper.isDestinationSecure(JobDataMap dataMap)

static boolean
JmsHelper.useTransaction(JobDataMap dataMap)

Uses of JobDataMap in org.quartz.jobs.ee.mail

Methods in org.quartz.jobs.ee.mail with parameters of type JobDataMap

protected  String
SendMailJob.getOptionalParm(JobDataMap data,
                String property)

protected  String
SendMailJob.getRequiredParm(JobDataMap data,
                String property,
                String constantName)

protected  SendMailJob.MailInfo
SendMailJob.populateMailInfo(JobDataMap data,
                 SendMailJob.MailInfo mailInfo)

Uses of JobDataMap in org.quartz.simpl

Methods in org.quartz.simpl with parameters of type JobDataMap

protected  void
PropertySettingJobFactory.setBeanProps(Object obj,
             JobDataMap data)

Uses of JobDataMap in org.quartz.spi

Methods in org.quartz.spi with parameters of type JobDataMap

 void
MutableTrigger.setJobDataMap(JobDataMap jobDataMap)

 Set the JobDataMap to be associated with the
 Trigger.

Uses of JobDataMap in org.terracotta.quartz.wrappers

Methods in org.terracotta.quartz.wrappers that return JobDataMap

 JobDataMap
JobWrapper.getJobDataMapClone()

Methods in org.terracotta.quartz.wrappers with parameters of type JobDataMap

 void
JobWrapper.setJobDataMap(JobDataMap newData,
              JobFacade jobFacade)

      Overview
      Package
      Class
    Use
      Tree
      Deprecated
      Index
      Help

 PREV
 NEXT

  FRAMES
 NO FRAMES

  All Classes

Copyright 2001-2013, Terracotta, Inc.


text:
namespace chi {

Result jsonToGraphModule(Context& createInside, const nlohmann::json& input,
                         const std::filesystem::path& fullName, GraphModule** toFill) {
	Result res;

	auto resCtx = res.addScopedContext({{"Loading Module Name", fullName.string()},
	                                    {"Workspace Path", createInside.workspacePath().string()}});

	// create the module
	auto createdModule = createInside.newGraphModule(fullName);
	if (toFill != nullptr) { *toFill = createdModule; }

	// load if it has C enabled
	{
		auto iter = input.find("has_c_support");
		if (iter == input.end()) {
			res.addEntry("EUKN", "No has_c_support section in module JSON, assuming none", {});
			return res;
		}
		if (!iter->is_boolean()) {
			res.addEntry("EUKN", "has_c_support section in module JSON isn't a bool",
			             {{"Actual Data", *iter}});
			return res;
		}

		createdModule->setCEnabled(*iter);
	}

	// load dependencies
	{
		auto iter = input.find("dependencies");
		if (iter == input.end()) {
			res.addEntry("E38", "No dependencies element in module", {});
			return res;
		}
		if (!iter->is_array()) {
			res.addEntry("E39", "dependencies element isn't an array", {});
			return res;
		}

		for (const auto& dep : *iter) {
			if (!dep.is_string()) {
				res.addEntry("E40", "dependency isn't a string", {{"Actual Data", dep}});
				continue;
			}

			std::string depName = dep;
			res += createdModule->addDependency(depName);

			if (!res) { return res; }
		}
	}

	// load types
	{
		auto iter = input.find("types");
		if (iter == input.end() || !iter->is_object()) {
			res.addEntry("EUKN", "No types object in module", {});
			return res;
		}

		// declare them
		for (auto tyIter = iter->begin(); tyIter != iter->end(); ++tyIter) {
			createdModule->getOrCreateStruct(tyIter.key());
		}
		// load them
		for (auto tyIter = iter->begin(); tyIter != iter->end(); ++tyIter) {
			res += jsonToGraphStruct(*createdModule, tyIter.key(), tyIter.value());
		}
	}

	// load graphs
	{
		auto iter = input.find("graphs");
		if (iter == input.end()) {
			res.addEntry("E41", "no graphs element in module", {});
			return res;
		}
		if (!iter->is_array()) {
			res.addEntry("E42", "graph element isn't an array", {{"Actual Data", *iter}});
			return res;
		}

		std::vector<GraphFunction*> functions;
		functions.resize(iter->size());

		// create forward declarations
		auto id = 0ull;
		for (const auto& graph : *iter) {
			res += createGraphFunctionDeclarationFromJson(*createdModule, graph, &functions[id]);

			++id;
		}

		if (!res) { return res; }

		// load the graphs
		id = 0;
		for (const auto& graph : *iter) {
			res += jsonToGraphFunction(*functions[id], graph);

			++id;
		}
	}

	return res;
}

Result createGraphFunctionDeclarationFromJson(GraphModule&          createInside,
                                              const nlohmann::json& input, GraphFunction** toFill) {
	Result res;

	if (!input.is_object()) {
		res.addEntry("E1", "Graph json isn't a JSON object", {});
		return res;
	}
	// make sure it has a type element
	if (input.find("type") == input.end() || !input["type"].is_string()) {
		res.addEntry("E2", R"(JSON in graph doesn't have a "type" element)",
		             {{"Module Name", createInside.fullName()}});
		return res;
	}
	if (input["type"] != "function") {
		res.addEntry("E3", "JSON in graph doesn't have a function type",
		             {{"Module Name", createInside.fullName()}});
		return res;
	}
	// make sure there is a name
	if (input.find("name") == input.end() || !input["name"].is_string()) {
		res.addEntry("E4", "JSON in graph doesn't have a name parameter",
		             {{"Module Name", createInside.fullName()}});
		return res;
	}
	std::string name = input["name"];

	// load the description
	if (input.find("description") == input.end() || !input["description"].is_string()) {
		res.addEntry("E50", "JSON in graph doesn't have a description string",
		             {{"Function Name", name}, {"Module Name", createInside.fullName()}});
		return res;
	}
	std::string description = input["description"];

	if (input.find("data_inputs") == input.end() || !input["data_inputs"].is_array()) {
		res.addEntry("E43", "JSON in graph doesn't have an data_inputs array", {});
		return res;
	}

	std::vector<NamedDataType> datainputs;
	for (auto param : input["data_inputs"]) {
		std::string docString, qualifiedType;
		std::tie(docString, qualifiedType) = parseObjectPair(param);

		std::string moduleName, name;
		std::tie(moduleName, name) = parseColonPair(qualifiedType);

		DataType ty;
		res += createInside.context().typeFromModule(moduleName, name, &ty);

		if (!res) { return res; }

		datainputs.emplace_back(docString, ty);
	}

	if (input.find("data_outputs") == input.end() || !input["data_outputs"].is_array()) {
		res.addEntry("E44", "JSON in graph doesn't have an data_outputs array", {});
		return res;
	}

	std::vector<NamedDataType> dataoutputs;
	for (auto param : input["data_outputs"]) {
		std::string docString, qualifiedType;
		std::tie(docString, qualifiedType) = parseObjectPair(param);

		std::string moduleName, name;
		std::tie(moduleName, name) = parseColonPair(qualifiedType);

		DataType ty;
		res += createInside.context().typeFromModule(moduleName, name, &ty);

		if (!res) { return res; }

		dataoutputs.emplace_back(docString, ty);
	}

	// get exec I/O
	if (input.find("exec_inputs") == input.end() || !input["exec_inputs"].is_array()) {
		res.addEntry("E48", "JSON in graph doesn't have an exec_inputs array", {});
		return res;
	}

	std::vector<std::string> execinputs;
	for (const auto& param : input["exec_inputs"]) {
		std::string name = param;

		execinputs.emplace_back(name);
	}

	if (input.find("exec_outputs") == input.end() || !input["exec_outputs"].is_array()) {
		res.addEntry("E49", "JSON in graph doesn't have an data_outputs array", {});
		return res;
	}

	std::vector<std::string> execoutputs;
	for (const auto& param : input["exec_outputs"]) {
		std::string name = param;

		execoutputs.emplace_back(name);
	}

	// construct it
	auto created =
	    createInside.getOrCreateFunction(name, datainputs, dataoutputs, execinputs, execoutputs);
	created->setDescription(std::move(description));
	if (toFill != nullptr) { *toFill = created; }

	return res;
}

Result jsonToGraphFunction(GraphFunction& createInside, const nlohmann::json& input) {
	Result res;

	// read the local variables
	if (input.find("local_variables") == input.end() || !input["local_variables"].is_object()) {
		res.addEntry("E45", "JSON in graph doesn't have a local_variables object", {});

		return res;
	}

	for (auto localiter = input["local_variables"].begin();
	     localiter != input["local_variables"].end(); ++localiter) {
		std::string localName = localiter.key();

		if (!localiter.value().is_string()) {
			res.addEntry("E46", "Local variable vaue in json wasn't a string",
			             {{"Given local variable json", localiter.value()}});

			continue;
		}

		// parse the type names
		std::string qualifiedType = localiter.value();

		std::string moduleName, typeName;
		std::tie(moduleName, typeName) = parseColonPair(qualifiedType);

		DataType ty;
		res += createInside.context().typeFromModule(moduleName, typeName, &ty);

		if (!res) { continue; }

		createInside.getOrCreateLocalVariable(localName, ty);
	}

	// read the nodes
	if (input.find("nodes") == input.end() || !input["nodes"].is_object()) {
		res.addEntry("E5", "JSON in graph doesn't have nodes object", {});
		return res;
	}

	for (auto nodeiter = input["nodes"].begin(); nodeiter != input["nodes"].end(); ++nodeiter) {
		auto        node   = nodeiter.value();
		std::string nodeid = nodeiter.key();
		if (node.find("type") == node.end() || !node.find("type")->is_string()) {
			res.addEntry("E6", R"(Node doesn't have a "type" string)", {{"Node ID", nodeid}});
			return res;
		}
		std::string fullType = node["type"];
		std::string moduleName, typeName;
		std::tie(moduleName, typeName) = parseColonPair(fullType);

		if (moduleName.empty() || typeName.empty()) {
			res.addEntry("E7", "Incorrect qualified module name (should be module:type)",
			             {{"Node ID", nodeid}, {"Requested Qualified Name", fullType}});
			return res;
		}

		if (node.find("data") == node.end()) {
			res.addEntry("E9", "Node doens't have a data section", {{"Node ID", nodeid}});
			return res;
		}

		std::unique_ptr<NodeType> nodeType;
		res += createInside.context().nodeTypeFromModule(moduleName, typeName, node["data"],
		                                                 &nodeType);
		if (!res) { continue; }

		auto testIter = node.find("location");
		if (testIter == node.end()) {
			res.addEntry("E12", "Node doesn't have a location.", {{"Node ID", nodeid}});
			continue;
		}

		// make sure it is the right size
		if (!testIter.value().is_array()) {
			res.addEntry("E10", "Node doesn't have a location that is an array.",
			             {{"Node ID", nodeid}});
			continue;
		}

		if (testIter.value().size() != 2) {
			res.addEntry("E11", "Node doesn't have a location that is an array of size 2.",
			             {{"Node ID", nodeid}});
			continue;
		}

		auto uuidNodeID = Uuid::fromString(nodeid);
		if (uuidNodeID.has_value()) {
			createInside.insertNode(std::move(nodeType), node["location"][0], node["location"][1],
			                        *uuidNodeID);
		} else {
			res.addEntry("E51", "Invalid UUID string", {{"string", nodeid}});
		}
	}

	// read the connections
	{
		auto connIter = input.find("connections");
		if (connIter == input.end() || !connIter->is_array()) {
			res.addEntry("E13", "No connections array in function", {});
			return res;
		}

		auto connID = 0ull;
		for (auto& connection : input["connections"]) {
			if (connection.find("type") == connection.end() ||
			    !connection.find("type")->is_string()) {
				res.addEntry("E14", "No type string in connection", {{"connectionid", connID}});

				++connID;
				continue;
			}
			std::string type   = connection["type"];
			bool        isData = type == "data";
			// it either has to be "input" or "exec"
			if (!isData && type != "exec") {
				res.addEntry("E15", "Unrecognized connection type",
				             {{"connectionid", connID}, {"Found Type", type}});

				++connID;
				continue;
			}

			if (connection.find("input") == connection.end()) {
				res.addEntry("E16", "No input element in connection", {{"connectionid", connID}});

				++connID;
				continue;
			}
			if (!connection.find("input")->is_array() || connection.find("input")->size() != 2 ||
			    !connection.find("input")->operator[](0).is_string() ||
			    !connection.find("input")->operator[](1).is_number_integer()) {
				res.addEntry(
				    "E17",
				    "Incorrect connection input format, must be an array of of a string (node id) "
				    "and int (connection id)",
				    {{"connectionid", connID}, {"Requested Type", *connection.find("input")}});

				++connID;
				continue;
			}
			std::string InputNodeID = connection["input"][0];

			auto InputNodeIDUUID = Uuid::fromString(InputNodeID);
			if (!InputNodeIDUUID.has_value()) {
				res.addEntry("EUKN", "Invalid UUID string in connection",
				             {{"string", InputNodeID}});

				++connID;
				continue;
			}
			int InputConnectionID = connection["input"][1];

			if (connection.find("output") == connection.end()) {
				res.addEntry("E18", "No output element in connection", {{"connectionid", connID}});

				++connID;
				continue;
			}
			if (!connection.find("output")->is_array() || connection.find("output")->size() != 2 ||
			    !connection.find("output")->operator[](0).is_string() ||
			    !connection.find("output")->operator[](1).is_number_integer()) {
				res.addEntry(
				    "E19",
				    "Incorrect connection output format, must be an array of a string (node id) "
				    "and int (connection id)",
				    {{"connectionid", connID}, {"Requested Type", *connection.find("output")}});
				++connID;
				continue;
			}
			std::string OutputNodeID = connection["output"][0];

			auto OutputNodeIDUUID = Uuid::fromString(OutputNodeID);
			if (!OutputNodeIDUUID.has_value()) {
				res.addEntry("EUKN", "Invalid UUID string in connection",
				             {{"string", OutputNodeID}});

				++connID;
				continue;
			}
			int OutputConnectionID = connection["output"][1];

			// make sure the nodes exist
			if (createInside.nodes().find(*InputNodeIDUUID) == createInside.nodes().end()) {
				res.addEntry("E20", "Input node for connection doesn't exist",
				             {{"connectionid", connID}, {"Requested Node", InputNodeID}});
				++connID;
				continue;
			}
			if (createInside.nodes().find(*OutputNodeIDUUID) == createInside.nodes().end()) {
				res.addEntry("E21", "Output node for connection doesn't exist",
				             {{"connectionid", connID}, {"Requested Node", OutputNodeID}});
				++connID;
				continue;
			}

			// connect
			// these functions do bounds checking, it's okay
			if (isData) {
				res += connectData(*createInside.nodes()[*InputNodeIDUUID], InputConnectionID,
				                   *createInside.nodes()[*OutputNodeIDUUID], OutputConnectionID);
			} else {
				res += connectExec(*createInside.nodes()[*InputNodeIDUUID], InputConnectionID,
				                   *createInside.nodes()[*OutputNodeIDUUID], OutputConnectionID);
			}

			++connID;
		}
	}
	return res;
}  // namespace chi

Result jsonToGraphStruct(GraphModule& mod, std::string_view name, const nlohmann::json& input,
                         GraphStruct** toFill) {
	Result res;

	if (!input.is_array()) {
		res.addEntry("EUKN", "Graph Struct json has to be an array", {{"Given JSON", input}});
		return res;
	}

	auto createdStruct = mod.getOrCreateStruct(std::string(name));
	if (toFill != nullptr) { *toFill = createdStruct; }

	for (const auto& str : input) {
		if (!str.is_object()) {
			res.addEntry("EUKN", "Graph Struct entry must be an object", {{"Given JSON", str}});
			continue;
		}

		if (str.size() != 1) {
			res.addEntry("EUKN", "Graph Struct entry must have size of 1", {{"Size", str.size()}});
			continue;
		}

		std::string docstring, qualifiedType;
		std::tie(docstring, qualifiedType) = parseObjectPair(str);

		// parse the type
		std::string typeModuleName, typeName;
		std::tie(typeModuleName, typeName) = parseColonPair(qualifiedType);

		DataType ty;
		res += mod.context().typeFromModule(typeModuleName, typeName, &ty);

		if (!res) { continue; }

		createdStruct->addType(ty, docstring, createdStruct->types().size());
	}

	return res;
}

std::pair<std::string, std::string> parseObjectPair(const nlohmann::json& object) {
	if (!object.is_object()) { return {}; }

	auto iter = object.begin();
	if (iter == object.end()) { return {}; }

	std::string key = iter.key();
	std::string val = iter.value();

	// make sure it's the only element
	++iter;
	if (iter != object.end()) { return {}; }

	return {key, val};
}
}  // namespace chi


text:
package com.ukefu.webim.service.repository;

import java.util.Date;
import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import com.ukefu.webim.web.model.OnlineUser;

public abstract interface OnlineUserRepository extends JpaRepository<OnlineUser, String> {
	public abstract OnlineUser findBySessionidAndOrgi(String paramString, String orgi);

	public abstract List<OnlineUser> findByUseridAndOrgi(String userid, String orgi);

	public abstract int countByUseridAndOrgi(String userid, String orgi);

	public abstract Page<OnlineUser> findByUseridAndOrgi(String userid, String orgi , Pageable page);

	public abstract OnlineUser findByOrgiAndSessionid(String orgi , String sessionid);

	public abstract Page<OnlineUser> findByOrgiAndStatusAndCreatetimeLessThan(String orgi , String status , Date createtime , Pageable paramPageable);

	public abstract Page<OnlineUser> findByOrgiAndStatus(String paramString1,String paramString2, Pageable paramPageable);

	@Query("select invitestatus , count(id) as users from OnlineUser where orgi = ?1 and status = ?2 group by invitestatus")
	List<Object> findByOrgiAndStatus(String orgi ,String status);

	@Query("select result , count(id) as records from InviteRecord where orgi = ?1 and agentno = ?2 and createtime > ?3 and createtime < ?4 group by result")
	List<Object> findByOrgiAndAgentnoAndCreatetimeRange(String orgi ,String agentno , Date start , Date end);

	@Query("select result , count(id) as records from InviteRecord where orgi = ?1 and agentno = ?2 group by result")
	List<Object> findByOrgiAndUserid(String orgi ,String userid);

	@Query("select count(id) from AgentService where orgi = ?1 and status = ?2 and agentno = ?3 and createtime > ?4 and createtime < ?5")
	Long countByAgentForAgentUser(String orgi ,String status,String agentno , Date start , Date end);

	@Query("select count(id) from AgentService where orgi = ?1 and status = ?2 and agentno = ?3 and createtime > ?4 and createtime < ?5")
	Long countByAgentForAgentService(String orgi ,String status,String agentno , Date start , Date end);

	@Query("select avg(sessiontimes) from AgentService where orgi = ?1 and status = ?2 and agentno = ?3 and createtime > ?4 and createtime < ?5")
	Long countByAgentForAvagTime(String orgi ,String status,String agentno , Date start , Date end);

	@Query("select avg(sessiontimes) from AgentService where orgi = ?1 and status = ?2 and userid = ?3")
	Long countByUserForAvagTime(String orgi ,String status,String userid);

	@Query("select createdate as dt, count(distinct ip) as ips ,  count(id) as records from UserHistory where orgi = ?1 and model = ?2 and createtime > ?3 and createtime < ?4 group by createdate order by dt asc")
	List<Object> findByOrgiAndCreatetimeRange(String orgi , String model ,Date start , Date end);

	@Query("select createdate as dt, count(id) as users from AgentService where orgi = ?1 and createtime > ?2 and createtime < ?3 group by createdate order by dt asc")
	List<Object> findByOrgiAndCreatetimeRangeForAgent(String orgi , Date start , Date end);

	@Query("select osname, count(id) as users from AgentService where orgi = ?1 and createtime > ?2 and createtime < ?3 and channel = ?4 group by osname")
	List<Object> findByOrgiAndCreatetimeRangeForClient(String orgi , Date start , Date end , String channel);

	@Query("select browser, count(id) as users from AgentService where orgi = ?1 and createtime > ?2 and createtime < ?3 and channel = ?4 group by browser")
	List<Object> findByOrgiAndCreatetimeRangeForBrowser(String orgi , Date start , Date end , String channel);

	@Query("select agentno, count(id) as users from AgentService where orgi = ?1 and userid = ?2 group by agentno")
	List<Object> findByOrgiForDistinctAgent(String orgi , String userid);

	@Query("select count(id) from AgentService where orgi = ?1 and appid = ?2 and createtime > ?3 and createtime < ?4")
	Long countByOrgiAndAppidForCount(String orgi ,String appid ,Date start,Date end);

	@Query("select count(id) from StatusEvent where ani = ?1 and direction = ?2")
	Long countByAniFromCallCenter(String ani , String direction);

	@Query("select count(id) from StatusEvent where ani = ?1")
	Long countByAniFromCallCenter(String ani);

	@Query("select avg(ringduration) from StatusEvent where ani = ?1")
	Long avgByRingDurationFromCallCenter(String ani);

	@Query("select avg(duration) from StatusEvent where ani = ?1")
	Long avgByDurationFromCallCenter(String ani);

}


text:
module Control.Concurrent.Object
    ( Class(..), Object, Self(..), CallbackModule(..)
    , ObjectLike(..)
    ) where

import Prelude hiding (init, mod)
import Control.Exception
import Control.Concurrent
import Control.Concurrent.STM
import Control.Concurrent.Object.Internal

instance ObjectLike IO (Object msg reply) where
    type OMessage (Object msg reply) = msg
    type OReply (Object msg reply) = reply
    type OClass (Object msg reply) = Class msg reply

    new = newObject

    obj ! msg = atomically $ writeTChan (objChan obj) (msg, Nothing)

    obj !? msg = do
        mv <- newEmptyMVar
        atomically $ writeTChan (objChan obj) (msg, Just mv)
        -- TODO: timeout
        return $ readMVar mv

    kill obj = killThread $ objThreadId obj

instance ObjectLike IO (Self msg reply state) where
    type OMessage (Self msg reply state) = msg
    type OReply (Self msg reply state) = reply
    type OClass (Self msg reply state) = Class msg reply

    -- | Self should not be made by itself.
    new = error "Self cannot be made"

    self ! msg = do
        _ <- runCallbackModule self msg
        return ()

    self !? msg = do
        (reply, _self') <- runCallbackModule self msg
        mv <- newMVar reply
        return $ readMVar mv

    kill self = killThread $ selfThreadId self


text:
package com.amazonaws.services.cognitoidp.model.transform;

import javax.annotation.Generated;

import com.amazonaws.SdkClientException;
import com.amazonaws.services.cognitoidp.model.*;

import com.amazonaws.protocol.*;
import com.amazonaws.annotation.SdkInternalApi;

/**
 * PasswordPolicyTypeMarshaller
 */
@Generated("com.amazonaws:aws-java-sdk-code-generator")
@SdkInternalApi
public class PasswordPolicyTypeMarshaller {

    private static final MarshallingInfo<Integer> MINIMUMLENGTH_BINDING = MarshallingInfo.builder(MarshallingType.INTEGER)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("MinimumLength").build();
    private static final MarshallingInfo<Boolean> REQUIREUPPERCASE_BINDING = MarshallingInfo.builder(MarshallingType.BOOLEAN)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("RequireUppercase").build();
    private static final MarshallingInfo<Boolean> REQUIRELOWERCASE_BINDING = MarshallingInfo.builder(MarshallingType.BOOLEAN)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("RequireLowercase").build();
    private static final MarshallingInfo<Boolean> REQUIRENUMBERS_BINDING = MarshallingInfo.builder(MarshallingType.BOOLEAN)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("RequireNumbers").build();
    private static final MarshallingInfo<Boolean> REQUIRESYMBOLS_BINDING = MarshallingInfo.builder(MarshallingType.BOOLEAN)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("RequireSymbols").build();
    private static final MarshallingInfo<Integer> TEMPORARYPASSWORDVALIDITYDAYS_BINDING = MarshallingInfo.builder(MarshallingType.INTEGER)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("TemporaryPasswordValidityDays").build();

    private static final PasswordPolicyTypeMarshaller instance = new PasswordPolicyTypeMarshaller();

    public static PasswordPolicyTypeMarshaller getInstance() {
        return instance;
    }

    /**
     * Marshall the given parameter object.
     */
    public void marshall(PasswordPolicyType passwordPolicyType, ProtocolMarshaller protocolMarshaller) {

        if (passwordPolicyType == null) {
            throw new SdkClientException("Invalid argument passed to marshall(...)");
        }

        try {
            protocolMarshaller.marshall(passwordPolicyType.getMinimumLength(), MINIMUMLENGTH_BINDING);
            protocolMarshaller.marshall(passwordPolicyType.getRequireUppercase(), REQUIREUPPERCASE_BINDING);
            protocolMarshaller.marshall(passwordPolicyType.getRequireLowercase(), REQUIRELOWERCASE_BINDING);
            protocolMarshaller.marshall(passwordPolicyType.getRequireNumbers(), REQUIRENUMBERS_BINDING);
            protocolMarshaller.marshall(passwordPolicyType.getRequireSymbols(), REQUIRESYMBOLS_BINDING);
            protocolMarshaller.marshall(passwordPolicyType.getTemporaryPasswordValidityDays(), TEMPORARYPASSWORDVALIDITYDAYS_BINDING);
        } catch (Exception e) {
            throw new SdkClientException("Unable to marshall request to JSON: " + e.getMessage(), e);
        }
    }

}


text:
require 'sequel'
require 'rack/test'
require 'json'
require 'uri'
require_relative '../../spec_helper'
require_relative '../../../app/controllers/api/json/visualizations_controller'
require_relative '../../../services/data-repository/backend/sequel'
require_relative '../../../app/models/visualization/migrator'
require_relative '../../../app/models/overlay/migrator'

def app
  CartoDB::Application.new
end

# INFO: THIS TEST SUITE SHOULD NOT GET NEW TESTS. In order to test visualization controller
# add the specs to ./spec/requests/api/json/visualizations_controller_shared_examples.rb instead.
# You can then run it with ./spec/requests/api/json/visualizations_controller_specs.rb and
# ./spec/requests/carto/api/visualizations_controller_specs.rb.
describe Api::Json::VisualizationsController do
  include Rack::Test::Methods
  include DataRepository

  before(:all) do
    CartoDB::Varnish.any_instance.stubs(:send_command).returns(true)
    @user = create_user(
      username: 'test',
      email:    'client@example.com',
      password: 'clientex',
      private_tables_enabled: 'true'
    )
    @api_key = @user.api_key
  end

  before(:each) do
    CartoDB::Varnish.any_instance.stubs(:send_command).returns(true)
    stub_named_maps_calls
    @db = Rails::Sequel.connection
    Sequel.extension(:pagination)

    CartoDB::Visualization.repository = DataRepository::Backend::Sequel.new(@db, :visualizations)
    CartoDB::Overlay.repository       = DataRepository::Backend::Sequel.new(@db, :overlays)

    begin
      delete_user_data @user
    rescue => exception
      # Silence named maps problems only here upon data cleaning, not in specs
      raise unless exception.class.to_s == 'CartoDB::NamedMapsWrapper::HTTPResponseError'
    end

    @headers = {
      'CONTENT_TYPE'  => 'application/json',
    }
    host! 'test.localhost.lan'
  end

  after(:all) do
    stub_named_maps_calls
    @user.destroy
  end

  describe 'POST /api/v1/viz' do
    it 'creates a visualization' do
      pending
      payload = factory.merge(type: 'table')

      post "/api/v1/viz?api_key=#{@api_key}",
            payload.to_json, @headers

      last_response.status.should == 200
      response = JSON.parse(last_response.body)
      response.fetch('name')        .should =~ /visualization/
      response.fetch('tags')        .should == payload.fetch(:tags)
      response.fetch('map_id')      .should == payload.fetch(:map_id)
      response.fetch('description') .should == payload.fetch(:description)

      id      = response.fetch('id')
      map_id  = response.fetch('map_id')

      get "/api/v1/viz/#{id}?api_key=#{@api_key}",
        {}, @headers
      last_response.status.should ==  200

      response = JSON.parse(last_response.body)
      response.fetch('name')        .should_not == nil
      response.fetch('tags')        .should_not == payload.fetch(:tags).to_json
      response.keys.should_not include 'related'

      payload = { kind: 'carto', order: 1 }
      post "/api/v1/maps/#{map_id}/layers?api_key=#{@api_key}",
        payload.to_json, @headers
      last_response.status.should == 200

      payload = { kind: 'carto', order: 2 }
      post "/api/v1/maps/#{map_id}/layers?api_key=#{@api_key}",
        payload.to_json, @headers
      last_response.status.should == 400
    end

    it 'creates a visualization from a source_visualization_id' do
      pending
      table                 = table_factory
      source_visualization  = table.fetch('table_visualization')

      payload = { source_visualization_id: source_visualization.fetch('id') }

      post "/api/v1/viz?api_key=#{@api_key}",
        payload.to_json, @headers

      last_response.status.should == 200
    end

    it 'creates a private visualization from a private table' do
      pending
      table1 = table_factory(privacy: 0)
      source_visualization_id = table1.fetch('table_visualization').fetch('id')
      payload = { source_visualization_id: source_visualization_id }

      post "/api/v1/viz?api_key=#{@api_key}", payload.to_json, @headers
      last_response.status.should == 200

      visualization = JSON.parse(last_response.body)
      visualization.fetch('privacy').should == 'PRIVATE'
    end

    it 'creates a private visualization if any table in the list is private' do
      pending
      table3 = table_factory(privacy: 0)

      payload = {
        name: 'new visualization',
        tables: [table3.fetch('name')]
      }

      post "/api/v1/viz?api_key=#{@api_key}", payload.to_json, @headers
      last_response.status.should == 200

      visualization = JSON.parse(last_response.body)
      visualization.fetch('privacy').should == 'PRIVATE'
    end

    it 'creates a private visualization if any table in the list is private' do
      pending
      table1 = table_factory
      table2 = table_factory
      table3 = table_factory(privacy: 0)

      payload = {
        name: 'new visualization',
        tables: [
          table1.fetch('name'),
          table2.fetch('name'),
          table3.fetch('name')
        ],
        privacy: 'public'
      }

      post "/api/v1/viz?api_key=#{@api_key}", payload.to_json, @headers
      last_response.status.should == 200

      visualization = JSON.parse(last_response.body)
      visualization.fetch('privacy').should == 'PRIVATE'
    end

    it 'assigns a generated name if name taken' do
      pending
      table               = table_factory
      visualization       = table.fetch('table_visualization')
      visualization_name  = visualization.fetch('name')

      payload = {
        source_visualization_id:  visualization.fetch('id'),
        name:                     visualization_name
      }

      post "/api/v1/viz?api_key=#{@api_key}",
        payload.to_json, @headers
      last_response.status.should == 200

      response  = JSON.parse(last_response.body)
      response.fetch('name').should =~ /#{visualization_name} 0/
    end
  end # POST /api/v1/viz

  describe 'PUT /api/v1/viz/:id' do
    it 'updates an existing visualization' do
      pending
      payload   = factory
      post "/api/v1/viz?api_key=#{@api_key}",
        payload.to_json, @headers

      response  =  JSON.parse(last_response.body)
      id        = response.fetch('id')
      tags      = response.fetch('tags')

      response.fetch('tags').should == ['foo', 'bar']

      put "/api/v1/viz/#{id}?api_key=#{@api_key}",
        { name: 'changed', tags: [] }.to_json, @headers
      last_response.status.should == 200
      response = JSON.parse(last_response.body)
      response.fetch('name').should == 'changed'
      response.fetch('tags').should == []
    end

    it 'updates the table in a table visualization', now: true do
      pending
      table_attributes = table_factory
      id = table_attributes.fetch('table_visualization').fetch('id')

      sleep(0.6)
      put "/api/v1/viz/#{id}?api_key=#{@api_key}",
        { name: 'changed name' }.to_json, @headers
      last_response.status.should == 200
      response = JSON.parse(last_response.body)

      response.fetch('table').fetch('updated_at')
        .should_not == table_attributes.fetch('updated_at')
    end

    it 'allows setting the active layer' do
      pending
      payload   = factory
      post "/api/v1/viz?api_key=#{@api_key}",
        payload.to_json, @headers

      response  =  JSON.parse(last_response.body)
      id        = response.fetch('id')
      tags      = response.fetch('tags')

      response.fetch('tags').should == ['foo', 'bar']

      active_layer_id = 8
      put "/api/v1/viz/#{id}?api_key=#{@api_key}",
        { active_layer_id: active_layer_id }.to_json, @headers
      last_response.status.should == 200
      response = JSON.parse(last_response.body)
      response.fetch('active_layer_id').should == active_layer_id
      response.fetch('tags').should == ['foo', 'bar']
    end

    it 'returns a sanitized name' do
      pending
      table_attributes = table_factory
      id = table_attributes.fetch('table_visualization').fetch('id')

      put "/api/v1/viz/#{id}?api_key=#{@api_key}",
        { name: 'changed name' }.to_json, @headers
      last_response.status.should == 200
      response = JSON.parse(last_response.body)
      response.fetch('name').should == 'changed_name'

      get "/api/v1/viz/#{id}?api_key=#{@api_key}", {}, @headers
      response = JSON.parse(last_response.body)
      response.fetch('name').should == 'changed_name'
    end
  end # PUT /api/v1/viz/:id

  describe 'DELETE /api/v1/viz/:id' do
    it 'deletes the visualization' do
      pending
      payload   = factory
      post "/api/v1/viz?api_key=#{@api_key}",
        payload.to_json, @headers

      id = JSON.parse(last_response.body).fetch('id')
      get "/api/v1/viz/#{id}?api_key=#{@api_key}",
        {}, @headers
      last_response.status.should == 200

      delete "/api/v1/viz/#{id}?api_key=#{@api_key}",
        {}, @headers
      last_response.status.should == 204
      last_response.body.should be_empty

      get "/api/v1/viz/#{id}?api_key=#{@api_key}",
        {}, @headers
      last_response.status.should == 404
    end

    it 'deletes the associated table' do
      pending
      table_attributes = table_factory
      table_id         = table_attributes.fetch('id')

      get "/api/v1/tables/#{table_id}?api_key=#{@api_key}",
        {}, @headers
      last_response.status.should == 200
      table             = JSON.parse(last_response.body)
      visualization_id  = table.fetch('table_visualization').fetch('id')

      delete "/api/v1/viz/#{visualization_id}?api_key=#{@api_key}",
        {}, @headers
      last_response.status.should == 204

      get "/api/v1/tables/#{table_id}?api_key=#{@api_key}",
        {}, @headers
      last_response.status.should == 404
    end
  end # DELETE /api/v1/viz/:id

  describe 'DELETE /api/v1/tables/:id' do
    it 'deletes the associated table visualization' do
      pending
      table_attributes = table_factory
      table_id         = table_attributes.fetch('id')

      get "/api/v1/tables/#{table_id}?api_key=#{@api_key}",
        {}, @headers
      last_response.status.should == 200
      table             = JSON.parse(last_response.body)
      visualization_id  = table.fetch('table_visualization').fetch('id')

      get "/api/v1/viz/#{visualization_id}?api_key=#{@api_key}",
        {}, @headers
      last_response.status.should == 200

      delete "/api/v1/tables/#{table_id}?api_key=#{@api_key}",
        {}, @headers

      get "/api/v1/viz/#{visualization_id}?api_key=#{@api_key}",
        {}, @headers
      last_response.status.should == 404
    end

    it 'deletes dependent visualizations' do
      pending
      table_attributes = table_factory
      table_id         = table_attributes.fetch('id')

      get "/api/v1/tables/#{table_id}?api_key=#{@api_key}",
        {}, @headers
      last_response.status.should == 200
      table                   = JSON.parse(last_response.body)
      source_visualization_id = table.fetch('table_visualization').fetch('id')

      payload = { source_visualization_id: source_visualization_id }

      post "/api/v1/viz?api_key=#{@api_key}", payload.to_json, @headers
      response          = JSON.parse(last_response.body)
      visualization_id  = response.fetch('id')

      get "/api/v1/viz/#{visualization_id}?api_key=#{@api_key}", {}, @headers
      last_response.status.should == 200

      delete "/api/v1/tables/#{table_id}?api_key=#{@api_key}", {}, @headers

      get "/api/v1/viz/#{visualization_id}?api_key=#{@api_key}", {}, @headers
      last_response.status.should == 404

      get "/api/v1/viz/#{source_visualization_id}?api_key=#{@api_key}",
        {}, @headers
      last_response.status.should == 404
    end

    it 'removes the layer from non dependent visualizations' do
      pending
      table1    = table_factory
      table2    = table_factory
      table1_id = table1.fetch('id')
      table2_id = table1.fetch('id')

      payload = { tables: [table1.fetch('name'), table2.fetch('name')] }

      post "/api/v1/viz?api_key=#{@api_key}", payload.to_json, @headers
      response          = JSON.parse(last_response.body)
      visualization_id  = response.fetch('id')
      map_id            = response.fetch('map_id')

      get "/api/v1/viz/#{visualization_id}?api_key=#{@api_key}", {}, @headers
      last_response.status.should == 200

      JSON.parse(last_response.body).fetch('related_tables').length
        .should == 2

      get "/api/v1/tables/#{table1_id}?api_key=#{@api_key}", {}, @headers
      table1 = JSON.parse(last_response.body)
      table1.fetch('non_dependent_visualizations').length.should == 1
      table1.fetch('dependent_visualizations').length.should == 0

      get "/api/v1/tables/#{table2_id}?api_key=#{@api_key}", {}, @headers
      table2 = JSON.parse(last_response.body)
      table2.fetch('non_dependent_visualizations').length.should == 1
      table2.fetch('dependent_visualizations').length.should == 0

      delete "/api/v1/tables/#{table1_id}?api_key=#{@api_key}", {}, @headers

      get "/api/v1/tables/#{table1_id}?api_key=#{@api_key}", {}, @headers
      last_response.status.should == 404

      get "/api/v1/viz/#{visualization_id}?api_key=#{@api_key}", {}, @headers
      last_response.status.should == 200
      JSON.parse(last_response.body).fetch('related_tables').length
        .should == 1

      get "/api/v1/maps/#{map_id}/layers?api_key=#{@api_key}", {}, @headers
      JSON.parse(last_response.body).length.should == 2
    end

    it 'removes dependent visualizations that have the same layer twice' do
      pending
      table     = table_factory
      table_id  = table.fetch('id')
      payload   = { tables: [table.fetch('name'), table.fetch('name')] }

      post "/api/v1/viz?api_key=#{@api_key}", payload.to_json, @headers
      response          = JSON.parse(last_response.body)
      visualization_id  = response.fetch('id')
      map_id            = response.fetch('map_id')

      delete "/api/v1/tables/#{table_id}?api_key=#{@api_key}", {}, @headers
      last_response.status.should == 204

      get "/api/v1/tables/#{table_id}?api_key=#{@api_key}", {}, @headers
      last_response.status.should == 404

      get "/api/v1/tables?api_key=#{@api_key}", {}, @headers
      last_response.status.should == 200
    end
  end # DELETE /api/v1/tables/:id

  describe '#slides_sorting' do
    it 'checks proper working of prev/next' do
      CartoDB::NamedMapsWrapper::NamedMaps.any_instance.stubs(:get => nil, :create => true, :update => true, :delete => true)

      map_id = ::Map.create(user_id: @user.id).id

      post api_v1_visualizations_create_url(user_domain: @user.username, api_key: @api_key),
           factory({
                     name: 'PARENT',
                     type: CartoDB::Visualization::Member::TYPE_DERIVED
                   }).to_json, @headers
      body = JSON.parse(last_response.body)
      parent_vis_id = body.fetch('id')

      # A
      post api_v1_visualizations_create_url(user_domain: @user.username, api_key: @api_key),
           {
             name: 'A',
             type: CartoDB::Visualization::Member::TYPE_SLIDE,
             parent_id: parent_vis_id,
             map_id: map_id
           }.to_json, @headers
      body = JSON.parse(last_response.body)
      vis_a_id = body.fetch('id')
      body.fetch('prev_id').should eq nil
      body.fetch('next_id').should eq nil

      # standalone
      post api_v1_visualizations_create_url(user_domain: @user.username, api_key: @api_key),
           factory(name: 'standalone').to_json, @headers
      body = JSON.parse(last_response.body)
      body.fetch('prev_id').should eq nil
      body.fetch('next_id').should eq nil

      # A -> B
      post api_v1_visualizations_create_url(user_domain: @user.username, api_key: @api_key),
           {
             name: 'B',
             type: CartoDB::Visualization::Member::TYPE_SLIDE,
             parent_id: parent_vis_id,
             map_id: map_id,
             prev_id: vis_a_id
           }.to_json, @headers
      body = JSON.parse(last_response.body)
      vis_b_id = body.fetch('id')
      body.fetch('prev_id').should eq vis_a_id
      body.fetch('next_id').should eq nil

      get api_v1_visualizations_show_url(user_domain: @user.username, api_key: @api_key, id: vis_a_id),
          {}, @headers
      body = JSON.parse(last_response.body)
      body.fetch('prev_id').should eq nil
      body.fetch('next_id').should eq vis_b_id
      get api_v1_visualizations_show_url(user_domain: @user.username, api_key: @api_key, id: vis_b_id),
          {}, @headers
      body = JSON.parse(last_response.body)
      body.fetch('prev_id').should eq vis_a_id
      body.fetch('next_id').should eq nil

      # C -> A -> B
      post api_v1_visualizations_create_url(user_domain: @user.username, api_key: @api_key),
           {
             name: 'C',
             type: CartoDB::Visualization::Member::TYPE_SLIDE,
             parent_id: parent_vis_id,
             map_id: map_id,
             next_id: vis_a_id
           }.to_json, @headers
      body = JSON.parse(last_response.body)
      vis_c_id = body.fetch('id')
      body.fetch('prev_id').should eq nil
      body.fetch('next_id').should eq vis_a_id

      get api_v1_visualizations_show_url(user_domain: @user.username, api_key: @api_key, id: vis_c_id),
          {}, @headers
      body = JSON.parse(last_response.body)
      body.fetch('prev_id').should eq nil
      body.fetch('next_id').should eq vis_a_id
      get api_v1_visualizations_show_url(user_domain: @user.username, api_key: @api_key, id: vis_a_id),
          {}, @headers
      body = JSON.parse(last_response.body)
      body.fetch('prev_id').should eq vis_c_id
      body.fetch('next_id').should eq vis_b_id
      get api_v1_visualizations_show_url(user_domain: @user.username, api_key: @api_key, id: vis_b_id),
          {}, @headers
      body = JSON.parse(last_response.body)
      body.fetch('prev_id').should eq vis_a_id
      body.fetch('next_id').should eq nil

      # C -> D -> A -> B
      post api_v1_visualizations_create_url(user_domain: @user.username, api_key: @api_key),
           {
             name: 'D',
             type: CartoDB::Visualization::Member::TYPE_SLIDE,
             parent_id: parent_vis_id,
             map_id: map_id,
             prev_id: vis_c_id,
             next_id: vis_a_id
           }.to_json, @headers
      body = JSON.parse(last_response.body)
      vis_d_id = body.fetch('id')
      body.fetch('prev_id').should eq vis_c_id
      body.fetch('next_id').should eq vis_a_id

      get api_v1_visualizations_show_url(user_domain: @user.username, api_key: @api_key, id: vis_c_id),
          {}, @headers
      body = JSON.parse(last_response.body)
      body.fetch('prev_id').should eq nil
      body.fetch('next_id').should eq vis_d_id

      get api_v1_visualizations_show_url(user_domain: @user.username, api_key: @api_key, id: vis_d_id),
          {}, @headers
      body = JSON.parse(last_response.body)
      body.fetch('prev_id').should eq vis_c_id
      body.fetch('next_id').should eq vis_a_id

      get api_v1_visualizations_show_url(user_domain: @user.username, api_key: @api_key, id: vis_a_id),
          {}, @headers
      body = JSON.parse(last_response.body)
      body.fetch('prev_id').should eq vis_d_id
      body.fetch('next_id').should eq vis_b_id

      get api_v1_visualizations_show_url(user_domain: @user.username, api_key: @api_key, id: vis_b_id),
          {}, @headers
      body = JSON.parse(last_response.body)
      body.fetch('prev_id').should eq vis_a_id
      body.fetch('next_id').should eq nil

      # C -> A -> B -> D
      put api_v1_visualizations_set_next_id_url(user_domain: @user.username, api_key: @api_key, id: vis_d_id),
           { next_id: nil }.to_json, @headers
      last_response.status.should == 200

      get api_v1_visualizations_show_url(user_domain: @user.username, api_key: @api_key, id: vis_c_id),
          {}, @headers
      body = JSON.parse(last_response.body)
      body.fetch('prev_id').should eq nil
      body.fetch('next_id').should eq vis_a_id

      get api_v1_visualizations_show_url(user_domain: @user.username, api_key: @api_key, id: vis_a_id),
          {}, @headers
      body = JSON.parse(last_response.body)
      body.fetch('prev_id').should eq vis_c_id
      body.fetch('next_id').should eq vis_b_id

      get api_v1_visualizations_show_url(user_domain: @user.username, api_key: @api_key, id: vis_b_id),
          {}, @headers
      body = JSON.parse(last_response.body)
      body.fetch('prev_id').should eq vis_a_id
      body.fetch('next_id').should eq vis_d_id

      get api_v1_visualizations_show_url(user_domain: @user.username, api_key: @api_key, id: vis_d_id),
          {}, @headers
      body = JSON.parse(last_response.body)
      body.fetch('prev_id').should eq vis_b_id
      body.fetch('next_id').should eq nil
    end
  end

  describe '#source_visualization_id_and_hierarchy' do
    it 'checks proper working of parent_id' do
      CartoDB::NamedMapsWrapper::NamedMaps.any_instance.stubs(:get => nil, :create => true, :update => true, :delete => true)

      map_id = ::Map.create(user_id: @user.id).id

      post api_v1_visualizations_create_url(user_domain: @user.username, api_key: @api_key),
       factory({
                 name: "PARENT #{UUIDTools::UUID.timestamp_create.to_s}",
                 type: CartoDB::Visualization::Member::TYPE_DERIVED
               }).to_json, @headers
      body = JSON.parse(last_response.body)
      parent_vis_id = body.fetch('id')

      post api_v1_visualizations_create_url(user_domain: @user.username, api_key: @api_key),
           {
             name: "CHILD 1 #{UUIDTools::UUID.timestamp_create.to_s}",
             type: CartoDB::Visualization::Member::TYPE_SLIDE,
             parent_id: parent_vis_id,
             map_id: map_id
           }.to_json, @headers
      vis_1_body = JSON.parse(last_response.body)

      # This should also set as next sibiling of vis_1 as has no prev_id/next_id set
      post api_v1_visualizations_create_url(user_domain: @user.username, api_key: @api_key),
           {
             name: "CHILD 2 #{UUIDTools::UUID.timestamp_create.to_s}",
             type: CartoDB::Visualization::Member::TYPE_SLIDE,
             source_visualization_id: vis_1_body.fetch('id'),
             parent_id: parent_vis_id
           }.to_json, @headers
      vis_2_body = JSON.parse(last_response.body)

      vis_2_body.fetch('prev_id').should eq vis_1_body.fetch('id')

      vis_2_body.fetch('parent_id').should eq vis_1_body.fetch('parent_id')
      vis_1_body.fetch('parent_id').should eq parent_vis_id
      vis_2_body.fetch('id').should_not eq vis_1_body.fetch('id')
    end
  end

  # Visualizations are always created with default_privacy
  def factory(attributes={})
    {
      name:                     attributes.fetch(:name, "visualization #{rand(9999)}"),
      tags:                     attributes.fetch(:tags, ['foo', 'bar']),
      map_id:                   attributes.fetch(:map_id, ::Map.create(user_id: @user.id).id),
      description:              attributes.fetch(:description, 'bogus'),
      type:                     attributes.fetch(:type, 'derived'),
      privacy:                  attributes.fetch(:privacy, 'public'),
      source_visualization_id:  attributes.fetch(:source_visualization_id, nil),
      parent_id:                attributes.fetch(:parent_id, nil),
      locked:                   attributes.fetch(:locked, false),
      prev_id:                  attributes.fetch(:prev_id, nil),
      next_id:                  attributes.fetch(:next_id, nil)
    }
  end

  def table_factory(options={})
    privacy = options.fetch(:privacy, 1)

    seed    = rand(9999)
    payload = {
      name:         "table #{seed}",
      description:  "table #{seed} description"
    }
    post "/api/v1/tables?api_key=#{@api_key}",
      payload.to_json, @headers

    table_attributes  = JSON.parse(last_response.body)
    table_id          = table_attributes.fetch('table_visualization').fetch("id")

    put "/api/v1/viz/#{table_id}?api_key=#{@api_key}",
      { privacy: privacy }.to_json, @headers

    table_attributes
  end #table_factory
end # Api::Json::VisualizationsController


text:
roshi-server provides a thin, REST-ish HTTP interface to a [farm][farm]. All
the parameters for each conceptual layer are provided as commandline flags,
most with sensible defaults. roshi-server expects an existant set of Redis
instances (at least 1) to be running somewhere as the data layer. roshi-server
is effectively stateless, so you may run as many instances as required to
satisfy your load volume.

[farm]: http://github.com/soundcloud/roshi/blob/master/farm

## Getting and building

roshi-server uses vendored dependencies and a "blessed build" process to ensure
stability over time. Users should get and build roshi-server by cloning this
repository and running `make` in the roshi-server subdirectory. A working Go
toolchain is assumed.

    git clone git@github.com:soundcloud/roshi
    cd roshi/roshi-server
    make

It's also possible to get roshi-server via `go get`, and/or build it with a
simple `go build`, with the caveat that it will use your normal GOPATH to
resolve dependencies, and therefore will enforce no constraints on dependency
versions, which could introduce bugs or strange behavior.

## Running

As a demo, start an instance of Redis on the standard port, and run

```
roshi-server -redis.instances=localhost:6379
```

This will create a farm with a single cluster containing a single Redis
instance. All functionality will work as advertised, albeit with effectively
zero fault-tolerance.

## API

The server installs one handler on the root path. Operations are
differentiated by their HTTP verb. Keys and members must be base64 encoded.
For demo purposes, we'll use key `foo` (base64 `Zm9v`) and members `bar`
(base64 `YmFy`) and `baz` (base64 `YmF6`).

Note that write operations will claim success and return 200 as long as quorum
is achieved, even if the provided score was lower than what has already been
persisted and therefore the operation was actually a no-op.

### Insert

POST to `/`. Provide a request body with a JSON array of key-score-member
objects. No URL parameters are accepted.

```bash
$ cat insert.json
[{"key":"Zm9v", "score":1.05, "member":"YmFy"},
 {"key":"Zm9v", "score":1.99, "member":"YmF6"}]

$ curl -Ss -d@insert.json -XPOST 'http://localhost:6302' | jq .
{
  "duration": "377.863us",
  "inserted":2
}
```

### Select

GET to `/`. Provide a request body with a JSON-encoded array of key strings.
There are some URL parameters:

- **offset**, for pagination, default 0
- **limit**, for pagination, default 10
- **coalesce**, merge multiple keys into one response, default false

```bash
$ cat select.json
["Zm9v"]

$ curl -Ss -d@select.json -XGET 'http://localhost:6302' | jq .
{
  "records": {
    "foo": [
      {
        "member": "YmF6",
        "score": 1.99,
        "key": "Zm9v"
      },
      {
        "member": "YmFy",
        "score": 1.05,
        "key": "Zm9v"
      }
    ]
  },
  "offset": 0,
  "limit": 10,
  "keys": [
    "Zm9v"
  ],
  "duration": "238.204us"
}
```

### Delete

DELETE to `/`. Provide a request body with a JSON array of key-score-member
objects. No URL parameters are accepted.

```bash
$ cat delete.json
[{"key":"Zm9v", "score":2.01, "member":"YmF6"}]

$ curl -Ss -d@delete.json -XDELETE 'http://localhost:6302' | jq .
{
  "duration": "429.993us",
  "deleted": 1
}
```

## Integrating with your code

Golang clients that wish to make HTTP requests to roshi-server should
`import "github.com/soundcloud/roshi/common"` and interact with (i.e. serialize
and deserialize) `common.KeyScoreMember` tuples directly. That type implements
`json.Marshaler` such that base64 encoding and decoding is transparent to the
user.

Clients in other languages should ensure all key and member strings are
properly base64 encoded.

## Operations

roshi-server expects to interact with a set of independent Redis instances,
which operators should deploy, monitor, and manage. Roshi assumes a successful
write to Redis will be persisted; Roshi's durability guarantees are largely
predicated on the durability of each Redis instance. Please familiarize
yourself with [Redis persistence][redis-persistence].

[redis-persistence]: http://redis.io/topics/persistence

In general, Redis will use a lot of RAM and comparatively little CPU, and
roshi-server will use very little RAM and comparatively large amount of CPU.
It may make sense to co-locate a roshi-server instance with every Redis
instance. (It's been our experience that a single server-class machine is best
utilized when it runs multiple Redis instances.)