text:
<?php namespace Addons\Form;

use \Addons\HTMLHandler\HTMLHandler;

abstract class Input {
	protected $name;
	protected $type;

	protected $label;
	protected $text;
	protected $required;

	protected $attributes;

	protected $errors;

	public function __construct($name, $type, $text, $label, $required = true, $reFillValue = false, $attributes = array()) {
		$this->attributes = $attributes;

		$this->setName($name);
		$this->setType($type);
		$this->label = $label;
		$this->text = $text;
		$this->required = $required;

		if($required)
			$this->attributes["required"] = true;

		if($reFillValue && isSet($_POST) && !empty($_POST[$name]))
			$this->attributes["value"] = $_POST[$name];

		$this->errors = array();
	}

	abstract public function validate();

	public function createInput() {
		global $util;

		$binder = HTMLHandler::createHTML("div", array("class" => "inputBinder"));
		$input = HTMLHandler::createHTML("input", $this->attributes);
		$label = HTMLHandler::createHTML("label", array("class" => "formLabel input_{$this->name}", "for" => $this->name));

		$errorHolder = HTMLHandler::createHTML("div", array("class" => "formErrorHolder"));

		$errors = $errorHolder["open"];
		foreach($this->errors as $error) {
			$htmlError = HTMLHandler::createHTML("span", array("class" => "formError"));
			$errors .= $htmlError["open"] . $util->getString("{$error}_{$this->name}") . $htmlError["close"];
		}
		$errors .= $errorHolder["close"];

		return  $binder["open"] .
				(count($this->errors) > 0 ? $errors : "") .
				($this->label ? $label["open"] . $util->getString($this->text) . "\n" . $label["close"] : "") .
				$input["noContent"] .
				$binder["close"];
	}

	protected function setType($type) {
		$this->type = $type;
		$this->attributes["type"] = $type;
	}

	protected function setName($name) {
		$this->name = $name;
		$this->attributes["name"] = $name;
	}

	protected function setAttribute($attribute, $value) {
		$this->attributes[$attribute] = $value;
	}

	public function getErrors() {
		return $this->errors;
	}

	public function addError($error) {
		$this->errors[] = $error;
	}

	public function getName() {
		return $this->name;
	}
}


text:
<?php
namespace Icecave\Chastity\Exception;

use Exception;
use LogicException;

/**
 * A lock operation has been attempted on a detatched scoped lock.
 *
 * @see ScopedLockInterface::detach()
 */
class LockDetachedException extends LogicException
{
    /**
     * @param Exception|null $previous The previous exception.
     */
    public function __construct(Exception $previous = null)
    {
        parent::__construct(
            'Lock has been detached.',
            0,
            $previous
        );
    }
}

redpajama_set_name: RedPajamaGithub


text:
<?php

namespace app\commands;

use Yii;
use yii\console\Controller;

class RbacController extends Controller
{
    public function actionInit()
    {
        $auth = Yii::$app->authManager;

        // добавляем роль "author" и даём роли разрешение "createPost"
//        $partner = $auth->createRole('partner');
//        $auth->add($partner);
        //$auth->addChild($author, $createPost);

        // добавляем роль "admin" и даём роли разрешение "updatePost"
        // а также все разрешения роли "author"
        $admin = $auth->createRole('admin');
        $auth->add($admin);

        // Назначение ролей пользователям. 1 и 2 это IDs возвращаемые IdentityInterface::getId()
        // обычно реализуемый в модели User.
        //$auth->assign($author, 2);
        $auth->assign($admin, 1);
    }
}


text:
Shared way of loading and reading configuration in Travis CI.

Users can either set defaults and include logic directly to the class
`Travis::Config` or extend the class to, e.g. `Travis::Logs::Config`.

E.g.

```ruby
require 'travis/config'

module Travis
  class Config < Hashr
    define  host:  'travis-ci.org'

    def foo
      :foo
    end
  end
end
```

Or:

```ruby
require 'travis/config'

module Travis::Logs
  class Config < Travis::Config
    define  host:  'logs.travis-ci.org'

    def foo
      :foo
    end
  end
end
```

### Config sources

Serveral config sources are supported:

* Files: All files `config/travis.yml` and `config/travis/*.yml` are read and
  merged (alpabetically sorted).
* Env: `ENV['travis_config']` is parsed as YAML and merged, if present.
* Heroku: The env vars `DATABASE_URL` or `SHARED_DATABASE_URL`, and `DB_POOL`
  or `DATABASE_POOL_SIZE` are merged into the database config.
* Docker: The env vars `POSTGRESQL_PORT`, `RABBITMQ_PORT`, and `REDIS_PORT` are
  interpreted as resource URLs, and merged into the database config.

Configuration from all sources is merged before it is passed to the `Hashr`
instance. All merging is deep merging of Hashes on any level.

### Doing a Rubygem release

Any tool works. The current releases were done with
[`gem-release`](https://github.com/svenfuchs/gem-release) which allows creating
a Git tag, pushing it to GitHub, building the gem and pushing it to Rubygems in
one go:

```bash
$ gem install gem-release
$ gem release --tag
```


text:
<?php

// Middleware for deleting expired notices
$this->add(function($req, $res, $next) {
    /* not very efficient, but it works.
    */
    $expired = \NoticeDetail::where('end_date', '<', date('Y-m-d H:i:s'));
    $expired->update([
        'expired' => true
    ]);
    $expired->delete();
    $response = $next($req, $res);
    return $response;
});

$this->group('/notices', function() {
    // GET all the notices
    $this->get('', function($request, $response, $args) {
        // Fetch all notices
        $notices = \NoticeDetail::latest()->get();
        return $response->withJson($notices);
    });

    // POST a new notice
    $this->post('', function($request, $response, $args) {
        // getting the user from the access_token
        $access_token = $request->getQueryParams()['access_token'];
        $token = \AccessToken::where('token', $access_token)->first();

        if ($token && $token['u_type'] == 'notice-admin') {
            // getting the request body
            $json = $request->getBody();
            $data = json_decode($json, true);

            // fetching the u_id of the current user
            $user = \NoticeAdminUser::find($token['u_id']);

            // error_log(print_r("Response: \n" . $data['end_date']), 4);
            // echo $json . '

';
            // echo $data['image'];

            $img_url = '';
            // if request body contains image, save it to uploads/
            // and update the $img_url
            if (array_key_exists('image', $data)) {
                $image = base64_decode($data['image']);
                $filename = uniqid().'.jpg';
                $file = fopen('uploads/'.$filename, 'wb');
                fwrite($file, $image);
                fclose($file);
                $img_url = $request->getUri()->getBaseUrl().'/uploads/'.$filename;
            }
            // error_log(print_r("Uploaded img_url: ".$img_url));
            // echo '
img_url: '.$img_url;

            // Creating a new notice
            $notice = new \NoticeDetail(array(
                'title' => $data['title'],
                'body' => $data['body'],
                'img_url' => $img_url,
                'end_date' => $data['end_date'],
                'branch' => strtolower($data['branch']),
                'class' => strtolower($data['class']),
                'division' => $data['division'],
                'audience' => strtolower($data['u_type']),
                'u_id' => $user['id'],
            ));
            $notice->save();
            return $response->withJson($notice);
        } else {
            return $response->withJson(array('status'=>401,
                                            'error'=>'Unauthorized Access'));
        }
    });

    // DELETE a notice
    $this->delete('/{n_id}', function($request, $response, $args) {

        $access_token = $request->getQueryParams()['access_token'];
        $token = \AccessToken::where('token', $access_token)->first();
        // echo $token;

        if ($token && $token['u_type'] == 'notice-admin') {
            $user = \NoticeAdminUser::find($token['u_id']);
            $notice = \NoticeDetail::find($args['n_id']);

            if (!$notice) {
                return $response->withJson(array('status'=>400,
                                                'error'=>'Notice not found'));
            } else {
                if ($notice['u_id'] == $user['id']) {
                    if ($notice['img_url']) {
                        $img = pathinfo($notice['img_url'], PATHINFO_BASENAME);
                        // delete the image
                        unlink("uploads/$img");
                    }
                    $notice->delete();

                    return $response->withJson(array('status'=>204,
                                                    'message'=>'Notice Deleted'));
                }
            }
        }
        return $response->withJson(array('status'=>401,
                                        'error'=>'User not authorized'));
    });

    // GET the notices of the user
    $this->get('/self', function($request, $response, $args) {
        $access_token = $request->getQueryParams()['access_token'];
        // echo $access_token;
        $token = \AccessToken::where('token', $access_token)->first();

        if ($token && $token['u_type'] == 'notice-admin') {
            // fetching the u_id of the current user
            $user = \NoticeAdminUser::find($token['u_id']);

            // Fetch all notices
            $notices = \NoticeDetail::where('u_id', $user['id'])
                                    // ->orderBy('end_date', 'asc')
                                    ->orderBy('created_at', 'asc')
                                    ->get();
            return $response->withJson($notices);
        } else {
            return $response->withJson(array('status'=>401,
                                            'error'=>'Unauthorized Access'));
        }
    });

    // GET the trashed notices
    $this->get('/self/trashed', function($request, $response) {
        $access_token = $request->getQueryParams()['access_token'];
        $token = \AccessToken::where('token', $access_token)->first();

        if ($token && $token['u_type'] == 'notice-admin') {
            $user = \NoticeAdminUser::find($token->u_id);

            // fetch the notices trashed by the $user
            $notice = \NoticeDetail::onlyTrashed()
                                    ->orderBy('end_date', 'desc')
                                    ->get();

            return $response->withJson($notice);
        }

        return $response->withJson(array(
            'status' => 401,
            'error' => 'Unauthorized'
        ));
    });
});

?>


text:
#ifndef MONSTER_H
#define MONSTER_H

#include <SDL2/SDL.h>

#include "creature.h"

namespace pac {
    class Monster;
}

class pac::Monster : public pac::Creature {

    public:

    Monster() = delete;
    Monster(SDL_Renderer* rend, int x, int y, int w = 17, int h = 17, Direction d = Direction::LEFT, int sp = 1)
        : Creature(rend,x,y,w,h,d,sp), misVulnerable(false) {}

    /* Getters */
    bool isVulnerable() const {return misVulnerable;}

    /* Setters */
    void set_isVulnerable(bool f) {misVulnerable = f;}

    /* Methods */
    void switch_vulner() {misVulnerable = (misVulnerable ? false : true);}
    virtual void die() override;

    //static void set_all_vulner(bool f) {for(auto m : monsters) m->set_isVulnerable(f);}
    //static std::shared_ptr<Monster> monster(size_t n) {return monsters.at(n);}

    private:

    bool misVulnerable;

    //static std::array<std::shared_ptr<Monster>,4> monsters;
};

#endif


text:
@interface EmailSpaceViewController : UITableViewController <UITextViewDelegate, UITextFieldDelegate, RESTFinished, ABPeoplePickerNavigationControllerDelegate, UITextFieldKeyPressDelegate> {

}

@property (nonatomic, retain) Space *space;
@property (nonatomic, retain) OverlayMessage *overlay;
@property (nonatomic, retain) REST *rest;
@property (nonatomic) BOOL is_sending_email;
@property (nonatomic, retain) IBOutlet UILabel *room_label;
@property (nonatomic, retain) IBOutlet UILabel *building_label;
@property (nonatomic, retain) NSMutableDictionary *existing_emails;
@property (nonatomic, retain) NSMutableArray *email_list;
@property (nonatomic) CGFloat to_cell_size;
@property (nonatomic) BOOL has_valid_to_email;
@property (nonatomic) NSInteger current_selected_email_tag;
@property (nonatomic, retain) NSArray *search_matches;
@property (nonatomic, retain) NSArray *all_contacts;

-(IBAction)sendEmail:(id)selector;
-(IBAction)openContactChooser:(id)selector;
@end


text:
import React, { PropTypes, Component } from 'react'
import { Link } from 'react-router'
import { connect } from 'react-redux'

const mapStateToProps = state => ({
  current: state.router.location.pathname
})

class SidebarItem extends Component {

  static propTypes = {
    link: PropTypes.string.isRequired,
    icon: PropTypes.string.isRequired,
    name: PropTypes.string.isRequired,
    soon: PropTypes.bool,
    current: PropTypes.string.isRequired
  };

  render () {
    const active = this.props.link === this.props.current
    const to = !this.props.soon ? this.props.link : '#'
    return

      <Link to={to} className={active ? 'active' : ''}>
        <i className={`fa fa-fw fa-${this.props.icon}`}>
          {this.props.name}
        { this.props.soon ? SOON : '' }
      </Link>

  }
}

export class Sidebar extends Component {

  static propTypes = {
    current: PropTypes.string.isRequired
  };

  render () {
    return

        <SidebarItem link='/' icon='dashboard' name='Dashboard'
                     current={this.props.current} />
        <SidebarItem link='/blockchain' icon='bold' name='Blockchain State'
                     current={this.props.current} />
        <SidebarItem link='/keys' icon='key' name='Key Manager'
                     current={this.props.current} />
        <SidebarItem link='/crafttx' icon='terminal' name='Transaction Creator'
                     current={this.props.current} />
        <SidebarItem link='/decodetx' icon='edit' name='Transaction Inspector'
                     current={this.props.current} />
        <SidebarItem link='/script' icon='bolt' name='Script Evaluation'
                     current={this.props.current} soon />
                     { /*
        <SidebarItem link='/address' icon='credit-card' name='Address Manager'
                     current={this.props.current} soon />
        <SidebarItem link='/multisig' icon='bars' name='Multisig Address'
                     current={this.props.current} soon />
        <SidebarItem link='/explorer' icon='search' name='Block Explorer'
                     current={this.props.current} soon />
                      */ }

  }
}

export default connect(mapStateToProps)(Sidebar)


text:
/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jruyi.io;

import org.jruyi.io.internal.CodecProvider;

/**
 * This class is a factory class for int codecs.
 *
 * @see IIntCodec
 */
public final class IntCodec {

	private static final IIntCodecProvider c_provider = CodecProvider.getInstance().getIntCodecProvider();

	/**
	 * This interface defines all the methods that an int codec provider has to
	 * implement. It is used to separate the implementation provider from the
	 * API module.
	 */
	public interface IIntCodecProvider {

		/**
		 * Returns a big-endian int codec.
		 *
		 * @return a big-endian int codec
		 */
		IIntCodec bigEndianIntCodec();

		/**
		 * Returns a little-endian int codec.
		 *
		 * @return a little-endian int codec
		 */
		IIntCodec littleEndianIntCodec();

		/**
		 * Returns a varint int codec.
		 *
		 * @return a varint int codec
		 * @since 1.2
		 */
		IIntCodec varintIntCodec();
	}

	/**
	 * Returns a big-endian int codec.
	 *
	 * @return a big-endian int codec
	 */
	public static IIntCodec bigEndian() {
		return c_provider.bigEndianIntCodec();
	}

	/**
	 * Returns a little-endian int codec.
	 *
	 * @return a little-endian int codec
	 */
	public static IIntCodec littleEndian() {
		return c_provider.littleEndianIntCodec();
	}

	/**
	 * Returns a varint int codec.
	 *
	 * @return a varint int codec
	 * @since 1.2
	 */
	public static IIntCodec varint() {
		return c_provider.varintIntCodec();
	}

	private IntCodec() {
	}
}


text:
%{
MIT License

Copyright (c) [2016] [Mallory Ann Jensen, jensenma@alum.mit.edu]

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
%}

% This Matlab script reads the output files from a free-carrier absoprtion
% measurement. The data is processed and save as raw data, carrier density,
% and then lifetime.
clear all
close all

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% define parameters
bin=1; % binning resolution
d=490*10^-4; % thickness of silicon wafer, cm
% define the cut-off injection level. signal at low injection levels
% is very noisy
cutoff_inject=1.0e13; %cm^-3
%Define the cutoff time - this is similar to the above consideration
cutoff_t=1e-3; %s
T = 25+273.15; %sample temperature in K
FCA = 7.5e-18; %FCA cross-section to be used, cm^2. 7.5e-18 is the value determined by Sin Cheng's work.
inj_dep = 0; %Is the FCA cross-section injection dependent? This will also perform a correction for temperature if measurements are not made at room-temperature.
save_file='20150821_FCAData_bin1_5303_25C.mat'; %filename for .mat file with raw data for fitting

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Read the data and do some initial processing

% read all files with the extension .plt
files=dir('*.txt');
% read the name of all files and store as a column vector
filenames={files.name};
% number of files for import
number=length(filenames);

% First, read experimental data from files
filename1=filenames{1};
filename2=filenames{2};
[deltan,t,datas,carrier,V0]=FCA_process(filename1,filename2,FCA,inj_dep,T,cutoff_inject,cutoff_t,bin,d);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Calculate the lifetime

%First with the unfiltered data
lifetime_raw = lifetime(deltan,t);

%Plot the results so that we can see them
figure;
loglog(deltan,lifetime_raw,'.');
xlabel('\Deltan [cm^-^3]');
ylabel('Lifetime [s]');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Save all of our results
save(save_file,'t','deltan','datas','carrier','V0','lifetime_raw');


text:
using System;
using System.Runtime.CompilerServices;
using System.Threading;

namespace RioSharp
{
    internal sealed class RioBufferSegmentAwaiter : INotifyCompletion, IDisposable
    {
        RioBufferSegment _currentValue;
        Action _continuation = null;
        WaitCallback _continuationWrapperDelegate;
        SpinLock _spinLock = new SpinLock();

        public RioBufferSegmentAwaiter()
        {
            _continuationWrapperDelegate = continuationWrapper;
        }

        private void continuationWrapper(object o)
        {
            ((Action)o)();
        }

        public bool IsCompleted
        {
            get
            {
                bool taken = false;
                _spinLock.Enter(ref taken);
                var res = _currentValue != null;
                if (res)
                    _spinLock.Exit();
                return res;
            }
        }

        public void OnCompleted(Action continuation)
        {
            _continuation = continuation;
            _spinLock.Exit();
        }

        public void Set(RioBufferSegment item)
        {
            bool taken = false;
            _spinLock.Enter(ref taken);
            //if (!taken)
            //    throw new ArgumentException("fuu");

            //if (_currentValue != null)
            //    throw new ArgumentException("fuu");

            _currentValue = item;
            _spinLock.Exit();

            if (_continuation != null)
            {
                var res = _continuation;
                _continuation = null;
                ThreadPool.QueueUserWorkItem(_continuationWrapperDelegate, res);
            }
        }

        public RioBufferSegment GetResult()
        {
            var res = _currentValue;
            _currentValue = null;
            return res;
        }

        public RioBufferSegmentAwaiter GetAwaiter() => this;

        public void Dispose()
        {
            _currentValue?.Dispose();
            _currentValue = null;
            if (_continuation != null)
                _continuation();
        }
    }
}


text:
<?php

class Google_Service_PagespeedInsights_Timing extends Google_Model
{
  public $total;

  public function setTotal($total)
  {
    $this->total = $total;
  }
  public function getTotal()
  {
    return $this->total;
  }
}


text:
<?php
	//************* Database Config ***************//
	define('DB_HOST','localhost');
	define('DB_USER','root');
	define('DB_PASS','');
	define('DB','automation');
	define('URL','http://localhost/automation/');

	//************* EH Global Variables ***************//
	define('EH_LOCAL_SCRIPTS_PATH', $_SERVER['DOCUMENT_ROOT'].'automation/scripts/');
	define('EH_LOCAL_KEYS_PATH', $_SERVER['DOCUMENT_ROOT'].'automation/keys/');
	//for server
	//define('EH_LOCAL_SCRIPTS_PATH', '/var/www/automation/scripts/');
	//define('EH_LOCAL_KEYS_PATH', '/var/www/automation/keys/');

	define('EH_REMOTE_PATH', '/root/');
	define('EH_REMOTE_SCRIPT', 'automation.sh');
	define('EH_LOCAL_SCRIPT', 'automation.sh');
	define('EH_KEY_NAME', '');
?>


text:
package apfe.peg.generate;

import java.util.Arrays;
import java.util.List;

/**
 *
 * @author gburdell
 */
public class Template {

    public static String replace(final String tmpl, Object... args) {
        String r = tmpl;
        int i = 1;
        for (Object s : args) {
            String repl = "@" + i++ + "@";
            r = r.replace(repl, s.toString());
        }
        return r;
    }

    /**
     * Replace metachars in tmpl with specified values.
     *
     * @param tmpl template string with metachars.
     * @param args even-number of elements: spec1, repl1, spec2, repl2, ...
     * @return tmpl with each spec1 replaced by repl1, each spec2 replaced by
     * repl2, etc.
     */
    public static String replaceSpecd(final String tmpl, Object... args) {
        final int n = args.length;
        assert (0 == n % 2);
        List<Object> argsl = Arrays.asList(args);
        String r = tmpl;
        for (int i = 0; i < n; i += 2) {
            String repl = argsl.get(i).toString(), with = argsl.get(i + 1).toString();
            r = r.replace(repl, with);
        }
        return r;
    }

    /**
     * Return substring between "beg" and "end" markers.
     *
     * @param tmpl template string to substring.
     * @param beg begin marker.
     * @param end end marker (could be same name as beg: but expect different
     * location).
     * @return substring between beg and end.
     */
    public static String substring(final String tmpl, final String beg, final String end) {
        int begIx = tmpl.indexOf(beg) + beg.length(), endIx = tmpl.lastIndexOf(end);
        return tmpl.substring(begIx, endIx);
    }

    public static String substring(final String tmpl, final String beg) {
        return substring(tmpl, beg, beg);
    }

    /**
     * Delete substrings delimited by marks.
     *
     * @param ss string containing marks.
     * @param marks begin/end marks.
     * @return remainder of ss after marked substrings are removed.
     */
    public static String delete(final String ss, String... marks) {
        StringBuilder rval = new StringBuilder(ss);
        int beg, end;
        for (String m : marks) {
            beg = rval.indexOf(m);
            end = rval.lastIndexOf(m) + m.length();
            if (0 <= beg) {
                rval.delete(beg, end);
            }
        }
        return rval.toString();
    }

    /**
     * Either remove substring between marks or null out marks.
     *
     * @param keep if true: null marks; else remove substring between marks.
     * @param tmpl template/string to modify.
     * @param marks unique marks which appear in pairs in tmpl.
     * @return modified string.
     */
    public static String removeOrKeep(boolean keep, final String tmpl, String... marks) {
        String rval = tmpl;
        if (keep) {
            for (String m : marks) {
                rval = replaceSpecd(rval, m, "");
            }
        } else {
            rval = delete(rval, marks);
        }
        return rval;
    }
}


text:
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use std::string::ToString;

use indy_api_types::{CommandHandle, PoolHandle, WalletHandle};
use indy_api_types::errors::prelude::*;
use indy_utils::next_command_handle;
use rust_base58::ToBase58;
use serde_json;
use serde_json::Value;

use indy_wallet::{RecordOptions, WalletService};

use crate::api::ledger::{CustomFree, CustomTransactionParser};
use crate::commands::{BoxedCallbackStringStringSend, Command, CommandExecutor};
use crate::domain::anoncreds::credential_definition::{CredentialDefinition, CredentialDefinitionId, CredentialDefinitionV1};
use crate::domain::anoncreds::revocation_registry_definition::{RevocationRegistryDefinition, RevocationRegistryDefinitionV1, RevocationRegistryId};
use crate::domain::anoncreds::revocation_registry_delta::{RevocationRegistryDelta, RevocationRegistryDeltaV1};
use crate::domain::anoncreds::schema::{Schema, SchemaId, SchemaV1};
use crate::domain::crypto::did::{Did, DidValue};
use crate::domain::crypto::key::Key;
use crate::domain::ledger::auth_rule::{AuthRules, Constraint};
use crate::domain::ledger::author_agreement::{AcceptanceMechanisms, GetTxnAuthorAgreementData};
use crate::domain::ledger::node::NodeOperationData;
use crate::domain::ledger::pool::Schedule;
use crate::domain::ledger::request::Request;
use crate::services::crypto::CryptoService;
use crate::services::ledger::LedgerService;
use crate::services::pool::{
    parse_response_metadata,
    PoolService
};
use crate::utils::crypto::signature_serializer::serialize_signature;

pub enum LedgerCommand {
    SignAndSubmitRequest(
        PoolHandle, // pool handle
        WalletHandle,
        DidValue, // submitter did
        String, // request json
        Box<dyn Fn(IndyResult<String>) + Send>),
    SubmitRequest(
        PoolHandle, // pool handle
        String, // request json
        Box<dyn Fn(IndyResult<String>) + Send>),
    SubmitAck(
        CommandHandle,
        IndyResult<String>, // result json or error
    ),
    SubmitAction(
        PoolHandle, // pool handle
        String, // request json
        Option<String>, // nodes
        Option<i32>, // timeout
        Box<dyn Fn(IndyResult<String>) + Send>),
    SignRequest(
        WalletHandle,
        DidValue, // submitter did
        String, // request json
        Box<dyn Fn(IndyResult<String>) + Send>),
    MultiSignRequest(
        WalletHandle,
        DidValue, // submitter did
        String, // request json
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildGetDdoRequest(
        Option<DidValue>, // submitter did
        DidValue, // target did
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildNymRequest(
        DidValue, // submitter did
        DidValue, // target did
        Option<String>, // verkey
        Option<String>, // alias
        Option<String>, // role
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildAttribRequest(
        DidValue, // submitter did
        DidValue, // target did
        Option<String>, // hash
        Option<serde_json::Value>, // raw
        Option<String>, // enc
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildGetAttribRequest(
        Option<DidValue>, // submitter did
        DidValue, // target did
        Option<String>, // raw
        Option<String>, // hash
        Option<String>, // enc
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildGetNymRequest(
        Option<DidValue>, // submitter did
        DidValue, // target did
        Box<dyn Fn(IndyResult<String>) + Send>),
    ParseGetNymResponse(
        String, // get nym response json
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildSchemaRequest(
        DidValue, // submitter did
        Schema, // data
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildGetSchemaRequest(
        Option<DidValue>, // submitter did
        SchemaId, // id
        Box<dyn Fn(IndyResult<String>) + Send>),
    ParseGetSchemaResponse(
        String, // get schema response json
        BoxedCallbackStringStringSend),
    BuildCredDefRequest(
        DidValue, // submitter did
        CredentialDefinition, // data
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildGetCredDefRequest(
        Option<DidValue>, // submitter did
        CredentialDefinitionId, // id
        Box<dyn Fn(IndyResult<String>) + Send>),
    ParseGetCredDefResponse(
        String, // get cred definition response
        BoxedCallbackStringStringSend),
    BuildNodeRequest(
        DidValue, // submitter did
        DidValue, // target_did
        NodeOperationData, // data
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildGetValidatorInfoRequest(
        DidValue, // submitter did
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildGetTxnRequest(
        Option<DidValue>, // submitter did
        Option<String>, // ledger type
        i32, // data
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildPoolConfigRequest(
        DidValue, // submitter did
        bool, // writes
        bool, // force
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildPoolRestartRequest(
        DidValue, //submitter did
        String, //action
        Option<String>, //datetime
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildPoolUpgradeRequest(
        DidValue, // submitter did
        String, // name
        String, // version
        String, // action
        String, // sha256
        Option<u32>, // timeout
        Option<Schedule>, // schedule
        Option<String>, // justification
        bool, // reinstall
        bool, // force
        Option<String>, // package
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildRevocRegDefRequest(
        DidValue, // submitter did
        RevocationRegistryDefinition, // data
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildGetRevocRegDefRequest(
        Option<DidValue>, // submitter did
        RevocationRegistryId, // revocation registry definition id
        Box<dyn Fn(IndyResult<String>) + Send>),
    ParseGetRevocRegDefResponse(
        String, // get revocation registry definition response
        BoxedCallbackStringStringSend),
    BuildRevocRegEntryRequest(
        DidValue, // submitter did
        RevocationRegistryId, // revocation registry definition id
        String, // revocation registry definition type
        RevocationRegistryDelta, // value
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildGetRevocRegRequest(
        Option<DidValue>, // submitter did
        RevocationRegistryId, // revocation registry definition id
        i64, // timestamp
        Box<dyn Fn(IndyResult<String>) + Send>),
    ParseGetRevocRegResponse(
        String, // get revocation registry response
        Box<dyn Fn(IndyResult<(String, String, u64)>) + Send>),
    BuildGetRevocRegDeltaRequest(
        Option<DidValue>, // submitter did
        RevocationRegistryId, // revocation registry definition id
        Option<i64>, // from
        i64, // to
        Box<dyn Fn(IndyResult<String>) + Send>),
    ParseGetRevocRegDeltaResponse(
        String, // get revocation registry delta response
        Box<dyn Fn(IndyResult<(String, String, u64)>) + Send>),
    RegisterSPParser(
        String, // txn type
        CustomTransactionParser,
        CustomFree,
        Box<dyn Fn(IndyResult<()>) + Send>),
    GetResponseMetadata(
        String, // response
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildAuthRuleRequest(
        DidValue, // submitter did
        String, // auth type
        String, // auth action
        String, // field
        Option<String>, // old value
        Option<String>, // new value
        Constraint, // constraint
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildAuthRulesRequest(
        DidValue, // submitter did
        AuthRules, // auth rules
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildGetAuthRuleRequest(
        Option<DidValue>, // submitter did
        Option<String>, // auth type
        Option<String>, // auth action
        Option<String>, // field
        Option<String>, // old value
        Option<String>, // new value
        Box<dyn Fn(IndyResult<String>) + Send>),
    GetSchema(
        PoolHandle,
        Option<DidValue>,
        SchemaId,
        BoxedCallbackStringStringSend,
    ),
    GetSchemaContinue(
        SchemaId,
        IndyResult<String>,
        CommandHandle,
    ),
    GetCredDef(
        PoolHandle,
        Option<DidValue>,
        CredentialDefinitionId,
        BoxedCallbackStringStringSend,
    ),
    GetCredDefContinue(
        CredentialDefinitionId,
        IndyResult<String>,
        CommandHandle,
    ),
    BuildTxnAuthorAgreementRequest(
        DidValue, // submitter did
        Option<String>, // text
        String, // version
        Option<u64>,   // ratification date
        Option<u64>,   // retirement date
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildDisableAllTxnAuthorAgreementsRequest(
        DidValue, // submitter did
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildGetTxnAuthorAgreementRequest(
        Option<DidValue>, // submitter did
        Option<GetTxnAuthorAgreementData>, // data
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildAcceptanceMechanismRequests(
        DidValue, // submitter did
        AcceptanceMechanisms, // aml
        String, // version
        Option<String>, // aml context
        Box<dyn Fn(IndyResult<String>) + Send>),
    BuildGetAcceptanceMechanismsRequest(
        Option<DidValue>, // submitter did
        Option<u64>, // timestamp
        Option<String>, // version
        Box<dyn Fn(IndyResult<String>) + Send>),
    AppendTxnAuthorAgreementAcceptanceToRequest(
        String, // request json
        Option<String>, // text
        Option<String>, // version
        Option<String>, // hash
        String, // acceptance mechanism type
        u64, // time of acceptance
        Box<dyn Fn(IndyResult<String>) + Send>),
    AppendRequestEndorser(
        String, // request json
        DidValue, // endorser did
        Box<dyn Fn(IndyResult<String>) + Send>),
}

pub struct LedgerCommandExecutor {
    pool_service: Rc<PoolService>,
    crypto_service: Rc<CryptoService>,
    wallet_service: Rc<WalletService>,
    ledger_service: Rc<LedgerService>,

    send_callbacks: RefCell<HashMap<CommandHandle, Box<dyn Fn(IndyResult<String>)>>>,
    pending_callbacks: RefCell<HashMap<CommandHandle, Box<dyn Fn(IndyResult<(String, String)>)>>>,
}

impl LedgerCommandExecutor {
    pub fn new(pool_service: Rc<PoolService>,
               crypto_service: Rc<CryptoService>,
               wallet_service: Rc<WalletService>,
               ledger_service: Rc<LedgerService>) -> LedgerCommandExecutor {
        LedgerCommandExecutor {
            pool_service,
            crypto_service,
            wallet_service,
            ledger_service,
            send_callbacks: RefCell::new(HashMap::new()),
            pending_callbacks: RefCell::new(HashMap::new()),
        }
    }

    pub fn execute(&self, command: LedgerCommand) {
        match command {
            LedgerCommand::SignAndSubmitRequest(pool_handle, wallet_handle, submitter_did, request_json, cb) => {
                debug!(target: "ledger_command_executor", "SignAndSubmitRequest command received");
                self.sign_and_submit_request(pool_handle, wallet_handle, &submitter_did, &request_json, cb);
            }
            LedgerCommand::SubmitRequest(handle, request_json, cb) => {
                debug!(target: "ledger_command_executor", "SubmitRequest command received");
                self.submit_request(handle, &request_json, cb);
            }
            LedgerCommand::SubmitAck(handle, result) => {
                debug!(target: "ledger_command_executor", "SubmitAck command received");
                match self.send_callbacks.borrow_mut().remove(&handle) {
                    Some(cb) => cb(result.map_err(IndyError::from)),
                    None => {
                        error!("Can't process LedgerCommand::SubmitAck for handle {:?} with result {:?} - appropriate callback not found!",
                               handle, result);
                    }
                }
            }
            LedgerCommand::SubmitAction(handle, request_json, nodes, timeout, cb) => {
                debug!(target: "ledger_command_executor", "SubmitRequest command received");
                self.submit_action(handle, &request_json, nodes.as_ref().map(String::as_str), timeout, cb);
            }
            LedgerCommand::RegisterSPParser(txn_type, parser, free, cb) => {
                debug!(target: "ledger_command_executor", "RegisterSPParser command received");
                cb(self.register_sp_parser(&txn_type, parser, free));
            }
            LedgerCommand::SignRequest(wallet_handle, submitter_did, request_json, cb) => {
                debug!(target: "ledger_command_executor", "SignRequest command received");
                cb(self.sign_request(wallet_handle, &submitter_did, &request_json));
            }
            LedgerCommand::MultiSignRequest(wallet_handle, submitter_did, request_json, cb) => {
                debug!(target: "ledger_command_executor", "MultiSignRequest command received");
                cb(self.multi_sign_request(wallet_handle, &submitter_did, &request_json));
            }
            LedgerCommand::BuildGetDdoRequest(submitter_did, target_did, cb) => {
                debug!(target: "ledger_command_executor", "BuildGetDdoRequest command received");
                cb(self.build_get_ddo_request(submitter_did.as_ref(), &target_did));
            }
            LedgerCommand::BuildNymRequest(submitter_did, target_did, verkey, alias, role, cb) => {
                debug!(target: "ledger_command_executor", "BuildNymRequest command received");
                cb(self.build_nym_request(&submitter_did, &target_did,
                                          verkey.as_ref().map(String::as_str),
                                          alias.as_ref().map(String::as_str),
                                          role.as_ref().map(String::as_str)));
            }
            LedgerCommand::BuildAttribRequest(submitter_did, target_did, hash, raw, enc, cb) => {
                debug!(target: "ledger_command_executor", "BuildAttribRequest command received");
                cb(self.build_attrib_request(&submitter_did, &target_did,
                                             hash.as_ref().map(String::as_str),
                                             raw.as_ref(),
                                             enc.as_ref().map(String::as_str)));
            }
            LedgerCommand::BuildGetAttribRequest(submitter_did, target_did, raw, hash, enc, cb) => {
                debug!(target: "ledger_command_executor", "BuildGetAttribRequest command received");
                cb(self.build_get_attrib_request(submitter_did.as_ref(), &target_did,
                                                 raw.as_ref().map(String::as_str),
                                                 hash.as_ref().map(String::as_str),
                                                 enc.as_ref().map(String::as_str)));
            }
            LedgerCommand::BuildGetNymRequest(submitter_did, target_did, cb) => {
                debug!(target: "ledger_command_executor", "BuildGetNymRequest command received");
                cb(self.build_get_nym_request(submitter_did.as_ref(), &target_did));
            }
            LedgerCommand::ParseGetNymResponse(get_nym_response, cb) => {
                info!(target: "ledger_command_executor", "ParseGetNymResponse command received");
                cb(self.parse_get_nym_response(&get_nym_response));
            }
            LedgerCommand::BuildSchemaRequest(submitter_did, data, cb) => {
                debug!(target: "ledger_command_executor", "BuildSchemaRequest command received");
                cb(self.build_schema_request(&submitter_did, SchemaV1::from(data)));
            }
            LedgerCommand::BuildGetSchemaRequest(submitter_did, id, cb) => {
                debug!(target: "ledger_command_executor", "BuildGetSchemaRequest command received");
                cb(self.build_get_schema_request(submitter_did.as_ref(), &id));
            }
            LedgerCommand::ParseGetSchemaResponse(get_schema_response, cb) => {
                debug!(target: "ledger_command_executor", "ParseGetSchemaResponse command received");
                cb(self.parse_get_schema_response(&get_schema_response));
            }
            LedgerCommand::BuildCredDefRequest(submitter_did, data, cb) => {
                debug!(target: "ledger_command_executor", "BuildCredDefRequest command received");
                cb(self.build_cred_def_request(&submitter_did, CredentialDefinitionV1::from(data)));
            }
            LedgerCommand::BuildGetCredDefRequest(submitter_did, id, cb) => {
                debug!(target: "ledger_command_executor", "BuildGetCredDefRequest command received");
                cb(self.build_get_cred_def_request(submitter_did.as_ref(), &id));
            }
            LedgerCommand::ParseGetCredDefResponse(get_cred_def_response, cb) => {
                debug!(target: "ledger_command_executor", "ParseGetCredDefResponse command received");
                cb(self.parse_get_cred_def_response(&get_cred_def_response));
            }
            LedgerCommand::BuildNodeRequest(submitter_did, target_did, data, cb) => {
                debug!(target: "ledger_command_executor", "BuildNodeRequest command received");
                cb(self.build_node_request(&submitter_did, &target_did, data));
            }
            LedgerCommand::BuildGetValidatorInfoRequest(submitter_did, cb) => {
                debug!(target: "ledger_command_executor", "BuildGetValidatorInfoRequest command received");
                cb(self.build_get_validator_info_request(&submitter_did));
            }
            LedgerCommand::BuildGetTxnRequest(submitter_did, ledger_type, seq_no, cb) => {
                debug!(target: "ledger_command_executor", "BuildGetTxnRequest command received");
                cb(self.build_get_txn_request(submitter_did.as_ref(), ledger_type.as_ref().map(String::as_str), seq_no));
            }
            LedgerCommand::BuildPoolConfigRequest(submitter_did, writes, force, cb) => {
                debug!(target: "ledger_command_executor", "BuildPoolConfigRequest command received");
                cb(self.build_pool_config_request(&submitter_did, writes, force));
            }
            LedgerCommand::BuildPoolRestartRequest(submitter_did, action, datetime, cb) => {
                debug!(target: "ledger_command_executor", "BuildPoolRestartRequest command received");
                cb(self.build_pool_restart_request(&submitter_did, &action, datetime.as_ref().map(String::as_str)));
            }
            LedgerCommand::BuildPoolUpgradeRequest(submitter_did, name, version, action, sha256, timeout, schedule, justification, reinstall, force, package, cb) => {
                debug!(target: "ledger_command_executor", "BuildPoolUpgradeRequest command received");
                cb(self.build_pool_upgrade_request(&submitter_did, &name, &version, &action, &sha256, timeout,
                                                   schedule,
                                                   justification.as_ref().map(String::as_str),
                                                   reinstall, force, package.as_ref().map(String::as_str)));
            }
            LedgerCommand::BuildRevocRegDefRequest(submitter_did, data, cb) => {
                debug!(target: "ledger_command_executor", "BuildRevocRegDefRequest command received");
                cb(self.build_revoc_reg_def_request(&submitter_did, RevocationRegistryDefinitionV1::from(data)));
            }
            LedgerCommand::BuildGetRevocRegDefRequest(submitter_did, id, cb) => {
                debug!(target: "ledger_command_executor", "BuildGetRevocRegDefRequest command received");
                cb(self.build_get_revoc_reg_def_request(submitter_did.as_ref(), &id));
            }
            LedgerCommand::ParseGetRevocRegDefResponse(get_revoc_ref_def_response, cb) => {
                debug!(target: "ledger_command_executor", "ParseGetRevocRegDefDefResponse command received");
                cb(self.parse_revoc_reg_def_response(&get_revoc_ref_def_response));
            }
            LedgerCommand::BuildRevocRegEntryRequest(submitter_did, revoc_reg_def_id, rev_def_type, value, cb) => {
                debug!(target: "ledger_command_executor", "BuildRevocRegEntryRequest command received");
                cb(self.build_revoc_reg_entry_request(&submitter_did, &revoc_reg_def_id, &rev_def_type, RevocationRegistryDeltaV1::from(value)));
            }
            LedgerCommand::BuildGetRevocRegRequest(submitter_did, revoc_reg_def_id, timestamp, cb) => {
                debug!(target: "ledger_command_executor", "BuildGetRevocRegRequest command received");
                cb(self.build_get_revoc_reg_request(submitter_did.as_ref(), &revoc_reg_def_id, timestamp));
            }
            LedgerCommand::ParseGetRevocRegResponse(get_revoc_reg_response, cb) => {
                debug!(target: "ledger_command_executor", "ParseGetRevocRegResponse command received");
                cb(self.parse_revoc_reg_response(&get_revoc_reg_response));
            }
            LedgerCommand::BuildGetRevocRegDeltaRequest(submitter_did, revoc_reg_def_id, from, to, cb) => {
                debug!(target: "ledger_command_executor", "BuildGetRevocRegDeltaRequest command received");
                cb(self.build_get_revoc_reg_delta_request(submitter_did.as_ref(), &revoc_reg_def_id, from, to));
            }
            LedgerCommand::ParseGetRevocRegDeltaResponse(get_revoc_reg_delta_response, cb) => {
                debug!(target: "ledger_command_executor", "ParseGetRevocRegDeltaResponse command received");
                cb(self.parse_revoc_reg_delta_response(&get_revoc_reg_delta_response));
            }
            LedgerCommand::GetResponseMetadata(response, cb) => {
                debug!(target: "ledger_command_executor", "GetResponseMetadata command received");
                cb(self.get_response_metadata(&response));
            }
            LedgerCommand::BuildAuthRuleRequest(submitter_did, txn_type, action, field, old_value, new_value, constraint, cb) => {
                debug!(target: "ledger_command_executor", "BuildAuthRuleRequest command received");
                cb(self.build_auth_rule_request(&submitter_did, &txn_type, &action, &field, old_value.as_ref().map(String::as_str), new_value.as_ref().map(String::as_str), constraint));
            }
            LedgerCommand::BuildAuthRulesRequest(submitter_did, rules, cb) => {
                debug!(target: "ledger_command_executor", "BuildAuthRulesRequest command received");
                cb(self.build_auth_rules_request(&submitter_did, rules));
            }
            LedgerCommand::BuildGetAuthRuleRequest(submitter_did, txn_type, action, field, old_value, new_value, cb) => {
                debug!(target: "ledger_command_executor", "BuildGetAuthRuleRequest command received");
                cb(self.build_get_auth_rule_request(submitter_did.as_ref(),
                                                    txn_type.as_ref().map(String::as_str),
                                                    action.as_ref().map(String::as_str),
                                                    field.as_ref().map(String::as_str),
                                                    old_value.as_ref().map(String::as_str),
                                                    new_value.as_ref().map(String::as_str)));
            }
            LedgerCommand::GetSchema(pool_handle, submitter_did, id, cb) => {
                debug!(target: "ledger_command_executor", "GetSchema command received");
                self.get_schema(pool_handle, submitter_did.as_ref(), &id, cb);
            }
            LedgerCommand::GetSchemaContinue(id, pool_response, cb_id) => {
                debug!(target: "ledger_command_executor", "GetSchemaContinue command received");
                self._get_schema_continue(id, pool_response, cb_id);
            }
            LedgerCommand::GetCredDef(pool_handle, submitter_did, id, cb) => {
                debug!(target: "ledger_command_executor", "GetCredDef command received");
                self.get_cred_def(pool_handle, submitter_did.as_ref(), &id, cb);
            }
            LedgerCommand::GetCredDefContinue(id, pool_response, cb_id) => {
                debug!(target: "ledger_command_executor", "GetCredDefContinue command received");
                self._get_cred_def_continue(id, pool_response, cb_id);
            }
            LedgerCommand::BuildTxnAuthorAgreementRequest(submitter_did, text, version, ratification_ts, retirement_ts, cb) => {
                debug!(target: "ledger_command_executor", "BuildTxnAuthorAgreementRequest command received");
                cb(self.build_txn_author_agreement_request(&submitter_did, text.as_ref().map(String::as_str), &version, ratification_ts, retirement_ts));
            }
            LedgerCommand::BuildDisableAllTxnAuthorAgreementsRequest(submitter_did, cb) => {
                debug!(target: "ledger_command_executor", "BuildDisableAllTxnAuthorAgreementsRequest command received");
                cb(self.build_disable_all_txn_author_agreements_request(&submitter_did));
            }
            LedgerCommand::BuildGetTxnAuthorAgreementRequest(submitter_did, data, cb) => {
                debug!(target: "ledger_command_executor", "BuildGetTxnAuthorAgreementRequest command received");
                cb(self.build_get_txn_author_agreement_request(submitter_did.as_ref(), data.as_ref()));
            }
            LedgerCommand::BuildAcceptanceMechanismRequests(submitter_did, aml, version, aml_context, cb) => {
                debug!(target: "ledger_command_executor", "BuildAcceptanceMechanismRequests command received");
                cb(self.build_acceptance_mechanisms_request(&submitter_did, aml, &version, aml_context.as_ref().map(String::as_str)));
            }
            LedgerCommand::BuildGetAcceptanceMechanismsRequest(submitter_did, timestamp, version, cb) => {
                debug!(target: "ledger_command_executor", "BuildGetAcceptanceMechanismsRequest command received");
                cb(self.build_get_acceptance_mechanisms_request(submitter_did.as_ref(),
                                                                timestamp,
                                                                version.as_ref().map(String::as_str)));
            }
            LedgerCommand::AppendTxnAuthorAgreementAcceptanceToRequest(request_json, text, version, hash, acc_mech_type, time_of_acceptance, cb) => {
                debug!(target: "ledger_command_executor", "AppendTxnAuthorAgreementAcceptanceToRequest command received");
                cb(self.append_txn_author_agreement_acceptance_to_request(&request_json,
                                                                          text.as_ref().map(String::as_str),
                                                                          version.as_ref().map(String::as_str),
                                                                          hash.as_ref().map(String::as_str),
                                                                          &acc_mech_type,
                                                                          time_of_acceptance));
            }
            LedgerCommand::AppendRequestEndorser(request_json, endorser_did, cb) => {
                debug!(target: "ledger_command_executor", "AppendRequestEndorser command received");
                cb(self.append_request_endorser(&request_json,
                                                &endorser_did));
            }
        };
    }

    fn register_sp_parser(&self, txn_type: &str,
                          parser: CustomTransactionParser, free: CustomFree) -> IndyResult<()> {
        debug!("register_sp_parser >>> txn_type: {:?}, parser: {:?}, free: {:?}",
               txn_type, parser, free);

        PoolService::register_sp_parser(txn_type, parser, free)
            .map_err(IndyError::from)
    }

    fn sign_and_submit_request(&self,
                               pool_handle: PoolHandle,
                               wallet_handle: WalletHandle,
                               submitter_did: &DidValue,
                               request_json: &str,
                               cb: Box<dyn Fn(IndyResult<String>) + Send>) {
        debug!("sign_and_submit_request >>> pool_handle: {:?}, wallet_handle: {:?}, submitter_did: {:?}, request_json: {:?}",
               pool_handle, wallet_handle, submitter_did, request_json);

        match self._sign_request(wallet_handle, submitter_did, request_json, SignatureType::Single) {
            Ok(signed_request) => self.submit_request(pool_handle, signed_request.as_str(), cb),
            Err(err) => cb(Err(err))
        }
    }

    fn _sign_request(&self,
                     wallet_handle: WalletHandle,
                     submitter_did: &DidValue,
                     request_json: &str,
                     signature_type: SignatureType) -> IndyResult<String> {
        debug!("_sign_request >>> wallet_handle: {:?}, submitter_did: {:?}, request_json: {:?}", wallet_handle, submitter_did, request_json);

        let my_did: Did = self.wallet_service.get_indy_object(wallet_handle, &submitter_did.0, &RecordOptions::id_value())?;

        let my_key: Key = self.wallet_service.get_indy_object(wallet_handle, &my_did.verkey, &RecordOptions::id_value())?;

        let mut request: Value = serde_json::from_str(request_json)
            .to_indy(IndyErrorKind::InvalidStructure, "Message is invalid json")?;

        if !request.is_object() {
            return Err(err_msg(IndyErrorKind::InvalidStructure, "Message isn't json object"));
        }

        let serialized_request = serialize_signature(request.clone())?;
        let signature = self.crypto_service.sign(&my_key, &serialized_request.as_bytes().to_vec())?;
        let did = my_did.did.to_short();

        match signature_type {
            SignatureType::Single => { request["signature"] = Value::String(signature.to_base58()); }
            SignatureType::Multi => {
                request.as_object_mut()
                    .map(|request| {
                        if !request.contains_key("signatures") {
                            request.insert("signatures".to_string(), Value::Object(serde_json::Map::new()));
                        }
                        request["signatures"].as_object_mut().unwrap().insert(did.0, Value::String(signature.to_base58()));

                        if let (Some(identifier), Some(signature)) = (request.get("identifier").and_then(Value::as_str).map(str::to_owned),
                                                                      request.remove("signature")) {
                            request["signatures"].as_object_mut().unwrap().insert(identifier, signature);
                        }
                    });
            }
        }

        let res: String = serde_json::to_string(&request)
            .to_indy(IndyErrorKind::InvalidState, "Can't serialize message after signing")?;

        debug!("_sign_request <<< res: {:?}", res);

        Ok(res)
    }

    fn submit_request(&self,
                      handle: PoolHandle,
                      request_json: &str,
                      cb: Box<dyn Fn(IndyResult<String>) + Send>) {
        debug!("submit_request >>> handle: {:?}, request_json: {:?}", handle, request_json);

        if let Err(err) = serde_json::from_str::<Request<serde_json::Value>>(&request_json) {
            return cb(Err(IndyError::from_msg(IndyErrorKind::InvalidStructure, format!("Request is invalid json: {:?}", err))));
        }

        let x: IndyResult<CommandHandle> = self.pool_service.send_tx(handle, request_json);
        match x {
            Ok(cmd_id) => { self.send_callbacks.borrow_mut().insert(cmd_id, cb); }
            Err(err) => { cb(Err(err)); }
        };
    }

    fn submit_action(&self,
                     handle: PoolHandle,
                     request_json: &str,
                     nodes: Option<&str>,
                     timeout: Option<i32>,
                     cb: Box<dyn Fn(IndyResult<String>) + Send>) {
        debug!("submit_action >>> handle: {:?}, request_json: {:?}, nodes: {:?}, timeout: {:?}", handle, request_json, nodes, timeout);

        if let Err(err) = self.ledger_service.validate_action(request_json) {
            return cb(Err(err));
        }

        let x: IndyResult<CommandHandle> = self.pool_service.send_action(handle, request_json, nodes, timeout);
        match x {
            Ok(cmd_id) => { self.send_callbacks.borrow_mut().insert(cmd_id, cb); }
            Err(err) => { cb(Err(err)); }
        };
    }

    fn sign_request(&self,
                    wallet_handle: WalletHandle,
                    submitter_did: &DidValue,
                    request_json: &str) -> IndyResult<String> {
        debug!("sign_request >>> wallet_handle: {:?}, submitter_did: {:?}, request_json: {:?}", wallet_handle, submitter_did, request_json);

        let res = self._sign_request(wallet_handle, submitter_did, request_json, SignatureType::Single)?;

        debug!("sign_request <<< res: {:?}", res);

        Ok(res)
    }

    fn multi_sign_request(&self,
                          wallet_handle: WalletHandle,
                          submitter_did: &DidValue,
                          request_json: &str) -> IndyResult<String> {
        debug!("multi_sign_request >>> wallet_handle: {:?}, submitter_did: {:?}, request_json: {:?}", wallet_handle, submitter_did, request_json);

        let res = self._sign_request(wallet_handle, submitter_did, request_json, SignatureType::Multi)?;

        debug!("multi_sign_request <<< res: {:?}", res);

        Ok(res)
    }
    fn build_get_ddo_request(&self,
                             submitter_did: Option<&DidValue>,
                             target_did: &DidValue) -> IndyResult<String> {
        debug!("build_get_ddo_request >>> submitter_did: {:?}, target_did: {:?}", submitter_did, target_did);

        let res = self.ledger_service.build_get_ddo_request(submitter_did, target_did)?;

        debug!("build_get_ddo_request <<< res: {:?}", res);

        Ok(res)
    }

    fn build_nym_request(&self,
                         submitter_did: &DidValue,
                         target_did: &DidValue,
                         verkey: Option<&str>,
                         alias: Option<&str>,
                         role: Option<&str>) -> IndyResult<String> {
        debug!("build_nym_request >>> submitter_did: {:?}, target_did: {:?}, verkey: {:?}, alias: {:?}, role: {:?}",
               submitter_did, target_did, verkey, alias, role);

        self.crypto_service.validate_did(submitter_did)?;
        self.crypto_service.validate_did(target_did)?;
        if let Some(vk) = verkey {
            self.crypto_service.validate_key(vk)?;
        }

        let res = self.ledger_service.build_nym_request(submitter_did,
                                                        target_did,
                                                        verkey,
                                                        alias,
                                                        role)?;

        debug!("build_nym_request <<< res: {:?}", res);

        Ok(res)
    }

    fn build_attrib_request(&self,
                            submitter_did: &DidValue,
                            target_did: &DidValue,
                            hash: Option<&str>,
                            raw: Option<&serde_json::Value>,
                            enc: Option<&str>) -> IndyResult<String> {
        debug!("build_attrib_request >>> submitter_did: {:?}, target_did: {:?}, hash: {:?}, raw: {:?}, enc: {:?}",
               submitter_did, target_did, hash, raw, enc);

        self.crypto_service.validate_did(submitter_did)?;
        self.crypto_service.validate_did(target_did)?;

        let res = self.ledger_service.build_attrib_request(submitter_did,
                                                           target_did,
                                                           hash,
                                                           raw,
                                                           enc)?;

        debug!("build_attrib_request <<< res: {:?}", res);

        Ok(res)
    }

    fn build_get_attrib_request(&self,
                                submitter_did: Option<&DidValue>,
                                target_did: &DidValue,
                                raw: Option<&str>,
                                hash: Option<&str>,
                                enc: Option<&str>) -> IndyResult<String> {
        debug!("build_get_attrib_request >>> submitter_did: {:?}, target_did: {:?}, raw: {:?}, hash: {:?}, enc: {:?}",
               submitter_did, target_did, raw, hash, enc);

        self.validate_opt_did(submitter_did)?;
        self.crypto_service.validate_did(target_did)?;

        let res = self.ledger_service.build_get_attrib_request(submitter_did,
                                                               target_did,
                                                               raw,
                                                               hash,
                                                               enc)?;

        debug!("build_get_attrib_request <<< res: {:?}", res);

        Ok(res)
    }

    fn build_get_nym_request(&self,
                             submitter_did: Option<&DidValue>,
                             target_did: &DidValue) -> IndyResult<String> {
        debug!("build_get_nym_request >>> submitter_did: {:?}, target_did: {:?}", submitter_did, target_did);

        self.validate_opt_did(submitter_did)?;
        self.crypto_service.validate_did(target_did)?;

        let res = self.ledger_service.build_get_nym_request(submitter_did,
                                                            target_did)?;

        debug!("build_get_attrib_request <<< res: {:?}", res);

        Ok(res)
    }

    fn parse_get_nym_response(&self,
                             get_nym_response: &str) -> IndyResult<String> {
        debug!("parse_get_nym_response >>> get_nym_response: {:?}", get_nym_response);

        let res = self.ledger_service.parse_get_nym_response(get_nym_response)?;

        debug!("parse_get_nym_response <<< res: {:?}", res);

        Ok(res)
    }

    fn build_schema_request(&self,
                            submitter_did: &DidValue,
                            schema: SchemaV1) -> IndyResult<String> {
        debug!("build_schema_request >>> submitter_did: {:?}, schema: {:?}", submitter_did, schema);

        self.crypto_service.validate_did(submitter_did)?;

        let res = self.ledger_service.build_schema_request(submitter_did, schema)?;

        debug!("build_schema_request <<< res: {:?}", res);

        Ok(res)
    }

    fn build_get_schema_request(&self,
                                submitter_did: Option<&DidValue>,
                                id: &SchemaId) -> IndyResult<String> {
        debug!("build_get_schema_request >>> submitter_did: {:?}, id: {:?}", submitter_did, id);

        self.validate_opt_did(submitter_did)?;

        let res = self.ledger_service.build_get_schema_request(submitter_did, id)?;

        debug!("build_get_schema_request <<< res: {:?}", res);

        Ok(res)
    }

    fn parse_get_schema_response(&self,
                                 get_schema_response: &str) -> IndyResult<(String, String)> {
        debug!("parse_get_schema_response >>> get_schema_response: {:?}", get_schema_response);

        let res = self.ledger_service.parse_get_schema_response(get_schema_response, None)?;

        debug!("parse_get_schema_response <<< res: {:?}", res);

        Ok(res)
    }

    fn build_cred_def_request(&self,
                              submitter_did: &DidValue,
                              cred_def: CredentialDefinitionV1) -> IndyResult<String> {
        debug!("build_cred_def_request >>> submitter_did: {:?}, cred_def: {:?}",
               submitter_did, cred_def);

        self.crypto_service.validate_did(submitter_did)?;

        let res = self.ledger_service.build_cred_def_request(submitter_did, cred_def)?;

        debug!("build_cred_def_request <<< res: {:?}", res);

        Ok(res)
    }

    fn build_get_cred_def_request(&self,
                                  submitter_did: Option<&DidValue>,
                                  id: &CredentialDefinitionId) -> IndyResult<String> {
        debug!("build_get_cred_def_request >>> submitter_did: {:?}, id: {:?}", submitter_did, id);

        self.validate_opt_did(submitter_did)?;

        let res = self.ledger_service.build_get_cred_def_request(submitter_did, id)?;

        debug!("build_get_cred_def_request <<< res: {:?}", res);

        Ok(res)
    }

    fn parse_get_cred_def_response(&self,
                                   get_cred_def_response: &str) -> IndyResult<(String, String)> {
        debug!("parse_get_cred_def_response >>> get_cred_def_response: {:?}", get_cred_def_response);

        let res = self.ledger_service.parse_get_cred_def_response(get_cred_def_response, None)?;

        debug!("parse_get_cred_def_response <<< res: {:?}", res);

        Ok(res)
    }

    fn build_node_request(&self,
                          submitter_did: &DidValue,
                          target_did: &DidValue,
                          data: NodeOperationData) -> IndyResult<String> {
        debug!("build_node_request >>> submitter_did: {:?}, target_did: {:?}, data: {:?}",
               submitter_did, target_did, data);

        self.crypto_service.validate_did(submitter_did)?;

        let res = self.ledger_service.build_node_request(submitter_did, target_did, data)?;

        debug!("build_node_request <<< res: {:?}", res);

        Ok(res)
    }

    fn build_get_validator_info_request(&self,
                                        submitter_did: &DidValue) -> IndyResult<String> {
        info!("build_get_validator_info_request >>> submitter_did: {:?}", submitter_did);

        self.crypto_service.validate_did(submitter_did)?;

        let res = self.ledger_service.build_get_validator_info_request(submitter_did)?;

        info!("build_get_validator_info_request <<< res: {:?}", res);

        Ok(res)
    }

    fn build_get_txn_request(&self,
                             submitter_did: Option<&DidValue>,
                             ledger_type: Option<&str>,
                             seq_no: i32) -> IndyResult<String> {
        debug!("build_get_txn_request >>> submitter_did: {:?}, ledger_type: {:?}, seq_no: {:?}",
               submitter_did, ledger_type, seq_no);

        self.validate_opt_did(submitter_did)?;

        let res = self.ledger_service.build_get_txn_request(submitter_did, ledger_type, seq_no)?;

        debug!("build_get_txn_request <<< res: {:?}", res);

        Ok(res)
    }

    fn build_pool_config_request(&self,
                                 submitter_did: &DidValue,
                                 writes: bool,
                                 force: bool) -> IndyResult<String> {
        debug!("build_pool_config_request >>> submitter_did: {:?}, writes: {:?}, force: {:?}",
               submitter_did, writes, force);

        self.crypto_service.validate_did(submitter_did)?;

        let res = self.ledger_service.build_pool_config(submitter_did, writes, force)?;

        debug!("build_pool_config_request  <<< res: {:?}", res);

        Ok(res)
    }

    fn build_pool_restart_request(&self, submitter_did: &DidValue, action: &str,
                                  datetime: Option<&str>) -> IndyResult<String> {
        debug!("build_pool_restart_request >>> submitter_did: {:?}, action: {:?}, datetime: {:?}", submitter_did, action, datetime);

        self.crypto_service.validate_did(&submitter_did)?;

        let res = self.ledger_service.build_pool_restart(&submitter_did, action, datetime)?;

        debug!("build_pool_config_request  <<< res: {:?}", res);

        Ok(res)
    }

    fn build_pool_upgrade_request(&self,
                                  submitter_did: &DidValue,
                                  name: &str,
                                  version: &str,
                                  action: &str,
                                  sha256: &str,
                                  timeout: Option<u32>,
                                  schedule: Option<Schedule>,
                                  justification: Option<&str>,
                                  reinstall: bool,
                                  force: bool,
                                  package: Option<&str>) -> IndyResult<String> {
        debug!("build_pool_upgrade_request >>> submitter_did: {:?}, name: {:?}, version: {:?}, action: {:?}, sha256: {:?},\
         timeout: {:?}, schedule: {:?}, justification: {:?}, reinstall: {:?}, force: {:?}, package: {:?}",
               submitter_did, name, version, action, sha256, timeout, schedule, justification, reinstall, force, package);

        self.crypto_service.validate_did(&submitter_did)?;

        let res = self.ledger_service.build_pool_upgrade(&submitter_did, name, version, action, sha256,
                                                         timeout, schedule, justification, reinstall, force, package)?;

        debug!("build_pool_upgrade_request  <<< res: {:?}", res);

        Ok(res)
    }

    fn build_revoc_reg_def_request(&self,
                                   submitter_did: &DidValue,
                                   data: RevocationRegistryDefinitionV1) -> IndyResult<String> {
        debug!("build_revoc_reg_def_request >>> submitter_did: {:?}, data: {:?}", submitter_did, data);

        self.crypto_service.validate_did(&submitter_did)?;

        let res = self.ledger_service.build_revoc_reg_def_request(&submitter_did, data)?;

        debug!("build_revoc_reg_def_request  <<< res: {:?}", res);

        Ok(res)
    }

    fn build_get_revoc_reg_def_request(&self,
                                       submitter_did: Option<&DidValue>,
                                       id: &RevocationRegistryId) -> IndyResult<String> {
        debug!("build_get_revoc_reg_def_request >>> submitter_did: {:?}, id: {:?}", submitter_did, id);

        self.validate_opt_did(submitter_did)?;

        let res = self.ledger_service.build_get_revoc_reg_def_request(submitter_did, id)?;

        debug!("build_get_revoc_reg_def_request  <<< res: {:?}", res);

        Ok(res)
    }

    fn parse_revoc_reg_def_response(&self,
                                    get_revoc_reg_def_response: &str) -> IndyResult<(String, String)> {
        debug!("parse_revoc_reg_def_response >>> get_revoc_reg_def_response: {:?}", get_revoc_reg_def_response);

        let res = self.ledger_service.parse_get_revoc_reg_def_response(get_revoc_reg_def_response)?;

        debug!("parse_revoc_reg_def_response <<< res: {:?}", res);

        Ok(res)
    }

    fn build_revoc_reg_entry_request(&self,
                                     submitter_did: &DidValue,
                                     revoc_reg_def_id: &RevocationRegistryId,
                                     revoc_def_type: &str,
                                     value: RevocationRegistryDeltaV1) -> IndyResult<String> {
        debug!("build_revoc_reg_entry_request >>> submitter_did: {:?}, revoc_reg_def_id: {:?}, revoc_def_type: {:?}, value: {:?}",
               submitter_did, revoc_reg_def_id, revoc_def_type, value);

        self.crypto_service.validate_did(&submitter_did)?;

        let res = self.ledger_service.build_revoc_reg_entry_request(&submitter_did, revoc_reg_def_id, revoc_def_type, value)?;

        debug!("build_revoc_reg_request  <<< res: {:?}", res);

        Ok(res)
    }

    fn build_get_revoc_reg_request(&self,
                                   submitter_did: Option<&DidValue>,
                                   revoc_reg_def_id: &RevocationRegistryId,
                                   timestamp: i64) -> IndyResult<String> {
        debug!("build_get_revoc_reg_request >>> submitter_did: {:?}, revoc_reg_def_id: {:?}, timestamp: {:?}", submitter_did, revoc_reg_def_id, timestamp);

        self.validate_opt_did(submitter_did)?;

        let res = self.ledger_service.build_get_revoc_reg_request(submitter_did, revoc_reg_def_id, timestamp)?;

        debug!("build_get_revoc_reg_request  <<< res: {:?}", res);

        Ok(res)
    }

    fn parse_revoc_reg_response(&self,
                                get_revoc_reg_response: &str) -> IndyResult<(String, String, u64)> {
        debug!("parse_revoc_reg_response >>> get_revoc_reg_response: {:?}", get_revoc_reg_response);

        let res = self.ledger_service.parse_get_revoc_reg_response(get_revoc_reg_response)?;

        debug!("parse_revoc_reg_response <<< res: {:?}", res);

        Ok(res)
    }

    fn build_get_revoc_reg_delta_request(&self,
                                         submitter_did: Option<&DidValue>,
                                         revoc_reg_def_id: &RevocationRegistryId,
                                         from: Option<i64>,
                                         to: i64) -> IndyResult<String> {
        debug!("build_get_revoc_reg_delta_request >>> submitter_did: {:?}, revoc_reg_def_id: {:?}, from: {:?}, to: {:?}", submitter_did, revoc_reg_def_id, from, to);

        self.validate_opt_did(submitter_did)?;

        let res = self.ledger_service.build_get_revoc_reg_delta_request(submitter_did, revoc_reg_def_id, from, to)?;

        debug!("build_get_revoc_reg_delta_request  <<< res: {:?}", res);

        Ok(res)
    }

    fn parse_revoc_reg_delta_response(&self,
                                      get_revoc_reg_delta_response: &str) -> IndyResult<(String, String, u64)> {
        debug!("parse_revoc_reg_delta_response >>> get_revoc_reg_delta_response: {:?}", get_revoc_reg_delta_response);

        let res = self.ledger_service.parse_get_revoc_reg_delta_response(get_revoc_reg_delta_response)?;

        debug!("parse_revoc_reg_delta_response <<< res: {:?}", res);

        Ok(res)
    }

    fn get_response_metadata(&self,
                             response: &str) -> IndyResult<String> {
        debug!("get_response_metadata >>> response: {:?}", response);

        let metadata = parse_response_metadata(response)?;

        let res = serde_json::to_string(&metadata)
            .to_indy(IndyErrorKind::InvalidState, "Cannot serialize ResponseMetadata")?;

        debug!("get_response_metadata <<< res: {:?}", res);

        Ok(res)
    }

    fn build_auth_rule_request(&self,
                               submitter_did: &DidValue,
                               txn_type: &str,
                               action: &str,
                               field: &str,
                               old_value: Option<&str>,
                               new_value: Option<&str>,
                               constraint: Constraint) -> IndyResult<String> {
        debug!("build_auth_rule_request >>> submitter_did: {:?}, txn_type: {:?}, action: {:?}, field: {:?}, \
            old_value: {:?}, new_value: {:?}, constraint: {:?}", submitter_did, txn_type, action, field, old_value, new_value, constraint);

        self.crypto_service.validate_did(&submitter_did)?;

        let res = self.ledger_service.build_auth_rule_request(&submitter_did, txn_type, action, field, old_value, new_value, constraint)?;

        debug!("build_auth_rule_request <<< res: {:?}", res);

        Ok(res)
    }

    fn build_auth_rules_request(&self,
                                submitter_did: &DidValue,
                                rules: AuthRules) -> IndyResult<String> {
        debug!("build_auth_rules_request >>> submitter_did: {:?}, rules: {:?}", submitter_did, rules);

        self.validate_opt_did(Some(submitter_did))?;

        let res = self.ledger_service.build_auth_rules_request(submitter_did, rules)?;

        debug!("build_auth_rules_request <<< res: {:?}", res);

        Ok(res)
    }

    fn build_get_auth_rule_request(&self,
                                   submitter_did: Option<&DidValue>,
                                   txn_type: Option<&str>,
                                   action: Option<&str>,
                                   field: Option<&str>,
                                   old_value: Option<&str>,
                                   new_value: Option<&str>) -> IndyResult<String> {
        debug!("build_get_auth_rule_request >>> submitter_did: {:?}, auth_type: {:?}, auth_action: {:?}, field: {:?}, \
            old_value: {:?}, new_value: {:?}", submitter_did, txn_type, action, field, old_value, new_value);

        self.validate_opt_did(submitter_did)?;

        let res = self.ledger_service.build_get_auth_rule_request(submitter_did, txn_type, action, field, old_value, new_value)?;

        debug!("build_get_auth_rule_request <<< res: {:?}", res);

        Ok(res)
    }

    fn build_txn_author_agreement_request(&self,
                                          submitter_did: &DidValue,
                                          text: Option<&str>,
                                          version: &str,
                                          ratification_ts: Option<u64>,
                                          retirement_ts: Option<u64>) -> IndyResult<String> {
        debug!("build_txn_author_agreement_request >>> submitter_did: {:?}, text: {:?}, version: {:?}, ratification_ts {:?}, retirement_ts {:?}",
               submitter_did, text, version, ratification_ts, retirement_ts);

        self.crypto_service.validate_did(submitter_did)?;

        let res = self.ledger_service.build_txn_author_agreement_request(submitter_did, text, version, ratification_ts, retirement_ts)?;

        debug!("build_txn_author_agreement_request <<< res: {:?}", res);

        Ok(res)
    }

    fn build_disable_all_txn_author_agreements_request(&self, submitter_did: &DidValue) -> IndyResult<String> {
        debug!("build_disable_all_txn_author_agreements_request >>> submitter_did: {:?}", submitter_did);

        self.crypto_service.validate_did(submitter_did)?;

        let res = self.ledger_service.build_disable_all_txn_author_agreements_request(submitter_did)?;

        debug!("build_disable_all_txn_author_agreements_request <<< res: {:?}", res);

        Ok(res)
    }

    fn build_get_txn_author_agreement_request(&self,
                                              submitter_did: Option<&DidValue>,
                                              data: Option<&GetTxnAuthorAgreementData>) -> IndyResult<String> {
        debug!("build_get_txn_author_agreement_request >>> submitter_did: {:?}, data: {:?}", submitter_did, data);

        self.validate_opt_did(submitter_did)?;

        let res = self.ledger_service.build_get_txn_author_agreement_request(submitter_did, data)?;

        debug!("build_get_txn_author_agreement_request <<< res: {:?}", res);

        Ok(res)
    }

    fn build_acceptance_mechanisms_request(&self,
                                           submitter_did: &DidValue,
                                           aml: AcceptanceMechanisms,
                                           version: &str,
                                           aml_context: Option<&str>) -> IndyResult<String> {
        debug!("build_acceptance_mechanisms_request >>> submitter_did: {:?}, aml: {:?}, version: {:?}, aml_context: {:?}", submitter_did, aml, version, aml_context);

        self.crypto_service.validate_did(submitter_did)?;

        let res = self.ledger_service.build_acceptance_mechanisms_request(submitter_did, aml, version, aml_context)?;

        debug!("build_acceptance_mechanisms_request <<< res: {:?}", res);

        Ok(res)
    }

    fn build_get_acceptance_mechanisms_request(&self,
                                               submitter_did: Option<&DidValue>,
                                               timestamp: Option<u64>,
                                               version: Option<&str>) -> IndyResult<String> {
        debug!("build_get_acceptance_mechanisms_request >>> submitter_did: {:?}, timestamp: {:?}, version: {:?}", submitter_did, timestamp, version);

        self.validate_opt_did(submitter_did)?;

        let res = self.ledger_service.build_get_acceptance_mechanisms_request(submitter_did, timestamp, version)?;

        debug!("build_get_acceptance_mechanisms_request <<< res: {:?}", res);

        Ok(res)
    }

    fn append_txn_author_agreement_acceptance_to_request(&self,
                                                         request_json: &str,
                                                         text: Option<&str>,
                                                         version: Option<&str>,
                                                         taa_digest: Option<&str>,
                                                         acc_mech_type: &str,
                                                         time: u64) -> IndyResult<String> {
        debug!("append_txn_author_agreement_acceptance_to_request >>> request_json: {:?}, text: {:?}, version: {:?}, taa_digest: {:?}, acc_mech_type: {:?}, time: {:?}",
               request_json, text, version, taa_digest, acc_mech_type, time);

        let mut request: serde_json::Value = serde_json::from_str(request_json)
            .map_err(|err| IndyError::from_msg(IndyErrorKind::InvalidStructure, format!("Cannot deserialize request: {:?}", err)))?;

        request["taaAcceptance"] = json!(self.ledger_service.prepare_acceptance_data(text, version, taa_digest, acc_mech_type, time)?);

        let res: String = serde_json::to_string(&request)
            .to_indy(IndyErrorKind::InvalidState, "Can't serialize request after adding author agreement acceptance data")?;

        debug!("append_txn_author_agreement_acceptance_to_request <<< res: {:?}", res);

        Ok(res)
    }

    fn append_request_endorser(&self,
                               request_json: &str,
                               endorser_did: &DidValue) -> IndyResult<String> {
        debug!("append_request_endorser >>> request_json: {:?}, endorser_did: {:?}", request_json, endorser_did);

        self.crypto_service.validate_did(endorser_did)?;

        let endorser_did = endorser_did.to_short();

        let mut request: serde_json::Value = serde_json::from_str(request_json)
            .map_err(|err| IndyError::from_msg(IndyErrorKind::InvalidStructure, format!("Cannot deserialize request: {:?}", err)))?;

        request["endorser"] = json!(endorser_did);

        let res: String = serde_json::to_string(&request)
            .to_indy(IndyErrorKind::InvalidState, "Can't serialize request after adding endorser")?;

        debug!("append_request_endorser <<< res: {:?}", res);

        Ok(res)
    }

    fn validate_opt_did(&self, did: Option<&DidValue>) -> IndyResult<()> {
        match did {
            Some(did) => Ok(self.crypto_service.validate_did(did)?),
            None => Ok(())
        }
    }

    fn get_schema(&self, pool_handle: i32, submitter_did: Option<&DidValue>, id: &SchemaId, cb: BoxedCallbackStringStringSend) {
        let request_json = try_cb!(self.build_get_schema_request(submitter_did, id), cb);

        let cb_id = next_command_handle();
        self.pending_callbacks.borrow_mut().insert(cb_id, cb);
        let id = id.clone();

        self.submit_request(pool_handle, &request_json, Box::new(move |response| {
            CommandExecutor::instance().send(
                Command::Ledger(
                    LedgerCommand::GetSchemaContinue(
                        id.clone(),
                        response,
                        cb_id
                    )
                )
            ).unwrap();
        }));
    }

    fn _get_schema_continue(&self, id: SchemaId, pool_response: IndyResult<String>, cb_id: CommandHandle) {
        let cb = self.pending_callbacks.borrow_mut().remove(&cb_id).expect("FIXME INVALID STATE");
        let pool_response = try_cb!(pool_response, cb);
        cb(self.ledger_service.parse_get_schema_response(&pool_response, id.get_method().as_ref().map(String::as_str)))
    }

    fn get_cred_def(&self, pool_handle: i32, submitter_did: Option<&DidValue>, id: &CredentialDefinitionId, cb: BoxedCallbackStringStringSend) {
        let request_json = try_cb!(self.build_get_cred_def_request(submitter_did, id), cb);

        let cb_id = next_command_handle();
        self.pending_callbacks.borrow_mut().insert(cb_id, cb);
        let id = id.clone();

        self.submit_request(pool_handle, &request_json, Box::new(move |response| {
            CommandExecutor::instance().send(
                Command::Ledger(
                    LedgerCommand::GetCredDefContinue(
                        id.clone(),
                        response,
                        cb_id
                    )
                )
            ).unwrap();
        }));
    }

    fn _get_cred_def_continue(&self, id: CredentialDefinitionId, pool_response: IndyResult<String>, cb_id: CommandHandle) {
        let cb = self.pending_callbacks.borrow_mut().remove(&cb_id).expect("FIXME INVALID STATE");
        let pool_response = try_cb!(pool_response, cb);
        cb(self.ledger_service.parse_get_cred_def_response(&pool_response, id.get_method().as_ref().map(String::as_str)))
    }
}

enum SignatureType {
    Single,
    Multi
}