text:
#if HAVE_OPENSSL_SSL_H

#include "openssladapter.h"
#include "opensslidentity.h"

#if defined(POSIX)
#include <unistd.h>
#endif

// Must be included first before openssl headers.
#include "talk/base/win32.h"  // NOLINT

#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/opensslv.h>
#include <openssl/rand.h>
#include <openssl/x509v3.h>

#if HAVE_CONFIG_H
#include "config.h"
#endif  // HAVE_CONFIG_H

#include "talk/base/common.h"
#include "talk/base/logging.h"
#include "talk/base/openssl.h"
#include "sslroots.h"
#include "talk/base/stringutils.h"

// TODO: Use a nicer abstraction for mutex.

#if defined(WIN32)
  #define MUTEX_TYPE HANDLE
  #define MUTEX_SETUP(x) (x) = CreateMutex(NULL, FALSE, NULL)
  #define MUTEX_CLEANUP(x) CloseHandle(x)
  #define MUTEX_LOCK(x) WaitForSingleObject((x), INFINITE)
  #define MUTEX_UNLOCK(x) ReleaseMutex(x)
  #define THREAD_ID GetCurrentThreadId()
#elif defined(POSIX)
  #define MUTEX_TYPE pthread_mutex_t
  #define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
  #define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
  #define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
  #define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
  #define THREAD_ID pthread_self()
#else
  #error You must define mutex operations appropriate for your platform!
#endif

struct CRYPTO_dynlock_value {
  MUTEX_TYPE mutex;
};

//////////////////////////////////////////////////////////////////////
// SocketBIO
//////////////////////////////////////////////////////////////////////

namespace tincan {
static int socket_write(BIO* h, const char* buf, int num);
static int socket_read(BIO* h, char* buf, int size);
static int socket_puts(BIO* h, const char* str);
static long socket_ctrl(BIO* h, int cmd, long arg1, void* arg2);
static int socket_new(BIO* h);
static int socket_free(BIO* data);

static BIO_METHOD methods_socket = {
  BIO_TYPE_BIO,
  "socket",
  socket_write,
  socket_read,
  socket_puts,
  0,
  socket_ctrl,
  socket_new,
  socket_free,
  NULL,
};

BIO_METHOD* BIO_s_socket2() { return(&methods_socket); }

BIO* BIO_new_socket(talk_base::AsyncSocket* socket) {
  BIO* ret = BIO_new(BIO_s_socket2());
  if (ret == NULL) {
          return NULL;
  }
  ret->ptr = socket;
  return ret;
}

static int socket_new(BIO* b) {
  b->shutdown = 0;
  b->init = 1;
  b->num = 0; // 1 means socket closed
  b->ptr = 0;
  return 1;
}

static int socket_free(BIO* b) {
  if (b == NULL)
    return 0;
  return 1;
}

static int socket_read(BIO* b, char* out, int outl) {
  if (!out)
    return -1;
  talk_base::AsyncSocket* socket = static_cast<talk_base::AsyncSocket*>(b->ptr);
  BIO_clear_retry_flags(b);
  int result = socket->Recv(out, outl);
  if (result > 0) {
    return result;
  } else if (result == 0) {
    b->num = 1;
  } else if (socket->IsBlocking()) {
    BIO_set_retry_read(b);
  }
  return -1;
}

static int socket_write(BIO* b, const char* in, int inl) {
  if (!in)
    return -1;
  talk_base::AsyncSocket* socket = static_cast<talk_base::AsyncSocket*>(b->ptr);
  BIO_clear_retry_flags(b);
  int result = socket->Send(in, inl);
  if (result > 0) {
    return result;
  } else if (socket->IsBlocking()) {
    BIO_set_retry_write(b);
  }
  return -1;
}

static int socket_puts(BIO* b, const char* str) {
  return socket_write(b, str, strlen(str));
}

static long socket_ctrl(BIO* b, int cmd, long num, void* ptr) {
  UNUSED(num);
  UNUSED(ptr);

  switch (cmd) {
  case BIO_CTRL_RESET:
    return 0;
  case BIO_CTRL_EOF:
    return b->num;
  case BIO_CTRL_WPENDING:
  case BIO_CTRL_PENDING:
    return 0;
  case BIO_CTRL_FLUSH:
    return 1;
  default:
    return 0;
  }
}

/////////////////////////////////////////////////////////////////////////////
// OpenSSLAdapter
/////////////////////////////////////////////////////////////////////////////

// This array will store all of the mutexes available to OpenSSL.
static MUTEX_TYPE* mutex_buf = NULL;

static void locking_function(int mode, int n, const char * file, int line) {
  if (mode & CRYPTO_LOCK) {
    MUTEX_LOCK(mutex_buf[n]);
  } else {
    MUTEX_UNLOCK(mutex_buf[n]);
  }
}

static unsigned long id_function() {  // NOLINT
  // Use old-style C cast because THREAD_ID's type varies with the platform,
  // in some cases requiring static_cast, and in others requiring
  // reinterpret_cast.
  return (unsigned long)THREAD_ID; // NOLINT
}

static CRYPTO_dynlock_value* dyn_create_function(const char* file, int line) {
  CRYPTO_dynlock_value* value = new CRYPTO_dynlock_value;
  if (!value)
    return NULL;
  MUTEX_SETUP(value->mutex);
  return value;
}

static void dyn_lock_function(int mode, CRYPTO_dynlock_value* l,
                              const char* file, int line) {
  if (mode & CRYPTO_LOCK) {
    MUTEX_LOCK(l->mutex);
  } else {
    MUTEX_UNLOCK(l->mutex);
  }
}

static void dyn_destroy_function(CRYPTO_dynlock_value* l,
                                 const char* file, int line) {
  MUTEX_CLEANUP(l->mutex);
  delete l;
}

talk_base::VerificationCallback OpenSSLAdapter::custom_verify_callback_ = NULL;

bool OpenSSLAdapter::InitializeSSL(talk_base::VerificationCallback callback) {
  if (!InitializeSSLThread() || !SSL_library_init())
      return false;
#if !defined(ADDRESS_SANITIZER) || !defined(OSX)
  // Loading the error strings crashes mac_asan.  Omit this debugging aid there.
  SSL_load_error_strings();
#endif
  ERR_load_BIO_strings();
  OpenSSL_add_all_algorithms();
  RAND_poll();
  custom_verify_callback_ = callback;
  return true;
}

bool OpenSSLAdapter::InitializeSSLThread() {
  mutex_buf = new MUTEX_TYPE[CRYPTO_num_locks()];
  if (!mutex_buf)
    return false;
  for (int i = 0; i < CRYPTO_num_locks(); ++i)
    MUTEX_SETUP(mutex_buf[i]);

  // we need to cast our id_function to return an unsigned long -- pthread_t is
  // a pointer
  CRYPTO_set_id_callback(id_function);
  CRYPTO_set_locking_callback(locking_function);
  CRYPTO_set_dynlock_create_callback(dyn_create_function);
  CRYPTO_set_dynlock_lock_callback(dyn_lock_function);
  CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function);
  return true;
}

bool OpenSSLAdapter::CleanupSSL() {
  if (!mutex_buf)
    return false;
  CRYPTO_set_id_callback(NULL);
  CRYPTO_set_locking_callback(NULL);
  CRYPTO_set_dynlock_create_callback(NULL);
  CRYPTO_set_dynlock_lock_callback(NULL);
  CRYPTO_set_dynlock_destroy_callback(NULL);
  for (int i = 0; i < CRYPTO_num_locks(); ++i)
    MUTEX_CLEANUP(mutex_buf[i]);
  delete [] mutex_buf;
  mutex_buf = NULL;
  return true;
}

OpenSSLAdapter::OpenSSLAdapter(AsyncSocket* socket)
  : SSLAdapter(socket),
    state_(SSL_NONE),
    ssl_read_needs_write_(false),
    ssl_write_needs_read_(false),
    restartable_(false),
    ssl_(NULL), ssl_ctx_(NULL),
    custom_verification_succeeded_(false) {
}

OpenSSLAdapter::~OpenSSLAdapter() {
  Cleanup();
}

int
OpenSSLAdapter::StartSSL(const char* hostname, bool restartable) {
  if (state_ != SSL_NONE)
    return -1;

  ssl_host_name_ = hostname;
  restartable_ = restartable;

  if (socket_->GetState() != Socket::CS_CONNECTED) {
    state_ = SSL_WAIT;
    return 0;
  }

  state_ = SSL_CONNECTING;
  if (int err = BeginSSL()) {
    Error("BeginSSL", err, false);
    return err;
  }

  return 0;
}

int
OpenSSLAdapter::BeginSSL() {
  LOG(LS_INFO) << "BeginSSL: " << ssl_host_name_;
  ASSERT(state_ == SSL_CONNECTING);

  int err = 0;
  BIO* bio = NULL;

  // First set up the context
  if (!ssl_ctx_)
    ssl_ctx_ = SetupSSLContext();

  if (!ssl_ctx_) {
    err = -1;
    goto ssl_error;
  }

  bio = BIO_new_socket(static_cast<AsyncSocketAdapter*>(socket_));
  if (!bio) {
    err = -1;
    goto ssl_error;
  }

  ssl_ = SSL_new(ssl_ctx_);
  if (!ssl_) {
    err = -1;
    goto ssl_error;
  }

  SSL_set_app_data(ssl_, this);

  SSL_set_bio(ssl_, bio, bio);
  SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE |
                     SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);

  // the SSL object owns the bio now
  bio = NULL;

  // Do the connect
  err = ContinueSSL();
  if (err != 0)
    goto ssl_error;

  return err;

ssl_error:
  Cleanup();
  if (bio)
    BIO_free(bio);

  return err;
}

int
OpenSSLAdapter::ContinueSSL() {
  ASSERT(state_ == SSL_CONNECTING);

  int code = SSL_connect(ssl_);
  switch (SSL_get_error(ssl_, code)) {
  case SSL_ERROR_NONE:
    if (!SSLPostConnectionCheck(ssl_, ssl_host_name_.c_str())) {
      LOG(LS_ERROR) << "TLS post connection check failed";
      // make sure we close the socket
      Cleanup();
      // The connect failed so return -1 to shut down the socket
      return -1;
    }

    state_ = SSL_CONNECTED;
    AsyncSocketAdapter::OnConnectEvent(this);
#if 0  // TODO: worry about this
    // Don't let ourselves go away during the callbacks
    PRefPtr<OpenSSLAdapter> lock(this);
    LOG(LS_INFO) << " -- onStreamReadable";
    AsyncSocketAdapter::OnReadEvent(this);
    LOG(LS_INFO) << " -- onStreamWriteable";
    AsyncSocketAdapter::OnWriteEvent(this);
#endif
    break;

  case SSL_ERROR_WANT_READ:
  case SSL_ERROR_WANT_WRITE:
    break;

  case SSL_ERROR_ZERO_RETURN:
  default:
    LOG(LS_WARNING) << "ContinueSSL -- error " << code;
    return (code != 0) ? code : -1;
  }

  return 0;
}

void
OpenSSLAdapter::Error(const char* context, int err, bool signal) {
  LOG(LS_WARNING) << "OpenSSLAdapter::Error("
                  << context << ", " << err << ")";
  state_ = SSL_ERROR;
  SetError(err);
  if (signal)
    AsyncSocketAdapter::OnCloseEvent(this, err);
}

void
OpenSSLAdapter::Cleanup() {
  LOG(LS_INFO) << "Cleanup";

  state_ = SSL_NONE;
  ssl_read_needs_write_ = false;
  ssl_write_needs_read_ = false;
  custom_verification_succeeded_ = false;

  if (ssl_) {
    SSL_free(ssl_);
    ssl_ = NULL;
  }

  if (ssl_ctx_) {
    SSL_CTX_free(ssl_ctx_);
    ssl_ctx_ = NULL;
  }
}

//
// AsyncSocket Implementation
//

int
OpenSSLAdapter::Send(const void* pv, size_t cb) {
  //LOG(LS_INFO) << "OpenSSLAdapter::Send(" << cb << ")";

  switch (state_) {
  case SSL_NONE:
    return AsyncSocketAdapter::Send(pv, cb);

  case SSL_WAIT:
  case SSL_CONNECTING:
    SetError(EWOULDBLOCK);
    return SOCKET_ERROR;

  case SSL_CONNECTED:
    break;

  case SSL_ERROR:
  default:
    return SOCKET_ERROR;
  }

  // OpenSSL will return an error if we try to write zero bytes
  if (cb == 0)
    return 0;

  ssl_write_needs_read_ = false;

  int code = SSL_write(ssl_, pv, cb);
  switch (SSL_get_error(ssl_, code)) {
  case SSL_ERROR_NONE:
    //LOG(LS_INFO) << " -- success";
    return code;
  case SSL_ERROR_WANT_READ:
    //LOG(LS_INFO) << " -- error want read";
    ssl_write_needs_read_ = true;
    SetError(EWOULDBLOCK);
    break;
  case SSL_ERROR_WANT_WRITE:
    //LOG(LS_INFO) << " -- error want write";
    SetError(EWOULDBLOCK);
    break;
  case SSL_ERROR_ZERO_RETURN:
    //LOG(LS_INFO) << " -- remote side closed";
    SetError(EWOULDBLOCK);
    // do we need to signal closure?
    break;
  default:
    //LOG(LS_INFO) << " -- error " << code;
    Error("SSL_write", (code ? code : -1), false);
    break;
  }

  return SOCKET_ERROR;
}

int
OpenSSLAdapter::Recv(void* pv, size_t cb) {
  //LOG(LS_INFO) << "OpenSSLAdapter::Recv(" << cb << ")";
  switch (state_) {

  case SSL_NONE:
    return AsyncSocketAdapter::Recv(pv, cb);

  case SSL_WAIT:
  case SSL_CONNECTING:
    SetError(EWOULDBLOCK);
    return SOCKET_ERROR;

  case SSL_CONNECTED:
    break;

  case SSL_ERROR:
  default:
    return SOCKET_ERROR;
  }

  // Don't trust OpenSSL with zero byte reads
  if (cb == 0)
    return 0;

  ssl_read_needs_write_ = false;

  int code = SSL_read(ssl_, pv, cb);
  switch (SSL_get_error(ssl_, code)) {
  case SSL_ERROR_NONE:
    //LOG(LS_INFO) << " -- success";
    return code;
  case SSL_ERROR_WANT_READ:
    //LOG(LS_INFO) << " -- error want read";
    SetError(EWOULDBLOCK);
    break;
  case SSL_ERROR_WANT_WRITE:
    //LOG(LS_INFO) << " -- error want write";
    ssl_read_needs_write_ = true;
    SetError(EWOULDBLOCK);
    break;
  case SSL_ERROR_ZERO_RETURN:
    //LOG(LS_INFO) << " -- remote side closed";
    SetError(EWOULDBLOCK);
    // do we need to signal closure?
    break;
  default:
    //LOG(LS_INFO) << " -- error " << code;
    Error("SSL_read", (code ? code : -1), false);
    break;
  }

  return SOCKET_ERROR;
}

int
OpenSSLAdapter::Close() {
  Cleanup();
  state_ = restartable_ ? SSL_WAIT : SSL_NONE;
  return AsyncSocketAdapter::Close();
}

talk_base::Socket::ConnState
OpenSSLAdapter::GetState() const {
  //if (signal_close_)
  //  return CS_CONNECTED;
  ConnState state = socket_->GetState();
  if ((state == CS_CONNECTED)
      && ((state_ == SSL_WAIT) || (state_ == SSL_CONNECTING)))
    state = CS_CONNECTING;
  return state;
}

void
OpenSSLAdapter::OnConnectEvent(AsyncSocket* socket) {
  LOG(LS_INFO) << "OpenSSLAdapter::OnConnectEvent";
  if (state_ != SSL_WAIT) {
    ASSERT(state_ == SSL_NONE);
    AsyncSocketAdapter::OnConnectEvent(socket);
    return;
  }

  state_ = SSL_CONNECTING;
  if (int err = BeginSSL()) {
    AsyncSocketAdapter::OnCloseEvent(socket, err);
  }
}

void
OpenSSLAdapter::OnReadEvent(AsyncSocket* socket) {
  //LOG(LS_INFO) << "OpenSSLAdapter::OnReadEvent";

  if (state_ == SSL_NONE) {
    AsyncSocketAdapter::OnReadEvent(socket);
    return;
  }

  if (state_ == SSL_CONNECTING) {
    if (int err = ContinueSSL()) {
      Error("ContinueSSL", err);
    }
    return;
  }

  if (state_ != SSL_CONNECTED)
    return;

  // Don't let ourselves go away during the callbacks
  //PRefPtr<OpenSSLAdapter> lock(this); // TODO: fix this
  if (ssl_write_needs_read_)  {
    //LOG(LS_INFO) << " -- onStreamWriteable";
    AsyncSocketAdapter::OnWriteEvent(socket);
  }

  //LOG(LS_INFO) << " -- onStreamReadable";
  AsyncSocketAdapter::OnReadEvent(socket);
}

void
OpenSSLAdapter::OnWriteEvent(AsyncSocket* socket) {
  //LOG(LS_INFO) << "OpenSSLAdapter::OnWriteEvent";

  if (state_ == SSL_NONE) {
    AsyncSocketAdapter::OnWriteEvent(socket);
    return;
  }

  if (state_ == SSL_CONNECTING) {
    if (int err = ContinueSSL()) {
      Error("ContinueSSL", err);
    }
    return;
  }

  if (state_ != SSL_CONNECTED)
    return;

  // Don't let ourselves go away during the callbacks
  //PRefPtr<OpenSSLAdapter> lock(this); // TODO: fix this

  if (ssl_read_needs_write_)  {
    //LOG(LS_INFO) << " -- onStreamReadable";
    AsyncSocketAdapter::OnReadEvent(socket);
  }

  //LOG(LS_INFO) << " -- onStreamWriteable";
  AsyncSocketAdapter::OnWriteEvent(socket);
}

void
OpenSSLAdapter::OnCloseEvent(AsyncSocket* socket, int err) {
  LOG(LS_INFO) << "OpenSSLAdapter::OnCloseEvent(" << err << ")";
  AsyncSocketAdapter::OnCloseEvent(socket, err);
}

// This code is taken from the "Network Security with OpenSSL"
// sample in chapter 5

bool OpenSSLAdapter::VerifyServerName(SSL* ssl, const char* host,
                                      bool ignore_bad_cert) {
  if (!host)
    return false;

  // Checking the return from SSL_get_peer_certificate here is not strictly
  // necessary.  With our setup, it is not possible for it to return
  // NULL.  However, it is good form to check the return.
  X509* certificate = SSL_get_peer_certificate(ssl);
  if (!certificate)
    return false;

  // Logging certificates is extremely verbose. So it is disabled by default.
#ifdef LOG_CERTIFICATES
  {
    LOG(LS_INFO) << "Certificate from server:";
    BIO* mem = BIO_new(BIO_s_mem());
    X509_print_ex(mem, certificate, XN_FLAG_SEP_CPLUS_SPC, X509_FLAG_NO_HEADER);
    BIO_write(mem, "\0", 1);
    char* buffer;
    BIO_get_mem_data(mem, &buffer);
    LOG(LS_INFO) << buffer;
    BIO_free(mem);

    char* cipher_description =
      SSL_CIPHER_description(SSL_get_current_cipher(ssl), NULL, 128);
    LOG(LS_INFO) << "Cipher: " << cipher_description;
    OPENSSL_free(cipher_description);
  }
#endif

  bool ok = false;
  int extension_count = X509_get_ext_count(certificate);
  for (int i = 0; i < extension_count; ++i) {
    X509_EXTENSION* extension = X509_get_ext(certificate, i);
    int extension_nid = OBJ_obj2nid(X509_EXTENSION_get_object(extension));

    if (extension_nid == NID_subject_alt_name) {
      const X509V3_EXT_METHOD* meth = X509V3_EXT_get(extension);
      if (!meth)
        break;

      void* ext_str = NULL;

      // We assign this to a local variable, instead of passing the address
      // directly to ASN1_item_d2i.
      // See http://readlist.com/lists/openssl.org/openssl-users/0/4761.html.
      unsigned char* ext_value_data = extension->value->data;

      const unsigned char **ext_value_data_ptr =
          (const_cast<const unsigned char **>(&ext_value_data));

      if (meth->it) {
        ext_str = ASN1_item_d2i(NULL, ext_value_data_ptr,
                                extension->value->length,
                                ASN1_ITEM_ptr(meth->it));
      } else {
        ext_str = meth->d2i(NULL, ext_value_data_ptr, extension->value->length);
      }

      STACK_OF(CONF_VALUE)* value = meth->i2v(meth, ext_str, NULL);
      for (int j = 0; j < sk_CONF_VALUE_num(value); ++j) {
        CONF_VALUE* nval = sk_CONF_VALUE_value(value, j);
        // The value for nval can contain wildcards
        if (!strcmp(nval->name, "DNS") && talk_base::string_match(host, nval->value)) {
          ok = true;
          break;
        }
      }
      sk_CONF_VALUE_pop_free(value, X509V3_conf_free);
      value = NULL;

      if (meth->it) {
        ASN1_item_free(reinterpret_cast<ASN1_VALUE*>(ext_str),
                       ASN1_ITEM_ptr(meth->it));
      } else {
        meth->ext_free(ext_str);
      }
      ext_str = NULL;
    }
    if (ok)
      break;
  }

  char data[256];
  X509_name_st* subject;
  if (!ok
      && ((subject = X509_get_subject_name(certificate)) != NULL)
      && (X509_NAME_get_text_by_NID(subject, NID_commonName,
                                    data, sizeof(data)) > 0)) {
    data[sizeof(data)-1] = 0;
    if (_stricmp(data, host) == 0)
      ok = true;
  }

  X509_free(certificate);

  // This should only ever be turned on for debugging and development.
  if (!ok && ignore_bad_cert) {
    LOG(LS_WARNING) << "TLS certificate check FAILED.  "
      << "Allowing connection anyway.";
    ok = true;
  }

  return ok;
}

bool OpenSSLAdapter::SSLPostConnectionCheck(SSL* ssl, const char* host) {
  bool ok = VerifyServerName(ssl, host, ignore_bad_cert());

  if (ok) {
    ok = (SSL_get_verify_result(ssl) == X509_V_OK ||
          custom_verification_succeeded_);
  }

  if (!ok && ignore_bad_cert()) {
    LOG(LS_INFO) << "Other TLS post connection checks failed.";
    ok = true;
  }

  return ok;
}

#if _DEBUG

// We only use this for tracing and so it is only needed in debug mode

void
OpenSSLAdapter::SSLInfoCallback(const SSL* s, int where, int ret) {
  const char* str = "undefined";
  int w = where & ~SSL_ST_MASK;
  if (w & SSL_ST_CONNECT) {
    str = "SSL_connect";
  } else if (w & SSL_ST_ACCEPT) {
    str = "SSL_accept";
  }
  if (where & SSL_CB_LOOP) {
    LOG(LS_INFO) <<  str << ":" << SSL_state_string_long(s);
  } else if (where & SSL_CB_ALERT) {
    str = (where & SSL_CB_READ) ? "read" : "write";
    LOG(LS_INFO) <<  "SSL3 alert " << str
      << ":" << SSL_alert_type_string_long(ret)
      << ":" << SSL_alert_desc_string_long(ret);
  } else if (where & SSL_CB_EXIT) {
    if (ret == 0) {
      LOG(LS_INFO) << str << ":failed in " << SSL_state_string_long(s);
    } else if (ret < 0) {
      LOG(LS_INFO) << str << ":error in " << SSL_state_string_long(s);
    }
  }
}

#endif  // _DEBUG

int
OpenSSLAdapter::SSLVerifyCallback(int ok, X509_STORE_CTX* store) {
#if _DEBUG
  if (!ok) {
    char data[256];
    X509* cert = X509_STORE_CTX_get_current_cert(store);
    int depth = X509_STORE_CTX_get_error_depth(store);
    int err = X509_STORE_CTX_get_error(store);

    LOG(LS_INFO) << "Error with certificate at depth: " << depth;
    X509_NAME_oneline(X509_get_issuer_name(cert), data, sizeof(data));
    LOG(LS_INFO) << "  issuer  = " << data;
    X509_NAME_oneline(X509_get_subject_name(cert), data, sizeof(data));
    LOG(LS_INFO) << "  subject = " << data;
    LOG(LS_INFO) << "  err     = " << err
      << ":" << X509_verify_cert_error_string(err);
  }
#endif

  // Get our stream pointer from the store
  SSL* ssl = reinterpret_cast<SSL*>(
                X509_STORE_CTX_get_ex_data(store,
                  SSL_get_ex_data_X509_STORE_CTX_idx()));

  OpenSSLAdapter* stream =
    reinterpret_cast<OpenSSLAdapter*>(SSL_get_app_data(ssl));

  if (!ok && custom_verify_callback_) {
    void* cert =
        reinterpret_cast<void*>(X509_STORE_CTX_get_current_cert(store));
    if (custom_verify_callback_(cert)) {
      stream->custom_verification_succeeded_ = true;
      LOG(LS_INFO) << "validated certificate using custom callback";
      ok = true;
    }
  }

  // Should only be used for debugging and development.
  if (!ok && stream->ignore_bad_cert()) {
    LOG(LS_WARNING) << "Ignoring cert error while verifying cert chain";
    ok = 1;
  }

  return ok;
}

bool OpenSSLAdapter::ConfigureTrustedRootCertificates(SSL_CTX* ctx) {
  // Add the root cert that we care about to the SSL context
  int count_of_added_certs = 0;
  for (int i = 0; i < ARRAY_SIZE(tincan::kSSLCertCertificateList); i++) {
    const unsigned char* cert_buffer = tincan::kSSLCertCertificateList[i];
    size_t cert_buffer_len = tincan::kSSLCertCertificateSizeList[i];
    X509* cert = d2i_X509(NULL, &cert_buffer, cert_buffer_len);
    if (cert) {
      int return_value = X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx), cert);
      if (return_value == 0) {
        LOG(LS_WARNING) << "Unable to add certificate.";
      } else {
        count_of_added_certs++;
      }
      X509_free(cert);
    }
  }
  return count_of_added_certs > 0;
}

SSL_CTX*
OpenSSLAdapter::SetupSSLContext() {
  SSL_CTX* ctx = SSL_CTX_new(TLSv1_client_method());
  if (ctx == NULL) {
    unsigned long error = ERR_get_error();  // NOLINT: type used by OpenSSL.
    LOG(LS_WARNING) << "SSL_CTX creation failed: "
                    << '"' << ERR_reason_error_string(error) << "\" "
                    << "(error=" << error << ')';
    return NULL;
  }
  if (!ConfigureTrustedRootCertificates(ctx)) {
    SSL_CTX_free(ctx);
    return NULL;
  }

#ifdef _DEBUG
  SSL_CTX_set_info_callback(ctx, SSLInfoCallback);
#endif

  SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, SSLVerifyCallback);
  SSL_CTX_set_verify_depth(ctx, 4);
  SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");

  return ctx;
}

void
OpenSSLAdapter::OpenSSLAdapter::SetupSSLContextIdentity(void* identity) {

  SSL_CTX_use_certificate(ssl_ctx_, (static_cast<tincan::OpenSSLIdentity*>(identity))->certificate().x509());
  SSL_CTX_use_PrivateKey(ssl_ctx_, (static_cast<tincan::OpenSSLIdentity*>(identity))->key_pair().pkey());
}

} // namespace tincan

#endif  // HAVE_OPENSSL_SSL_H


text:
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="AsyncBehaviorRuleBase.cs" company="Kephas Software SRL">
//   Copyright (c) Kephas Software SRL. All rights reserved.
//   Licensed under the MIT license. See LICENSE file in the project root for full license information.
// </copyright>
// <summary>
//   Base class for asynchronous behavior rules.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Kephas.Behaviors
{
    using System.Threading;
    using System.Threading.Tasks;

    using Kephas.Logging;

    /// <summary>
    /// Base class for asynchronous behavior rules.
    /// </summary>
    /// <typeparam name="TContext">Type of the context.</typeparam>
    /// <typeparam name="TValue">Type of the value.</typeparam>
    public abstract class AsyncBehaviorRuleBase<TContext, TValue> : BehaviorRuleFlowControlBase, IAsyncBehaviorRule<TContext, TValue>
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="AsyncBehaviorRuleBase{TContext, TValue}"/> class.
        /// </summary>
        /// <param name="logManager">Optional. The log manager.</param>
        protected AsyncBehaviorRuleBase(ILogManager? logManager = null)
            : base(logManager)
        {
        }

        /// <summary>
        /// Gets a value asynchronously indicating whether the rule may be applied or not.
        /// </summary>
        /// <param name="context">          The context.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>
        /// A promise of a value indicating whether the rule may be applied or not.
        /// </returns>
        public virtual Task<bool> CanApplyAsync(TContext context, CancellationToken cancellationToken = default)
        {
            return Task.FromResult(true);
        }

        /// <summary>
        /// Gets the behavior value asynchronously.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>
        /// A promise of the behavior value.
        /// </returns>
        Task<IBehaviorValue> IAsyncBehaviorRule<TContext>.GetValueAsync(TContext context, CancellationToken cancellationToken)
        {
            // do not use await, to be able to use it both on the client and the server.
            return this.GetValueAsync(context, cancellationToken).ContinueWith(t => (IBehaviorValue)t.Result, cancellationToken);
        }

        /// <summary>
        /// Gets the behavior value asynchronously.
        /// </summary>
        /// <param name="context">          The context.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>
        /// A promise of the behavior value.
        /// </returns>
        public abstract Task<IBehaviorValue<TValue>> GetValueAsync(TContext context, CancellationToken cancellationToken = default);
    }
}

redpajama_set_name: RedPajamaGithub


text:
module CookbooksHelper
end


text:
.control
{
  composes: selector from './button.css';
  composes: normal from './button.css';
  composes: l from './button-size.css';
}


text:
from builtins import range
import json
import random
import time
import itertools
from ethereum.utils import (
    parse_as_bin,
    big_endian_to_int,
    to_string,
)
from ethereum.hybrid_casper import casper_utils
from ethereum.meta import apply_block
from ethereum.common import update_block_env_variables
from ethereum.tools import tester
import rlp
from rlp.utils import encode_hex
from ethereum.exceptions import InvalidTransaction, VerificationFailed
from ethereum.slogging import get_logger
from ethereum.config import Env
from ethereum.state import State, dict_to_prev_header
from ethereum.block import Block, BlockHeader, BLANK_UNCLES_HASH
from ethereum.pow.consensus import initialize
from ethereum.genesis_helpers import mk_basic_state, state_from_genesis_declaration, initialize_genesis_keys

log = get_logger('eth.chain')
config_string = ':info,eth.chain:debug'
# from ethereum.slogging import configure_logging
# config_string = ':info,eth.vm.log:trace,eth.vm.op:trace,eth.vm.stack:trace,eth.vm.exit:trace,eth.pb.msg:trace,eth.pb.tx:debug'
# configure_logging(config_string=config_string)

class Chain(object):

    def __init__(self, genesis=None, env=None, coinbase=b'\x00' * 20,
                 new_head_cb=None, reset_genesis=False, localtime=None, **kwargs):
        self.env = env or Env()
        # Initialize the state
        if b'head_hash' in self.db:  # new head tag
            self.state = self.mk_poststate_of_blockhash(self.db.get(b'head_hash'))
            print('Initializing chain from saved head, #%d (%s)' %
                  (self.state.prev_headers[0].number, encode_hex(self.state.prev_headers[0].hash)))
        elif genesis is None:
            raise Exception("Need genesis decl!")
        elif isinstance(genesis, State):
            assert env is None or env == genesis.env
            self.state = genesis
            self.env = self.state.env
            print('Initializing chain from provided state')
            reset_genesis = True
        elif "extraData" in genesis:
            self.state = state_from_genesis_declaration(
                genesis, self.env)
            reset_genesis = True
            print('Initializing chain from provided genesis declaration')
        elif "prev_headers" in genesis:
            self.state = State.from_snapshot(genesis, self.env)
            reset_genesis = True
            print('Initializing chain from provided state snapshot, %d (%s)' %
                  (self.state.block_number, encode_hex(self.state.prev_headers[0].hash[:8])))
        else:
            print('Initializing chain from new state based on alloc')
            self.state = mk_basic_state(genesis, {
                "number": kwargs.get('number', 0),
                "gas_limit": kwargs.get('gas_limit', 4712388),
                "gas_used": kwargs.get('gas_used', 0),
                "timestamp": kwargs.get('timestamp', 1467446877),
                "difficulty": kwargs.get('difficulty', 2**25),
                "hash": kwargs.get('prevhash', '00' * 32),
                "uncles_hash": kwargs.get('uncles_hash', '0x' + encode_hex(BLANK_UNCLES_HASH))
            }, self.env)
            reset_genesis = True

        assert self.env.db == self.state.db

        initialize(self.state)
        self.new_head_cb = new_head_cb

        self.head_hash = self.state.prev_headers[0].hash
        self.checkpoint_head_score = 0
        self.casper_address = self.config['CASPER_ADDRESS']
        log.info('Casper address: 0x'+encode_hex(self.casper_address))
        assert self.state.block_number == self.state.prev_headers[0].number
        if reset_genesis:
            self.genesis = Block(self.state.prev_headers[0], [], [])
            initialize_genesis_keys(self.state, self.genesis)
        else:
            self.genesis = self.get_block_by_number(0)
        self.min_gasprice = kwargs.get('min_gasprice', 5 * 10**9)
        self.coinbase = coinbase
        self.extra_data = 'moo ha ha says the laughing cow.'
        self.time_queue = []
        self.parent_queue = {}
        self.localtime = time.time() if localtime is None else localtime

    @property
    def head(self):
        try:
            block_rlp = self.db.get(self.head_hash)
            if block_rlp == b'GENESIS':
                return self.genesis
            else:
                return rlp.decode(block_rlp, Block)
        except Exception as e:
            log.error(e)
            return None

    # ~~~~~~~~~~~~~~~~~~~~ ADD BLOCK ~~~~~~~~~~~~~~~~~~~~ #

    # This function should be called periodically so as to
    # process blocks that were received but laid aside because
    # they were received too early
    def process_time_queue(self, new_time=None):
        self.localtime = time.time() if new_time is None else new_time
        i = 0
        while i < len(self.time_queue) and self.time_queue[i].timestamp <= self.localtime:
            log.info('Adding scheduled block')
            pre_len = len(self.time_queue)
            self.add_block(self.time_queue.pop(i))
            if len(self.time_queue) == pre_len:
                i += 1

    def should_add_block(self, block):
        # Check that the block wasn't recieved too early
        now = self.localtime
        if block.header.timestamp > now:
            i = 0
            while i < len(self.time_queue) and block.timestamp > self.time_queue[i].timestamp:
                i += 1
            self.time_queue.insert(i, block)
            log.info('Block received too early (%d vs %d). Delaying for %d seconds' %
                     (now, block.header.timestamp, block.header.timestamp - now))
            return False
        # Check that the block's parent has already been added
        if block.header.prevhash not in self.env.db:
            if block.header.prevhash not in self.parent_queue:
                self.parent_queue[block.header.prevhash] = []
            self.parent_queue[block.header.prevhash].append(block)
            log.info('Got block %d (%s) with prevhash %s, parent not found. Delaying for now' %
                     (block.number, encode_hex(block.hash), encode_hex(block.prevhash)))
            return False
        # Check that the block doesn't throw an exception
        if block.header.prevhash == self.head_hash:
            temp_state = self.state.ephemeral_clone()
        else:
            temp_state = self.mk_poststate_of_blockhash(block.header.prevhash)
        try:
            apply_block(temp_state, block)
        except (AssertionError, KeyError, ValueError, InvalidTransaction, VerificationFailed) as e:  # FIXME add relevant exceptions here
            log.info('Block %s with parent %s invalid, reason: %s' % (encode_hex(block.header.hash), encode_hex(block.header.prevhash), e))
            return False
        return True

    def add_block_to_head(self, block):
        log.info('Adding to head', head=encode_hex(block.header.prevhash))
        apply_block(self.state, block)
        self.db.put(b'block:' + to_string(block.header.number), block.header.hash)
        self.get_pow_difficulty(block)  # side effect: put 'score:' cache in db
        self.head_hash = block.header.hash
        for i, tx in enumerate(block.transactions):
            self.db.put(b'txindex:' + tx.hash, rlp.encode([block.number, i]))

    def set_head(self, block):
        # ~~~ PoW Fork Choice ~~~~ #
        # If block is directly on top of the head, immediately make it our head
        if block.header.prevhash == self.head_hash:
            self.add_block_to_head(block)
        else:  # Otherwise, check if we should change our head
            # Here we should run `is_fork_heavier_than_head` but modify it so it works for both PoW and Casper... ODEE great
            log.info('Receiving block not on head, adding to secondary post state',
                     prevhash=encode_hex(block.header.prevhash))
            self.reorganize_head_to(block)
        self.db.put(b'head_hash', self.head_hash)
        self.db.commit()
        log.info('Reorganizing chain to block %d (%s) with %d txs and %d gas' %
                 (block.header.number, encode_hex(block.header.hash)[:8],
                  len(block.transactions), block.header.gas_used))
        if self.new_head_cb and block.header.number != 0:
            self.new_head_cb(block)
        return True

    # Call upon receiving a block
    def add_block(self, block):
        # ~~~ Validate ~~~~ #
        # Validate that the block should be added
        if not self.should_add_block(block):
            return False
        # ~~~ Store ~~~~ #
        # Store the block
        self.db.put(block.header.hash, rlp.encode(block))
        self.add_child(block)
        # Store the state root
        if block.header.prevhash == self.head_hash:
            temp_state = self.state.ephemeral_clone()
        else:
            temp_state = self.mk_poststate_of_blockhash(block.header.prevhash)
        apply_block(temp_state, block)
        self.db.put(b'state:' + block.header.hash, temp_state.trie.root_hash)
        # Check the last finalized checkpoint and store
        # ~~~ Add block ~~~~ #
        if self.get_score(self.state, self.head) < self.get_score(temp_state, block) and not self.switch_reverts_finalized_block(self.head, block):
            self.set_head(block)
            log.info('Changed head to: {}'.format(block.number))
            casper = tester.ABIContract(tester.State(temp_state), casper_utils.casper_abi, self.config['CASPER_ADDRESS'])
            if casper.get_last_finalized_epoch() == casper.get_current_epoch() - 1:
                h = casper.get_checkpoint_hashes(casper.get_last_finalized_epoch())
                if h != b'\x00' * 32:
                    hist_casper = tester.ABIContract(tester.State(self.mk_poststate_of_blockhash(h)), casper_utils.casper_abi, self.config['CASPER_ADDRESS'])
                    if hist_casper.get_total_curdyn_deposits() > self.config['NON_REVERT_MIN_DEPOSIT'] and \
                            hist_casper.get_total_prevdyn_deposits() > self.config['NON_REVERT_MIN_DEPOSIT']:
                        self.db.put(b'finalized:'+h, b'true')
                        log.info('Finalized checkpoint {} {}'.format(casper.get_last_finalized_epoch(), encode_hex(h)[:8]))
                    else:
                        log.info('Trivially finalized checkpoint {}'.format(casper.get_last_finalized_epoch()))
        else:
            log.info('Skipping block {} which is not a descendant of current head checkpoint'.format(block.number))
        # Are there blocks that we received that were waiting for this block?
        # If so, process them.
        if block.header.hash in self.parent_queue:
            for _blk in self.parent_queue[block.header.hash]:
                self.add_block(_blk)
            del self.parent_queue[block.header.hash]
        return True

    def get_score(self, prestate, block):
        casper = tester.ABIContract(tester.State(prestate), casper_utils.casper_abi, self.config['CASPER_ADDRESS'])
        return casper.get_last_justified_epoch() * 10**40 + self.get_pow_difficulty(block)

    def switch_reverts_finalized_block(self, old_head, new_head):
        while old_head.number > new_head.number:
            if b'finalized:'+old_head.hash in self.db:
                log.info('[WARNING] Attempt to revert failed: checkpoint {} is finalized'.format(encode_hex(old_head.hash)))
                return True
            old_head = self.get_parent(old_head)
        while new_head.number > old_head.number:
            new_head = self.get_parent(new_head)
            if new_head is None:
                log.info('Revert: new_head is None')
                return False
        while new_head.hash != old_head.hash:
            if b'finalized:'+old_head.hash in self.db:
                log.info('[WARNING] Attempt to revert failed; checkpoint {} is finalized'.format(encode_hex(old_head.hash)))
                return True
            old_head = self.get_parent(old_head)
            new_head = self.get_parent(new_head)
            if new_head is None or old_head is None:
                log.info('Revert: new_head or old_head is None')
                return False
        return False

    def reorganize_head_to(self, block):
        log.info('Replacing head')
        b = block
        new_chain = {}
        while b and b.header.number >= int(self.db.get(b'GENESIS_NUMBER')):
            new_chain[b.header.number] = b
            key = b'block:' + to_string(b.header.number)
            orig_at_height = self.db.get(key) if key in self.db else None
            if orig_at_height == b.header.hash:
                break
            if b.prevhash not in self.db or self.db.get(b.prevhash) == b'GENESIS':
                break
            b = self.get_parent(b)
        replace_from = b.header.number if b else (int(self.db.get(b'GENESIS_NUMBER')) + 1)
        for i in itertools.count(replace_from):
            log.info('Rewriting height %d' % i)
            key = b'block:' + to_string(i)
            orig_at_height = self.db.get(key) if key in self.db else None
            if orig_at_height:
                self.db.delete(key)
                orig_block_at_height = self.get_block(orig_at_height)
                for tx in orig_block_at_height.transactions:
                    if b'txindex:' + tx.hash in self.db:
                        self.db.delete(b'txindex:' + tx.hash)
            if i in new_chain:
                new_block_at_height = new_chain[i]
                self.db.put(key, new_block_at_height.header.hash)
                for i, tx in enumerate(new_block_at_height.transactions):
                    self.db.put(b'txindex:' + tx.hash,
                                rlp.encode([new_block_at_height.number, i]))
            if i not in new_chain and not orig_at_height:
                break
        self.head_hash = block.header.hash
        self.state = self.mk_poststate_of_blockhash(block.hash)

    def find_heaviest_pow_block(self, root):
        children = self.get_children(root)
        maxchild, maxscore = root, self.get_pow_difficulty(root)
        for c in children:
            maxc, s = self.find_heaviest_pow_block(c)
            if s > maxscore:
                maxchild, maxscore = maxc, s
        return maxchild, maxscore

    # ~~~~~~~~~~~~~~~~~~~~ CASPER UTILS ~~~~~~~~~~~~~~~~~~~~ #

    def is_child_checkpoint(self, child, parent):
        if parent == b'\x00' * 32:
            # If the parent checkpoint is the genesis checkpoint, then the child must be a decedent
            return True
        parent_block = self.get_block(parent)
        child_block = self.get_block(child)
        while parent_block.number < child_block.number:
            child_block = self.get_block(child_block.prevhash)
        if parent_block == child_block:
            return True
        else:
            return False

    # ~~~~~~~~~~~~~~~~~~~~ BLOCK UTILS ~~~~~~~~~~~~~~~~~~~~ #

    def mk_poststate_of_blockhash(self, blockhash, convert=False):
        if blockhash not in self.db:
            raise Exception("Block hash %s not found" % encode_hex(blockhash))

        block_rlp = self.db.get(blockhash)
        if block_rlp == b'GENESIS':
            return State.from_snapshot(json.loads(self.db.get(b'GENESIS_STATE')), self.env)
        block = rlp.decode(block_rlp, Block)

        state = State(env=self.env)
        state.trie.root_hash = block.header.state_root if convert else self.db.get(b'state:'+blockhash)
        update_block_env_variables(state, block)
        state.gas_used = block.header.gas_used
        state.txindex = len(block.transactions)
        state.recent_uncles = {}
        state.prev_headers = []
        b = block
        header_depth = state.config['PREV_HEADER_DEPTH']
        for i in range(header_depth + 1):
            state.prev_headers.append(b.header)
            if i < 6:
                state.recent_uncles[state.block_number - i] = []
                for u in b.uncles:
                    state.recent_uncles[state.block_number - i].append(u.hash)
            try:
                b = rlp.decode(state.db.get(b.header.prevhash), Block)
            except:
                break
        if i < header_depth:
            if state.db.get(b.header.prevhash) == b'GENESIS':
                jsondata = json.loads(state.db.get(b'GENESIS_STATE'))
                for h in jsondata["prev_headers"][:header_depth - i]:
                    state.prev_headers.append(dict_to_prev_header(h))
                for blknum, uncles in jsondata["recent_uncles"].items():
                    if int(blknum) >= state.block_number - int(state.config['MAX_UNCLE_DEPTH']):
                        state.recent_uncles[blknum] = [parse_as_bin(u) for u in uncles]
            else:
                raise Exception("Dangling prevhash")
        assert len(state.journal) == 0, state.journal
        return state

    def get_parent(self, block):
        if block.header.number == int(self.db.get(b'GENESIS_NUMBER')):
            return None
        return self.get_block(block.header.prevhash)

    def get_block(self, blockhash):
        try:
            block_rlp = self.db.get(blockhash)
            if block_rlp == b'GENESIS':
                if not hasattr(self, 'genesis'):
                    self.genesis = rlp.decode(self.db.get(b'GENESIS_RLP'), sedes=Block)
                return self.genesis
            else:
                return rlp.decode(block_rlp, Block)
        except Exception as e:
            log.debug("Failed to get block", hash=blockhash, error=e)
            return None

    # Add a record allowing you to later look up the provided block's
    # parent hash and see that it is one of its children
    def add_child(self, child):
        try:
            existing = self.db.get(b'child:' + child.header.prevhash)
        except:
            existing = b''
        existing_hashes = []
        for i in range(0, len(existing), 32):
            existing_hashes.append(existing[i: i+32])
        if child.header.hash not in existing_hashes:
            self.db.put(b'child:' + child.header.prevhash, existing + child.header.hash)

    def get_blockhash_by_number(self, number):
        try:
            return self.db.get(b'block:' + to_string(number))
        except:
            return None

    def get_block_by_number(self, number):
        return self.get_block(self.get_blockhash_by_number(number))

    # Get the hashes of all known children of a given block
    def get_child_hashes(self, blockhash):
        o = []
        try:
            data = self.db.get(b'child:' + blockhash)
            for i in range(0, len(data), 32):
                o.append(data[i:i + 32])
            return o
        except:
            return []

    def get_children(self, block):
        if isinstance(block, Block):
            block = block.header.hash
        if isinstance(block, BlockHeader):
            block = block.hash
        return [self.get_block(h) for h in self.get_child_hashes(block)]

    # Get the score (AKA total difficulty in PoW) of a given block
    def get_pow_difficulty(self, block):
        if not block:
            return 0
        key = b'score:' + block.header.hash
        fills = []
        while key not in self.db:
            fills.insert(0, (block.header.hash, block.difficulty))
            key = b'score:' + block.header.prevhash
            block = self.get_parent(block)
            if block is None:
                return 0
        score = int(self.db.get(key))
        for h, d in fills:
            key = b'score:' + h
            score = score + d + random.randrange(d // 10**6 + 1)
            self.db.put(key, str(score))
        return score

    def has_block(self, block):
        return block in self

    def has_blockhash(self, blockhash):
        return blockhash in self.db

    def get_chain(self, frm=None, to=2**63 - 1):
        if frm is None:
            frm = int(self.db.get(b'GENESIS_NUMBER')) + 1
        chain = []
        for i in itertools.islice(itertools.count(), frm, to):
            h = self.get_blockhash_by_number(i)
            if not h:
                return chain
            chain.append(self.get_block(h))

    # Recover transaction and the block that contains it
    def get_transaction(self, tx):
        if not isinstance(tx, (str, bytes)):
            tx = tx.hash
        if b'txindex:' + tx in self.db:
            data = rlp.decode(self.db.get(b'txindex:' + tx))
            blk, index = self.get_block_by_number(
                big_endian_to_int(data[0])), big_endian_to_int(data[1])
            tx = blk.transactions[index]
            return tx, blk, index
        else:
            return None

    def get_descendants(self, block):
        output = []
        blocks = [block]
        while len(blocks):
            b = blocks.pop()
            blocks.extend(self.get_children(b))
            output.append(b)
        return output

    # Get blockhashes starting from a hash and going backwards
    def get_blockhashes_from_hash(self, hash, max):
        block = self.get_block(hash)
        if block is None:
            return []

        header = block.header
        hashes = []
        for i in range(max):
            hash = header.prevhash
            block = self.get_block(hash)
            if block is None:
                break
            header = block.header
            hashes.append(header.hash)
            if header.number == 0:
                break
        return hashes

    def __contains__(self, blk):
        if isinstance(blk, (str, bytes)):
            try:
                blk = rlp.decode(self.db.get(blk), Block)
            except:
                return False
        try:
            o = self.get_block(self.get_blockhash_by_number(blk.number)).hash
            assert o == blk.hash
            return True
        except:
            return False

    @property
    def config(self):
        return self.env.config

    @property
    def db(self):
        return self.env.db


text:
<?php

namespace Pimcore\Tool;

use Pimcore\Config;

class Console {
	/**
	 * @var string system environment
	 */
	private static $systemEnvironment;

    /**
     * @static
     * @return string "windows" or "unix"
     */
    public static function getSystemEnvironment(){
		if (self::$systemEnvironment == null) {
			if(stripos(php_uname("s"), "windows") !== false) {
				self::$systemEnvironment = 'windows';
			}else{
				self::$systemEnvironment = 'unix';
			}
		}
		return self::$systemEnvironment;
    }

    /**
     * @return mixed
     * @throws \Exception
     */
    public static function getPhpCli () {

        if(Config::getSystemConfig()->general->php_cli) {
            if(@is_executable(Config::getSystemConfig()->general->php_cli)) {
                return (string) Config::getSystemConfig()->general->php_cli;
            } else {
                \Logger::critical("PHP-CLI binary: " . Config::getSystemConfig()->general->php_cli . " is not executable");
            }
        }

        $paths = array(
            "/usr/bin/php",
            "/usr/local/bin/php",
            "/usr/local/zend/bin/php",
            "/bin/php",
            realpath(PIMCORE_DOCUMENT_ROOT . "/../php/php.exe") // for windows sample package (XAMPP)
        );

        foreach ($paths as $path) {
            if(@is_executable($path)) {
                return $path;
            }
        }

        throw new \Exception("No php executable found, please configure the correct path in the system settings");
    }

    public static function getTimeoutBinary () {
        $paths = array("/usr/bin/timeout","/usr/local/bin/timeout","/bin/timeout");

        foreach ($paths as $path) {
            if(@is_executable($path)) {
                return $path;
            }
        }

        return false;
    }

    /**
     * @param $cmd
     * @param null $outputFile
     * @param null $timeout
     * @return string
     */
    public static function exec ($cmd, $outputFile = null, $timeout = null) {

        if($timeout && self::getTimeoutBinary()) {

            // check if --kill-after flag is supported in timeout
            $killafter = "";
            $out = self::exec(self::getTimeoutBinary() . " --help");
            if(strpos($out, "--kill-after")) {
                $killafter = " -k 1m";
            }

            $cmd = self::getTimeoutBinary() . $killafter . " " . $timeout . "s " . $cmd;
        } else if($timeout) {
            \Logger::warn("timeout binary not found, executing command without timeout");
        }

        if($outputFile) {
            $cmd = $cmd . " > ". $outputFile ." 2>&1";
        } else {
            // send stderr to /dev/null otherwise this goes to the apache error log and can fill it up pretty quickly
            if(self::getSystemEnvironment() != 'windows') {
                $cmd .= " 2> /dev/null";
            }
        }

        \Logger::debug("Executing command `" . $cmd . "` on the current shell");
        $return = shell_exec($cmd);

        return $return;
    }

    /**
     * @static
     * @param string $cmd
     * @param null|string $outputFile
     * @return int
     */
    public static function execInBackground($cmd, $outputFile = null) {

        // windows systems
        if(self::getSystemEnvironment() == 'windows') {
            return self::execInBackgroundWindows($cmd, $outputFile);
        } else {
            return self::execInBackgroundUnix($cmd, $outputFile);
        }
    }

    /**
     * @static
     * @param string $cmd
     * @param string $outputFile
     * @return int
     */
    protected static function execInBackgroundUnix ($cmd, $outputFile) {

        if(!$outputFile) {
            $outputFile = "/dev/null";
        }

        $nice = "";
        if(@is_executable("/usr/bin/nice")) {
            $nice = "/usr/bin/nice -n 19 ";
        }

        $commandWrapped = "/usr/bin/nohup " . $nice . $cmd . " > ". $outputFile ." 2>&1 & echo $!";
        \Logger::debug("Executing command `" . $commandWrapped . "´ on the current shell in background");
        $pid = shell_exec($commandWrapped);

        \Logger::debug("Process started with PID " . $pid);

        return $pid;
    }

    /**
     * @static
     * @param string $cmd
     * @param string $outputFile
     * @return int
     */
    protected static function execInBackgroundWindows($cmd, $outputFile) {

        if(!$outputFile) {
            $outputFile = "NUL";
        }

        $commandWrapped = "cmd /c " . $cmd . " > ". $outputFile . " 2>&1";
        \Logger::debug("Executing command `" . $commandWrapped . "´ on the current shell in background");

        $WshShell = new \COM("WScript.Shell");
        $WshShell->Run($commandWrapped, 0, false);
        \Logger::debug("Process started - returning the PID is not supported on Windows Systems");

        return 0;
    }

    /**
     * Returns a hash with all options passed to a cli script
     *
     * @return array
     */
    public static function getOptions($onlyFullNotationArgs = false){
        GLOBAL $argv;
        $options = array();
        $tmpOptions = $argv;
        array_shift($tmpOptions);

        foreach($tmpOptions as $optionString){
            if($onlyFullNotationArgs && substr($optionString,0,2) != '--'){
                continue;
            }
            $exploded = explode("=",$optionString,2);
            $options[str_replace('-','',$exploded[0])] =  $exploded[1];
        }

        return $options;
    }

    /**
     * @param $options
     * @param string $concatenator
     * @param string $arrayConcatenator
     * @return string
     */
    public static function getOptionString($options,$concatenator = '=',$arrayConcatenator = ','){
        $string = '';

        foreach($options as $key => $value){
            $string .= '--' . $key;
            if($value){
                if(is_array($value)){
                    $value = implode($arrayConcatenator,$value);
                }
                $string .= $concatenator . "'" . $value . "'";
            }
            $string .= ' ';
        }

        return $string;
    }

    /**
     * @param array $allowedUsers
     * @throws \Exception
     */
    public static function checkExecutingUser($allowedUsers = array()){
        $owner = fileowner(PIMCORE_CONFIGURATION_SYSTEM);
        if($owner == false){
            throw new \Exception("Couldn't get user from file " . PIMCORE_CONFIGURATION_SYSTEM);
        }
        $userData = posix_getpwuid($owner);
        $allowedUsers[] = $userData['name'];

        $scriptExecutingUserData = posix_getpwuid(posix_geteuid());
        $scriptExecutingUser = $scriptExecutingUserData['name'];

        if(!in_array($scriptExecutingUser,$allowedUsers)){
            throw new \Exception("The current system user is not allowed to execute this script. Allowed users: '" . implode(',',$allowedUsers) ."' Executing user: '$scriptExecutingUser'.");
        }
    }

    /**
     * @throws \Exception
     */
    public static function checkCliExecution() {
        if (php_sapi_name() != 'cli') {
            throw new \Exception("Script execution is restricted to CLI");
        }
    }

}


text:
namespace System.Net.Http
{
    public partial class ByteArrayContent : System.Net.Http.HttpContent
    {
        public ByteArrayContent(byte[] content) { }
        public ByteArrayContent(byte[] content, int offset, int count) { }
        protected override System.Threading.Tasks.Task<System.IO.Stream> CreateContentReadStreamAsync() { throw null; }
        protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context) { throw null; }
        protected internal override bool TryComputeLength(out long length) { length = default(long); throw null; }
    }
    public enum ClientCertificateOption
    {
        Automatic = 1,
        Manual = 0,
    }
    public abstract partial class DelegatingHandler : System.Net.Http.HttpMessageHandler
    {
        protected DelegatingHandler() { }
        protected DelegatingHandler(System.Net.Http.HttpMessageHandler innerHandler) { }
        public System.Net.Http.HttpMessageHandler InnerHandler { get { throw null; } set { } }
        protected override void Dispose(bool disposing) { }
        protected internal override System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { throw null; }
    }
    public partial class FormUrlEncodedContent : System.Net.Http.ByteArrayContent
    {
        public FormUrlEncodedContent(System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, string>> nameValueCollection) : base (default(byte[])) { }
    }
    public partial class HttpClient : System.Net.Http.HttpMessageInvoker
    {
        public HttpClient() : base (default(System.Net.Http.HttpMessageHandler)) { }
        public HttpClient(System.Net.Http.HttpMessageHandler handler) : base (default(System.Net.Http.HttpMessageHandler)) { }
        public HttpClient(System.Net.Http.HttpMessageHandler handler, bool disposeHandler) : base (default(System.Net.Http.HttpMessageHandler)) { }
        public System.Uri BaseAddress { get { throw null; } set { } }
        public System.Net.Http.Headers.HttpRequestHeaders DefaultRequestHeaders { get { throw null; } }
        public long MaxResponseContentBufferSize { get { throw null; } set { } }
        public System.TimeSpan Timeout { get { throw null; } set { } }
        public void CancelPendingRequests() { }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> DeleteAsync(string requestUri) { throw null; }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> DeleteAsync(string requestUri, System.Threading.CancellationToken cancellationToken) { throw null; }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> DeleteAsync(System.Uri requestUri) { throw null; }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> DeleteAsync(System.Uri requestUri, System.Threading.CancellationToken cancellationToken) { throw null; }
        protected override void Dispose(bool disposing) { }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> GetAsync(string requestUri) { throw null; }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> GetAsync(string requestUri, System.Net.Http.HttpCompletionOption completionOption) { throw null; }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> GetAsync(string requestUri, System.Net.Http.HttpCompletionOption completionOption, System.Threading.CancellationToken cancellationToken) { throw null; }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> GetAsync(string requestUri, System.Threading.CancellationToken cancellationToken) { throw null; }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> GetAsync(System.Uri requestUri) { throw null; }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> GetAsync(System.Uri requestUri, System.Net.Http.HttpCompletionOption completionOption) { throw null; }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> GetAsync(System.Uri requestUri, System.Net.Http.HttpCompletionOption completionOption, System.Threading.CancellationToken cancellationToken) { throw null; }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> GetAsync(System.Uri requestUri, System.Threading.CancellationToken cancellationToken) { throw null; }
        public System.Threading.Tasks.Task<byte[]> GetByteArrayAsync(string requestUri) { throw null; }
        public System.Threading.Tasks.Task<byte[]> GetByteArrayAsync(System.Uri requestUri) { throw null; }
        public System.Threading.Tasks.Task<System.IO.Stream> GetStreamAsync(string requestUri) { throw null; }
        public System.Threading.Tasks.Task<System.IO.Stream> GetStreamAsync(System.Uri requestUri) { throw null; }
        public System.Threading.Tasks.Task<string> GetStringAsync(string requestUri) { throw null; }
        public System.Threading.Tasks.Task<string> GetStringAsync(System.Uri requestUri) { throw null; }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> PostAsync(string requestUri, System.Net.Http.HttpContent content) { throw null; }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> PostAsync(string requestUri, System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken) { throw null; }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> PostAsync(System.Uri requestUri, System.Net.Http.HttpContent content) { throw null; }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> PostAsync(System.Uri requestUri, System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken) { throw null; }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> PutAsync(string requestUri, System.Net.Http.HttpContent content) { throw null; }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> PutAsync(string requestUri, System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken) { throw null; }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> PutAsync(System.Uri requestUri, System.Net.Http.HttpContent content) { throw null; }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> PutAsync(System.Uri requestUri, System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken) { throw null; }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> SendAsync(System.Net.Http.HttpRequestMessage request) { throw null; }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> SendAsync(System.Net.Http.HttpRequestMessage request, System.Net.Http.HttpCompletionOption completionOption) { throw null; }
        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> SendAsync(System.Net.Http.HttpRequestMessage request, System.Net.Http.HttpCompletionOption completionOption, System.Threading.CancellationToken cancellationToken) { throw null; }
        public override System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { throw null; }
    }
    public partial class HttpClientHandler : System.Net.Http.HttpMessageHandler
    {
        public HttpClientHandler() { }
        public bool AllowAutoRedirect { get { throw null; } set { } }
        public System.Net.DecompressionMethods AutomaticDecompression { get { throw null; } set { } }
        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
        public bool CheckCertificateRevocationList { get { throw null; } set { } }
        public System.Net.Http.ClientCertificateOption ClientCertificateOptions { get { throw null; } set { } }
        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
        public System.Security.Cryptography.X509Certificates.X509CertificateCollection ClientCertificates { get; }
        public System.Net.CookieContainer CookieContainer { get { throw null; } set { } }
        public System.Net.ICredentials Credentials { get { throw null; } set { } }
        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
        public System.Net.ICredentials DefaultProxyCredentials { get { throw null; } set { } }
        public int MaxAutomaticRedirections { get { throw null; } set { } }
        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
        public int MaxConnectionsPerServer { get { throw null; } set { } }
        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
        public int MaxResponseHeadersLength { get { throw null; } set { } }
        public long MaxRequestContentBufferSize { get { throw null; } set { } }
        public bool PreAuthenticate { get { throw null; } set { } }
        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
        public System.Collections.Generic.IDictionary<string, object> Properties { get { throw null; } }
        public System.Net.IWebProxy Proxy { get { throw null; } set { } }
        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
        public System.Func<System.Net.Http.HttpRequestMessage, System.Security.Cryptography.X509Certificates.X509Certificate2, System.Security.Cryptography.X509Certificates.X509Chain, System.Net.Security.SslPolicyErrors, bool> ServerCertificateCustomValidationCallback { get { throw null; } set { } }
        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
        public System.Security.Authentication.SslProtocols SslProtocols { get { throw null; } set { } }
        public virtual bool SupportsAutomaticDecompression { get { throw null; } }
        public virtual bool SupportsProxy { get { throw null; } }
        public virtual bool SupportsRedirectConfiguration { get { throw null; } }
        public bool UseCookies { get { throw null; } set { } }
        public bool UseDefaultCredentials { get { throw null; } set { } }
        public bool UseProxy { get { throw null; } set { } }
        protected override void Dispose(bool disposing) { }
        protected internal override System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { throw null; }
    }
    public enum HttpCompletionOption
    {
        ResponseContentRead = 0,
        ResponseHeadersRead = 1,
    }
    public abstract partial class HttpContent : System.IDisposable
    {
        protected HttpContent() { }
        public System.Net.Http.Headers.HttpContentHeaders Headers { get { throw null; } }
        public System.Threading.Tasks.Task CopyToAsync(System.IO.Stream stream) { throw null; }
        public System.Threading.Tasks.Task CopyToAsync(System.IO.Stream stream, System.Net.TransportContext context) { throw null; }
        protected virtual System.Threading.Tasks.Task<System.IO.Stream> CreateContentReadStreamAsync() { throw null; }
        public void Dispose() { }
        protected virtual void Dispose(bool disposing) { }
        public System.Threading.Tasks.Task LoadIntoBufferAsync() { throw null; }
        public System.Threading.Tasks.Task LoadIntoBufferAsync(long maxBufferSize) { throw null; }
        public System.Threading.Tasks.Task<byte[]> ReadAsByteArrayAsync() { throw null; }
        public System.Threading.Tasks.Task<System.IO.Stream> ReadAsStreamAsync() { throw null; }
        public System.Threading.Tasks.Task<string> ReadAsStringAsync() { throw null; }
        protected abstract System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context);
        protected internal abstract bool TryComputeLength(out long length);
    }
    public abstract partial class HttpMessageHandler : System.IDisposable
    {
        protected HttpMessageHandler() { }
        public void Dispose() { }
        protected virtual void Dispose(bool disposing) { }
        protected internal abstract System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken);
    }
    public partial class HttpMessageInvoker : System.IDisposable
    {
        public HttpMessageInvoker(System.Net.Http.HttpMessageHandler handler) { }
        public HttpMessageInvoker(System.Net.Http.HttpMessageHandler handler, bool disposeHandler) { }
        public void Dispose() { }
        protected virtual void Dispose(bool disposing) { }
        public virtual System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { throw null; }
    }
    public partial class HttpMethod : System.IEquatable<System.Net.Http.HttpMethod>
    {
        public HttpMethod(string method) { }
        public static System.Net.Http.HttpMethod Delete { get { throw null; } }
        public static System.Net.Http.HttpMethod Get { get { throw null; } }
        public static System.Net.Http.HttpMethod Head { get { throw null; } }
        public string Method { get { throw null; } }
        public static System.Net.Http.HttpMethod Options { get { throw null; } }
        public static System.Net.Http.HttpMethod Post { get { throw null; } }
        public static System.Net.Http.HttpMethod Put { get { throw null; } }
        public static System.Net.Http.HttpMethod Trace { get { throw null; } }
        public bool Equals(System.Net.Http.HttpMethod other) { throw null; }
        public override bool Equals(object obj) { throw null; }
        public override int GetHashCode() { throw null; }
        public static bool operator ==(System.Net.Http.HttpMethod left, System.Net.Http.HttpMethod right) { throw null; }
        public static bool operator !=(System.Net.Http.HttpMethod left, System.Net.Http.HttpMethod right) { throw null; }
        public override string ToString() { throw null; }
    }
    public partial class HttpRequestException : System.Exception
    {
        public HttpRequestException() { }
        public HttpRequestException(string message) { }
        public HttpRequestException(string message, System.Exception inner) { }
    }
    public partial class HttpRequestMessage : System.IDisposable
    {
        public HttpRequestMessage() { }
        public HttpRequestMessage(System.Net.Http.HttpMethod method, string requestUri) { }
        public HttpRequestMessage(System.Net.Http.HttpMethod method, System.Uri requestUri) { }
        public System.Net.Http.HttpContent Content { get { throw null; } set { } }
        public System.Net.Http.Headers.HttpRequestHeaders Headers { get { throw null; } }
        public System.Net.Http.HttpMethod Method { get { throw null; } set { } }
        public System.Collections.Generic.IDictionary<string, object> Properties { get { throw null; } }
        public System.Uri RequestUri { get { throw null; } set { } }
        public System.Version Version { get { throw null; } set { } }
        public void Dispose() { }
        protected virtual void Dispose(bool disposing) { }
        public override string ToString() { throw null; }
    }
    public partial class HttpResponseMessage : System.IDisposable
    {
        public HttpResponseMessage() { }
        public HttpResponseMessage(System.Net.HttpStatusCode statusCode) { }
        public System.Net.Http.HttpContent Content { get { throw null; } set { } }
        public System.Net.Http.Headers.HttpResponseHeaders Headers { get { throw null; } }
        public bool IsSuccessStatusCode { get { throw null; } }
        public string ReasonPhrase { get { throw null; } set { } }
        public System.Net.Http.HttpRequestMessage RequestMessage { get { throw null; } set { } }
        public System.Net.HttpStatusCode StatusCode { get { throw null; } set { } }
        public System.Version Version { get { throw null; } set { } }
        public void Dispose() { }
        protected virtual void Dispose(bool disposing) { }
        public System.Net.Http.HttpResponseMessage EnsureSuccessStatusCode() { throw null; }
        public override string ToString() { throw null; }
    }
    public abstract partial class MessageProcessingHandler : System.Net.Http.DelegatingHandler
    {
        protected MessageProcessingHandler() { }
        protected MessageProcessingHandler(System.Net.Http.HttpMessageHandler innerHandler) { }
        protected abstract System.Net.Http.HttpRequestMessage ProcessRequest(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken);
        protected abstract System.Net.Http.HttpResponseMessage ProcessResponse(System.Net.Http.HttpResponseMessage response, System.Threading.CancellationToken cancellationToken);
        protected internal sealed override System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { throw null; }
    }
    public partial class MultipartContent : System.Net.Http.HttpContent, System.Collections.Generic.IEnumerable<System.Net.Http.HttpContent>, System.Collections.IEnumerable
    {
        public MultipartContent() { }
        public MultipartContent(string subtype) { }
        public MultipartContent(string subtype, string boundary) { }
        public virtual void Add(System.Net.Http.HttpContent content) { }
        protected override void Dispose(bool disposing) { }
        public System.Collections.Generic.IEnumerator<System.Net.Http.HttpContent> GetEnumerator() { throw null; }
        protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context) { throw null; }
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
        protected internal override bool TryComputeLength(out long length) { length = default(long); throw null; }
    }
    public partial class MultipartFormDataContent : System.Net.Http.MultipartContent
    {
        public MultipartFormDataContent() { }
        public MultipartFormDataContent(string boundary) { }
        public override void Add(System.Net.Http.HttpContent content) { }
        public void Add(System.Net.Http.HttpContent content, string name) { }
        public void Add(System.Net.Http.HttpContent content, string name, string fileName) { }
    }
    public partial class StreamContent : System.Net.Http.HttpContent
    {
        public StreamContent(System.IO.Stream content) { }
        public StreamContent(System.IO.Stream content, int bufferSize) { }
        protected override System.Threading.Tasks.Task<System.IO.Stream> CreateContentReadStreamAsync() { throw null; }
        protected override void Dispose(bool disposing) { }
        protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context) { throw null; }
        protected internal override bool TryComputeLength(out long length) { length = default(long); throw null; }
    }
    public partial class StringContent : System.Net.Http.ByteArrayContent
    {
        public StringContent(string content) : base (default(byte[])) { }
        public StringContent(string content, System.Text.Encoding encoding) : base (default(byte[])) { }
        public StringContent(string content, System.Text.Encoding encoding, string mediaType) : base (default(byte[])) { }
    }
}


text:
<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>
	<groupId>net.dontdrinkandroot.example</groupId>
	<artifactId>news</artifactId>
	<version>0.3.0-SNAPSHOT</version>
	<packaging>war</packaging>

	<properties>
		<version.org.springframework.security>4.0.4.RELEASE</version.org.springframework.security>
		<version.org.springframework>4.2.5.RELEASE</version.org.springframework>
		<version.com.sun.jersey.contribs>1.19.1</version.com.sun.jersey.contribs>
		<version.org.hibernate>4.2.21.Final</version.org.hibernate>
		<org.slf4j.version>1.7.21</org.slf4j.version>
		<javax.servlet-api.version>2.5</javax.servlet-api.version>
		<maven-compiler-plugin.version>3.1</maven-compiler-plugin.version>
		<org.hsqldb.version>2.3.2</org.hsqldb.version>
		<commons-dbcp.version>1.4</commons-dbcp.version>
		<junit.version>4.11</junit.version>
		<lang3.verison>3.4</lang3.verison>
		<org.eclipse.jetty.jetty-maven-plugin.version>9.1.1.v20140108</org.eclipse.jetty.jetty-maven-plugin.version>
	</properties>

	<developers>
		<developer>
			<name>Philip Washington Sorst</name>
			<url>https://sorst.net</url>
		</developer>
	</developers>

	<licenses>
		<license>
			<name>The Apache Software License, Version 2.0</name>
			<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
			<distribution>repo</distribution>
		</license>
	</licenses>

	<prerequisites>
		<maven>3.3.9</maven>
	</prerequisites>

	<build>
		<finalName>news</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>${maven-compiler-plugin.version}</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.eclipse.jetty</groupId>
				<artifactId>jetty-maven-plugin</artifactId>
				<version>${org.eclipse.jetty.jetty-maven-plugin.version}</version>
			</plugin>

			<plugin>
				<groupId>org.apache.tomcat.maven</groupId>
				<artifactId>tomcat7-maven-plugin</artifactId>
				<version>2.1</version>
				<configuration>
					<warFile>target/${project.build.finalName}.war</warFile>
					<server>tomcat</server>
					<username>admin</username>
					<password>admin</password>
					<port>8080</port>
					<url>http://localhost:8080/manager/text</url>
					<path>/${project.build.finalName}</path>
					<uriEncoding>UTF-8</uriEncoding>
				</configuration>
			</plugin>
		</plugins>
	</build>

	<dependencies>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${version.org.springframework}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${version.org.springframework}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${version.org.springframework}</version>
		</dependency>

		<dependency>
			<groupId>com.sun.jersey.contribs</groupId>
			<artifactId>jersey-spring</artifactId>
			<version>${version.com.sun.jersey.contribs}</version>
			<exclusions>
				<exclusion>
					<groupId>org.springframework</groupId>
					<artifactId>spring</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.springframework</groupId>
					<artifactId>spring-core</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.springframework</groupId>
					<artifactId>spring-web</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.springframework</groupId>
					<artifactId>spring-beans</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.springframework</groupId>
					<artifactId>spring-context</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.springframework</groupId>
					<artifactId>spring-aop</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

		<dependency>
			<groupId>com.sun.jersey</groupId>
			<artifactId>jersey-json</artifactId>
			<version>${version.com.sun.jersey.contribs}</version>
		</dependency>

		<!-- <dependency> -->
		<!-- <groupId>org.hsqldb</groupId> -->
		<!-- <artifactId>hsqldb</artifactId> -->
		<!-- <version>${org.hsqldb.version}</version> -->
		<!-- </dependency> -->

		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>${commons-dbcp.version}</version>
		</dependency>

		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>${lang3.verison}</version>
		</dependency>
		<!-- <dependency> -->
		<!-- <groupId>org.hibernate</groupId> -->
		<!-- <artifactId>hibernate-entitymanager</artifactId> -->
		<!-- <version>${version.org.hibernate}</version> -->
		<!-- </dependency> -->

		<!-- slf4j-log4j绑定 -->
		<dependency>
		<groupId>org.slf4j</groupId>
		<artifactId>slf4j-log4j12</artifactId>
		<version>${org.slf4j.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-web</artifactId>
			<version>${version.org.springframework.security}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-config</artifactId>
			<version>${version.org.springframework.security}</version>
		</dependency>

		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>${javax.servlet-api.version}</version>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${version.org.springframework}</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>

		<!-- mybatis -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.3.1</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>1.2.5</version>
		</dependency>
		<!-- mysql dirver -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.21</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-mapper-asl</artifactId>
			<version>1.9.13</version>
		</dependency>

		<dependency>
			<groupId>org.mybatis.generator</groupId>
			<artifactId>mybatis-generator-core</artifactId>
			<version>1.3.2</version>
			<scope>test</scope>
		</dependency>

<!-- 		<dependency> -->
<!-- 			<groupId>org.springframework.data</groupId> -->
<!-- 			<artifactId>spring-data-redis</artifactId> -->
<!-- 			<version>1.7.2.RELEASE</version> -->
<!-- 		</dependency> -->
<!-- 		<dependency> -->
<!-- 			<groupId>redis.clients</groupId> -->
<!-- 			<artifactId>jedis</artifactId> -->
<!-- 			<version>2.8.0</version> -->
<!-- 		</dependency> -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.8.0.rc2</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>2.8.0.rc2</version>
		</dependency>
	</dependencies>

</project>


text:
package com.intellij.java.psi.formatter.java;

import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.impl.DebugUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ref.GCUtil;

public class JavaPsiFormattingTest extends AbstractJavaFormatterTest {

  public void testReferenceExpressionSpaceInsertion() {
    String text = "if(x&y);";
    PsiFile file = createFile("A.java", "class C{{\n" + text + "\n}}");
    PsiElement element = file.findElementAt(file.getText().indexOf(text));
    PsiIfStatement statement = PsiTreeUtil.getParentOfType(element, PsiIfStatement.class);
    assertNotNull(statement);

    Ref<PsiElement> result = Ref.create();
    CommandProcessor.getInstance().executeCommand(getProject(), () -> WriteAction.run(
      () -> result.set(CodeStyleManager.getInstance(getProject()).reformat(statement))
    ), "", null);

    PsiExpression expr = ((PsiIfStatement)result.get()).getCondition();
    assertEquals("PsiBinaryExpression:x & y\n" +
                 "  PsiReferenceExpression:x\n" +
                 "    PsiReferenceParameterList\n" +
                 "      <empty list>\n" +
                 "    PsiIdentifier:x('x')\n" +
                 "  PsiWhiteSpace(' ')\n" +
                 "  PsiJavaToken:AND('&')\n" +
                 "  PsiWhiteSpace(' ')\n" +
                 "  PsiReferenceExpression:y\n" +
                 "    PsiReferenceParameterList\n" +
                 "      <empty list>\n" +
                 "    PsiIdentifier:y('y')\n",
                 DebugUtil.psiToString(expr, false));
  }

  public void testPostponedFormattingNotAffectedByGc() {
    PsiJavaFile file = (PsiJavaFile)createFile("a.java", "class A {}\nclass B{}");

    WriteCommandAction.runWriteCommandAction(getProject(), () -> {
      file.getClasses()[0].delete();
      GCUtil.tryGcSoftlyReachableObjects();
    });

    assertEquals("class B{}", file.getText());
  }
}


text:
package me.sgrouples.rogue.cc

trait BsonExecutors[MB] {
  def async: AsyncBsonQueryExecutor[MB]
}

object CcBsonExecutors extends BsonExecutors[CcMeta[_]] {
  override val async = CcAsyncQueryExecutor
}


text:
This repository serves as a collection of command line node scripts useful for penetration testers operating in a node environment.

## Examples:

### Netcat.js

Listen on port 8000 and return a command shell.
```
node netcat.js --listen-port 8000 -c
```

Connect on port 80 to localhost:
```
node netat.js --target-port 80 --target-address localhost
```

### TCP-Proxy.js

Listen on port 8000 and forward to port 80 on (most) home routers (192.168.1.1).
```
node tcp-proxy.js --local-port 8000 --remote-host 192.168.1.1 --remote-port 80
```

### SSH-Tunnel.js

Connect to remote address 192.168.0.156 and spawn shell:
```
node ssh-tunnel.js --remote-host 192.168.0.156 -u username
```

Connect to remote address 192.168.0.156 and open up a port on 192.168.0.156 to pipe data back
```
node ssh-tunnel.js --remote-host 192.168.0.156 -u username -f 8000
```

### URL-Fuzzer.js

Fuzz base url with word list and check for response codes 200 and 201:
```
node url-fuzzer.js --base-url http://localhost:3000/FUZZ.php --wordlist /path/to/wordlist --response-codes 200,201
```
Note that this only works on small wordlists because of its asynchronous, non-blocking nature.


text:
<?xml version="1.0" encoding="UTF-8"?>

<!--                                                                                -->
<!-- Copyright (c) 2014, Arjuna Technologies Limited, Newcastle-upon-Tyne, England. All rights reserved. -->
<!--                                                                                -->

<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.arjuna.dbsupport</groupId>
        <artifactId>jeebatch-support-parent</artifactId>
        <version>1.0.0p1m1</version>
    </parent>

    <artifactId>jeebatch-support-test</artifactId>

    <packaging>ejb</packaging>

    <name>JEE Batch DataBroker Support Test</name>

    <dependencies>
        <dependency>
            <groupId>org.jboss.spec.javax.ejb</groupId>
            <artifactId>jboss-ejb-api_${ejb-api.version}_spec</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.spec.javax.batch</groupId>
            <artifactId>jboss-batch-api_1.0_spec</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.arjuna.databroker</groupId>
            <artifactId>data-common</artifactId>
            <version>${version.com.arjuna.databroker}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.arjuna.dbsupport</groupId>
            <artifactId>jeebatch-support</artifactId>
            <version>1.0.0p1m1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>


text:
# acquit

Parse BDD-style tests (Mocha, Jasmine) to generate documentation

[![Build Status](https://travis-ci.org/vkarpov15/acquit.svg?branch=master)](https://travis-ci.org/vkarpov15/acquit)

## `acquit.parse()`

#### It can parse Mocha tests into `blocks`

Acquit's `parse()` function takes in mocha tests as a string, and outputs
a list of "blocks", which are either `describe` or `it` calls. A `describe`
call contains a list of "blocks", whereas an `it` call contains the actual
`code` in order to provide an effective, well-tested example.

```javascript

    var contents =
      '/**\n' +
      ' * A `Model` is a convenience wrapper around objects stored in a\n' +
      ' * collection\n' +
      ' */\n' +
      'describe(\'Model\', function() {\n' +
      '  /**\n' +
      '   * Model **should** be able to save stuff\n' +
      '   **/\n' +
      '  it(\'can save\', function() {\n' +
      '    assert.ok(1);\n' +
      '  });\n' +
      '\n' +
      '  it(\'can save with a parameter\', function() {\n' +
      '  });\n' +
      '});';

    var ret = acquit.parse(contents);

    // One top-level block: describe('Model')
    assert.equal(1, ret.length);
    assert.equal('describe', ret[0].type);
    assert.equal(1, ret[0].comments.length);
    assert.ok(ret[0].comments[0].indexOf('`Model`') != -1);

    // Top-level block contains the `it('can save')` block, which contains
    // the code
    assert.equal(2, ret[0].blocks.length);
    assert.equal('it', ret[0].blocks[0].type);
    assert.equal(1, ret[0].blocks[0].comments.length);
    assert.ok(ret[0].blocks[0].code.indexOf('assert.ok(1)') !== -1);
    assert.equal('can save', ret[0].blocks[0].contents);

    assert.equal('it', ret[0].blocks[1].type);
    assert.equal('can save with a parameter', ret[0].blocks[1].contents);
    assert.equal(0, ret[0].blocks[1].comments.length);

```

#### Acquit can also take a callback as second parameter

```javascript
    var contents =
    'describe(\'ES6\', function() {\n' +
    '  // ES6 has a `yield` keyword\n' +
    '  it(\'should be able to yield\', function() {\n' +
    '    // some code\n' +
    '  });\n' +
    '});';

    var cb = function(block) {
    block.code = 'return value from callback';
    };

    var ret = acquit.parse(contents, cb);

    assert.equal('return value from callback', ret[0].blocks[0].code);
```

#### It can parse the ES6 `yield` keyword

Acquit can also parse ES6 code

```javascript

    var contents =
      'describe(\'ES6\', function() {\n' +
      '  // ES6 has a `yield` keyword\n' +
      '  it(\'should be able to yield\', function() {\n' +
      '    co(function*() {\n' +
      '      yield 1;\n' +
      '    })();\n' +
      '  });\n' +
      '});';

    var ret = acquit.parse(contents);

    assert.equal(1, ret.length);
    assert.equal('describe', ret[0].type);
    assert.equal(0, ret[0].comments.length);
    assert.equal(1, ret[0].blocks.length);
    assert.equal('it', ret[0].blocks[0].type);
    assert.equal(1, ret[0].blocks[0].comments.length);
    assert.ok(ret[0].blocks[0].code);

```

## `acquit.trimEachLine()`

#### It strips out whitespace and asterisks in multiline comments

`trimEachLine()` is a helper function for trimming whitespace and asterisks
from JSdoc-style comments

```javascript

    var str = '  * This comment looks like a \n' +
      '  * parsed JSdoc-style comment';

    assert.equal(acquit.trimEachLine(str), 'This comment looks like a\n' +
      'parsed JSdoc-style comment');

```

#### It strips out whitespace and asterisks in multiline comments

You don't have to use JSdoc-style comments: `trimEachLine()` also trims
leading and trailing whitespace.

```javascript

    var str = 'This comment looks like a \n' +
      '  * parsed JSdoc-style comment';

    assert.equal(acquit.trimEachLine(str), 'This comment looks like a\n' +
      'parsed JSdoc-style comment');

```


text:
.intro-contato {
    background: url("../img/bg/bg-contato.jpg") no-repeat center;
    background-size: cover;
}

/*orçamnto*/
.contato{
    padding: 40px 0;
}

.form-contato {
    padding-right: 60px;
}
.form-contato label {
    display: block;
    font-family: Georgia, 'Times New Roman', Times, serif;
    font-size: 18px;
    line-height: 25px;
    margin-bottom: 4px;
}
.form-contato input {
    display: block;
    width: 100%;
    border: 4px solid #fec63e;
    background: none;
    padding: 7px 10px;
    margin-bottom: 10px;
    outline: none;
    font-size: 14px;
    font-family: Georgia, 'Times New Roman', Times, serif;
}
.form-contato textarea {
    display: block;
    width: 100%;
    height: 120px;
    border: 4px solid #fec63e;
    background: none;
    padding: 7px 10px;
    margin-bottom: 20px;
    outline: none;
    font-size: 14px;
    font-family: Georgia, 'Times New Roman', Times, serif;
}

.form-contato button {
    padding: 7px 40px;
    background: none;
}

.contato-dados {
    color: #000;
}

.contato-dados h3 {
    font-size: 18px;
    line-height: 25px;
    text-transform: uppercase;
    color: #fec63e;
    font-weight: bold;
}
.contato-dados span {
    display: block;
    font-size: 18px;
    line-height: 30px;
    font-family: Georgia, 'Times New Roman', Times, serif;
}
.contato-dados span:nth-of-type(even){
    margin-bottom: 30px;
}

.contato-dados ul {
    margin-top: 10px;
}

.contato-dados ul li {
    display: inline-block;
    margin-right: 10px;
}
.contato-dados ul li a {
    border: 3px solid #fec63e;
    display: block;
    padding: 10px;
}
.contato-dados ul li a:hover {
    border-color: #000;
}

.contato-mapa {
    margin-bottom: 60px;
}


text:
import {
	CanDeactivatePreviousStep,
	CanActivateNextStep,
	DeactivatePreviousStep,
	ActivateNextStep
} from '../src/activation';
import {
	INVOKE_LIFECYCLE,
	REPLACE
} from '../src/navigation-plan';

describe('activation', () => {
	var viewPortFactory = (resultHandler, strategy = INVOKE_LIFECYCLE) => {
		return {
			strategy: strategy,
			prevComponent: { executionContext: { canDeactivate: resultHandler } }
		};
	};

	describe('CanDeactivatePreviousStep', () => {
		var sut,
			nextResult = null,
			next = () => {
				nextResult = true;
				return Promise.resolve(nextResult);
			};

		next.cancel = () => {
			nextResult = 'cancel';
			return Promise.resolve(nextResult);
		};

		beforeEach(() => {
			sut = new CanDeactivatePreviousStep();
			nextResult = null;
		});

		it('should return true for context that canDeactivate', () => {
			var singleNavContext = { plan: { first: viewPortFactory(() => (true)) } };

			sut.run(singleNavContext, next)
			expect(nextResult).toBe(true);
		});

		it('should return true for context that canDeactivate with REPLACE strategy', () => {
			var singleNavContext = { plan: { first: viewPortFactory(() => (true), REPLACE) } };

			sut.run(singleNavContext, next)
			expect(nextResult).toBe(true);
		});

		it('should cancel for context that cannot Deactivate', () => {
			var singleNavContext = { plan: {first: viewPortFactory(() => (false)) } };

			sut.run(singleNavContext, next)
			expect(nextResult).toBe('cancel');
		});

		it('should return true for context that cannot Deactivate with unknown strategy', () => {
			var singleNavContext = { plan: {first: viewPortFactory(() => (false), 'unknown') } };

			sut.run(singleNavContext, next)
			expect(nextResult).toBe(true);
		});

		it('should return true for context that canDeactivate with a promise', (done) => {
			var singleNavPromiseContext = { plan: {first: viewPortFactory(() => (Promise.resolve(true))) } };

			sut.run(singleNavPromiseContext, next).then(() => {
				expect(nextResult).toBe(true);
				done();
			});
		});

		it('should cancel for context that cantDeactivate with a promise', (done) => {
			var singleNavPromiseContext = { plan: {first: viewPortFactory(() => (Promise.resolve(false))) } };

			sut.run(singleNavPromiseContext, next).then(() => {
				expect(nextResult).toBe('cancel');
				done();
			});
		});

		it('should return true when all plans return true', () => {
			var doubleNavContext = { plan: { first: viewPortFactory(() => (true)), second: viewPortFactory(() => (true))} };

			sut.run(doubleNavContext, next)
			expect(nextResult).toBe(true);
		});

		it('should cancel when some plans return false', () => {
			var doubleNavContext = { plan: {first: viewPortFactory(() => (true)), second: viewPortFactory(() => (false))} };

			sut.run(doubleNavContext, next)
			expect(nextResult).toBe('cancel');
		});

		describe('with a childNavigationContext', () => {
			it ('should return true when child is true', () => {
				var viewPort = viewPortFactory(() => (true)),
					navContextWithChild = { plan: { first: viewPort } };

				viewPort.childNavigationContext = { plan: { first:viewPortFactory(() => (true)) } };

				sut.run(navContextWithChild, next)
				expect(nextResult).toBe(true);
			});

			it ('should cancel when child is false', () => {
				var viewPort = viewPortFactory(() => (true)),
					navContextWithChild = { plan: { first: viewPort } };

				viewPort.childNavigationContext = { plan: { first:viewPortFactory(() => (false)) } };

				sut.run(navContextWithChild, next);
				expect(nextResult).toBe('cancel');
			});
		});

		describe('with router and currentInstruction', ()=> {
			var executionContext = { },
				viewPort = viewPortFactory(() => (true)),
				navContextWithRouter = { plan: { first: viewPort } };

			viewPort.prevComponent.executionContext.router = { currentInstruction: { viewPortInstructions: { first: { component: { executionContext: executionContext }}}} };

			it('should return true when router instruction canDeactivate', () => {
				executionContext.canDeactivate = () => (true);

				sut.run(navContextWithRouter, next)
				expect(nextResult).toBe(true);
			});

			it('should cancel when router instruction cannot deactivate', () => {
				executionContext.canDeactivate = () => (false);

				navContextWithRouter.plan = { first: viewPort };

				sut.run(navContextWithRouter, next)
				expect(nextResult).toBe('cancel');
			});
		});
	});
});


text:
import swig from 'swig';

swig.setFilter('length', function (input) {
    return input.length;
});

swig.setFilter('json', function (input) {
    return JSON.stringify(input);
});

swig.setFilter('nl2br', function (input) {
    return input.replace('\n', '<br/>');
});

swig.setFilter('striptags', function(input) {
    return input;
});

swig.setFilter(
    'numberformat',
    (input) => {
        return input;
    }
);

swig.setDefaults({
    cache: false,
    loader: {
        resolve: function (to, from) {

            if (to.indexOf('.html') < 0) {
                to = to + '.html';
            }

            if (from) {
                to = 'app/' + to;
            }

            return  to;
        },
        load: function (identifier,cb) {

            let encoding = encoding || 'utf8';
            let template = dirRoot + '/' + identifier;

            if (!cb) {
                return fs.readFileSync(template, encoding);
            }
            else {
                fs.readFile(dirRoot + '/' + identifier, encoding, cb);
            }

        }
    }
});

export default swig;