text:
namespace re2 {

static const int Trace = false;

typedef set<string>::iterator SSIter;
typedef set<string>::const_iterator ConstSSIter;

// Initializes a Prefilter, allocating subs_ as necessary.
Prefilter::Prefilter(Op op) {
  op_ = op;
  subs_ = NULL;
  if (op_ == AND || op_ == OR)
    subs_ = new vector<Prefilter*>;

  VLOG(10) << "constructed: " << reinterpret_cast<intptr_t>(this);
}

// Destroys a Prefilter.
Prefilter::~Prefilter() {
  VLOG(10) << "destructing: " << reinterpret_cast<intptr_t>(this);
  if (subs_) {
    for (size_t i = 0; i < subs_->size(); i++)
      delete (*subs_)[i];
    delete subs_;
    subs_ = NULL;
  }
}

// Simplify if the node is an empty Or or And.
Prefilter* Prefilter::Simplify() {
  if (op_ != AND && op_ != OR) {
    return this;
  }

  // Nothing left in the AND/OR.
  if (subs_->size() == 0) {
    if (op_ == AND)
      op_ = ALL;  // AND of nothing is true
    else
      op_ = NONE;  // OR of nothing is false

    return this;
  }

  // Just one subnode: throw away wrapper.
  if (subs_->size() == 1) {
    Prefilter* a = (*subs_)[0];
    subs_->clear();
    delete this;
    return a->Simplify();
  }

  return this;
}

// Combines two Prefilters together to create an "op" (AND or OR).
// The passed Prefilters will be part of the returned Prefilter or deleted.
// Does lots of work to avoid creating unnecessarily complicated structures.
Prefilter* Prefilter::AndOr(Op op, Prefilter* a, Prefilter* b) {
  // If a, b can be rewritten as op, do so.
  a = a->Simplify();
  b = b->Simplify();

  // Canonicalize: a->op <= b->op.
  if (a->op() > b->op()) {
    Prefilter* t = a;
    a = b;
    b = t;
  }

  // Trivial cases.
  //    ALL AND b = b
  //    NONE OR b = b
  //    ALL OR b   = ALL
  //    NONE AND b = NONE
  // Don't need to look at b, because of canonicalization above.
  // ALL and NONE are smallest opcodes.
  if (a->op() == ALL || a->op() == NONE) {
    if ((a->op() == ALL && op == AND) ||
        (a->op() == NONE && op == OR)) {
      delete a;
      return b;
    } else {
      delete b;
      return a;
    }
  }

  // If a and b match op, merge their contents.
  if (a->op() == op && b->op() == op) {
    for (size_t i = 0; i < b->subs()->size(); i++) {
      Prefilter* bb = (*b->subs())[i];
      a->subs()->push_back(bb);
    }
    b->subs()->clear();
    delete b;
    return a;
  }

  // If a already has the same op as the op that is under construction
  // add in b (similarly if b already has the same op, add in a).
  if (b->op() == op) {
    Prefilter* t = a;
    a = b;
    b = t;
  }
  if (a->op() == op) {
    a->subs()->push_back(b);
    return a;
  }

  // Otherwise just return the op.
  Prefilter* c = new Prefilter(op);
  c->subs()->push_back(a);
  c->subs()->push_back(b);
  return c;
}

Prefilter* Prefilter::And(Prefilter* a, Prefilter* b) {
  return AndOr(AND, a, b);
}

Prefilter* Prefilter::Or(Prefilter* a, Prefilter* b) {
  return AndOr(OR, a, b);
}

static void SimplifyStringSet(set<string> *ss) {
  // Now make sure that the strings aren't redundant.  For example, if
  // we know "ab" is a required string, then it doesn't help at all to
  // know that "abc" is also a required string, so delete "abc". This
  // is because, when we are performing a string search to filter
  // regexps, matching ab will already allow this regexp to be a
  // candidate for match, so further matching abc is redundant.

  for (SSIter i = ss->begin(); i != ss->end(); ++i) {
    SSIter j = i;
    ++j;
    while (j != ss->end()) {
      // Increment j early so that we can erase the element it points to.
      SSIter old_j = j;
      ++j;
      if (old_j->find(*i) != string::npos)
        ss->erase(old_j);
    }
  }
}

Prefilter* Prefilter::OrStrings(set<string>* ss) {
  SimplifyStringSet(ss);
  Prefilter* or_prefilter = NULL;
  if (!ss->empty()) {
    or_prefilter = new Prefilter(NONE);
    for (SSIter i = ss->begin(); i != ss->end(); ++i)
      or_prefilter = Or(or_prefilter, FromString(*i));
  }
  return or_prefilter;
}

static Rune ToLowerRune(Rune r) {
  if (r < Runeself) {
    if ('A' <= r && r <= 'Z')
      r += 'a' - 'A';
    return r;
  }

  const CaseFold *f = LookupCaseFold(unicode_tolower, num_unicode_tolower, r);
  if (f == NULL || r < f->lo)
    return r;
  return ApplyFold(f, r);
}

static Rune ToLowerRuneLatin1(Rune r) {
  if ('A' <= r && r <= 'Z')
    r += 'a' - 'A';
  return r;
}

Prefilter* Prefilter::FromString(const string& str) {
  Prefilter* m = new Prefilter(Prefilter::ATOM);
  m->atom_ = str;
  return m;
}

// Information about a regexp used during computation of Prefilter.
// Can be thought of as information about the set of strings matching
// the given regular expression.
class Prefilter::Info {
 public:
  Info();
  ~Info();

  // More constructors.  They delete their Info* arguments.
  static Info* Alt(Info* a, Info* b);
  static Info* Concat(Info* a, Info* b);
  static Info* And(Info* a, Info* b);
  static Info* Star(Info* a);
  static Info* Plus(Info* a);
  static Info* Quest(Info* a);
  static Info* EmptyString();
  static Info* NoMatch();
  static Info* AnyChar();
  static Info* CClass(CharClass* cc, bool latin1);
  static Info* Literal(Rune r);
  static Info* LiteralLatin1(Rune r);
  static Info* AnyMatch();

  // Format Info as a string.
  string ToString();

  // Caller takes ownership of the Prefilter.
  Prefilter* TakeMatch();

  set<string>& exact() { return exact_; }

  bool is_exact() const { return is_exact_; }

  class Walker;

 private:
  set<string> exact_;

  // When is_exact_ is true, the strings that match
  // are placed in exact_. When it is no longer an exact
  // set of strings that match this RE, then is_exact_
  // is false and the match_ contains the required match
  // criteria.
  bool is_exact_;

  // Accumulated Prefilter query that any
  // match for this regexp is guaranteed to match.
  Prefilter* match_;
};

Prefilter::Info::Info()
  : is_exact_(false),
    match_(NULL) {
}

Prefilter::Info::~Info() {
  delete match_;
}

Prefilter* Prefilter::Info::TakeMatch() {
  if (is_exact_) {
    match_ = Prefilter::OrStrings(&exact_);
    is_exact_ = false;
  }
  Prefilter* m = match_;
  match_ = NULL;
  return m;
}

// Format a Info in string form.
string Prefilter::Info::ToString() {
  if (is_exact_) {
    int n = 0;
    string s;
    for (set<string>::iterator i = exact_.begin(); i != exact_.end(); ++i) {
      if (n++ > 0)
        s += ",";
      s += *i;
    }
    return s;
  }

  if (match_)
    return match_->DebugString();

  return "";
}

// Add the strings from src to dst.
static void CopyIn(const set<string>& src, set<string>* dst) {
  for (ConstSSIter i = src.begin(); i != src.end(); ++i)
    dst->insert(*i);
}

// Add the cross-product of a and b to dst.
// (For each string i in a and j in b, add i+j.)
static void CrossProduct(const set<string>& a,
                         const set<string>& b,
                         set<string>* dst) {
  for (ConstSSIter i = a.begin(); i != a.end(); ++i)
    for (ConstSSIter j = b.begin(); j != b.end(); ++j)
      dst->insert(*i + *j);
}

// Concats a and b. Requires that both are exact sets.
// Forms an exact set that is a crossproduct of a and b.
Prefilter::Info* Prefilter::Info::Concat(Info* a, Info* b) {
  if (a == NULL)
    return b;
  DCHECK(a->is_exact_);
  DCHECK(b && b->is_exact_);
  Info *ab = new Info();

  CrossProduct(a->exact_, b->exact_, &ab->exact_);
  ab->is_exact_ = true;

  delete a;
  delete b;
  return ab;
}

// Constructs an inexact Info for ab given a and b.
// Used only when a or b is not exact or when the
// exact cross product is likely to be too big.
Prefilter::Info* Prefilter::Info::And(Info* a, Info* b) {
  if (a == NULL)
    return b;
  if (b == NULL)
    return a;

  Info *ab = new Info();

  ab->match_ = Prefilter::And(a->TakeMatch(), b->TakeMatch());
  ab->is_exact_ = false;
  delete a;
  delete b;
  return ab;
}

// Constructs Info for a|b given a and b.
Prefilter::Info* Prefilter::Info::Alt(Info* a, Info* b) {
  Info *ab = new Info();

  if (a->is_exact_ && b->is_exact_) {
    CopyIn(a->exact_, &ab->exact_);
    CopyIn(b->exact_, &ab->exact_);
    ab->is_exact_ = true;
  } else {
    // Either a or b has is_exact_ = false. If the other
    // one has is_exact_ = true, we move it to match_ and
    // then create a OR of a,b. The resulting Info has
    // is_exact_ = false.
    ab->match_ = Prefilter::Or(a->TakeMatch(), b->TakeMatch());
    ab->is_exact_ = false;
  }

  delete a;
  delete b;
  return ab;
}

// Constructs Info for a? given a.
Prefilter::Info* Prefilter::Info::Quest(Info *a) {
  Info *ab = new Info();

  ab->is_exact_ = false;
  ab->match_ = new Prefilter(ALL);
  delete a;
  return ab;
}

// Constructs Info for a* given a.
// Same as a? -- not much to do.
Prefilter::Info* Prefilter::Info::Star(Info *a) {
  return Quest(a);
}

// Constructs Info for a+ given a. If a was exact set, it isn't
// anymore.
Prefilter::Info* Prefilter::Info::Plus(Info *a) {
  Info *ab = new Info();

  ab->match_ = a->TakeMatch();
  ab->is_exact_ = false;

  delete a;
  return ab;
}

static string RuneToString(Rune r) {
  char buf[UTFmax];
  int n = runetochar(buf, &r);
  return string(buf, n);
}

static string RuneToStringLatin1(Rune r) {
  char c = r & 0xff;
  return string(&c, 1);
}

// Constructs Info for literal rune.
Prefilter::Info* Prefilter::Info::Literal(Rune r) {
  Info* info = new Info();
  info->exact_.insert(RuneToString(ToLowerRune(r)));
  info->is_exact_ = true;
  return info;
}

// Constructs Info for literal rune for Latin1 encoded string.
Prefilter::Info* Prefilter::Info::LiteralLatin1(Rune r) {
  Info* info = new Info();
  info->exact_.insert(RuneToStringLatin1(ToLowerRuneLatin1(r)));
  info->is_exact_ = true;
  return info;
}

// Constructs Info for dot (any character).
Prefilter::Info* Prefilter::Info::AnyChar() {
  Prefilter::Info* info = new Prefilter::Info();
  info->match_ = new Prefilter(ALL);
  return info;
}

// Constructs Prefilter::Info for no possible match.
Prefilter::Info* Prefilter::Info::NoMatch() {
  Prefilter::Info* info = new Prefilter::Info();
  info->match_ = new Prefilter(NONE);
  return info;
}

// Constructs Prefilter::Info for any possible match.
// This Prefilter::Info is valid for any regular expression,
// since it makes no assertions whatsoever about the
// strings being matched.
Prefilter::Info* Prefilter::Info::AnyMatch() {
  Prefilter::Info *info = new Prefilter::Info();
  info->match_ = new Prefilter(ALL);
  return info;
}

// Constructs Prefilter::Info for just the empty string.
Prefilter::Info* Prefilter::Info::EmptyString() {
  Prefilter::Info* info = new Prefilter::Info();
  info->is_exact_ = true;
  info->exact_.insert("");
  return info;
}

// Constructs Prefilter::Info for a character class.
typedef CharClass::iterator CCIter;
Prefilter::Info* Prefilter::Info::CClass(CharClass *cc,
                                         bool latin1) {
  if (Trace) {
    VLOG(0) << "CharClassInfo:";
    for (CCIter i = cc->begin(); i != cc->end(); ++i)
      VLOG(0) << "  " << i->lo << "-" << i->hi;
  }

  // If the class is too large, it's okay to overestimate.
  if (cc->size() > 10)
    return AnyChar();

  Prefilter::Info *a = new Prefilter::Info();
  for (CCIter i = cc->begin(); i != cc->end(); ++i)
    for (Rune r = i->lo; r <= i->hi; r++) {
      if (latin1) {
        a->exact_.insert(RuneToStringLatin1(ToLowerRuneLatin1(r)));
      } else {
        a->exact_.insert(RuneToString(ToLowerRune(r)));
      }
    }

  a->is_exact_ = true;

  if (Trace) {
    VLOG(0) << " = " << a->ToString();
  }

  return a;
}

class Prefilter::Info::Walker : public Regexp::Walker<Prefilter::Info*> {
 public:
  Walker(bool latin1) : latin1_(latin1) {}

  virtual Info* PostVisit(
      Regexp* re, Info* parent_arg,
      Info* pre_arg,
      Info** child_args, int nchild_args);

  virtual Info* ShortVisit(
      Regexp* re,
      Info* parent_arg);

  bool latin1() { return latin1_; }
 private:
  bool latin1_;
  DISALLOW_COPY_AND_ASSIGN(Walker);
};

Prefilter::Info* Prefilter::BuildInfo(Regexp* re) {
  if (Trace) {
    LOG(INFO) << "BuildPrefilter::Info: " << re->ToString();
  }

  bool latin1 = (re->parse_flags() & Regexp::Latin1) != 0;
  Prefilter::Info::Walker w(latin1);
  Prefilter::Info* info = w.WalkExponential(re, NULL, 100000);

  if (w.stopped_early()) {
    delete info;
    return NULL;
  }

  return info;
}

Prefilter::Info* Prefilter::Info::Walker::ShortVisit(
    Regexp* re, Prefilter::Info* parent_arg) {
  return AnyMatch();
}

// Constructs the Prefilter::Info for the given regular expression.
// Assumes re is simplified.
Prefilter::Info* Prefilter::Info::Walker::PostVisit(
    Regexp* re, Prefilter::Info* parent_arg,
    Prefilter::Info* pre_arg, Prefilter::Info** child_args,
    int nchild_args) {
  Prefilter::Info *info;
  switch (re->op()) {
    default:
    case kRegexpRepeat:
      LOG(DFATAL) << "Bad regexp op " << re->op();
      info = EmptyString();
      break;

    case kRegexpNoMatch:
      info = NoMatch();
      break;

    // These ops match the empty string:
    case kRegexpEmptyMatch:      // anywhere
    case kRegexpBeginLine:       // at beginning of line
    case kRegexpEndLine:         // at end of line
    case kRegexpBeginText:       // at beginning of text
    case kRegexpEndText:         // at end of text
    case kRegexpWordBoundary:    // at word boundary
    case kRegexpNoWordBoundary:  // not at word boundary
      info = EmptyString();
      break;

    case kRegexpLiteral:
      if (latin1()) {
        info = LiteralLatin1(re->rune());
      }
      else {
        info = Literal(re->rune());
      }
      break;

    case kRegexpLiteralString:
      if (re->nrunes() == 0) {
        info = NoMatch();
        break;
      }
      if (latin1()) {
        info = LiteralLatin1(re->runes()[0]);
        for (int i = 1; i < re->nrunes(); i++) {
          info = Concat(info, LiteralLatin1(re->runes()[i]));
        }
      } else {
        info = Literal(re->runes()[0]);
        for (int i = 1; i < re->nrunes(); i++) {
          info = Concat(info, Literal(re->runes()[i]));
        }
      }
      break;

    case kRegexpConcat: {
      // Accumulate in info.
      // Exact is concat of recent contiguous exact nodes.
      info = NULL;
      Info* exact = NULL;
      for (int i = 0; i < nchild_args; i++) {
        Info* ci = child_args[i];  // child info
        if (!ci->is_exact() ||
            (exact && ci->exact().size() * exact->exact().size() > 16)) {
          // Exact run is over.
          info = And(info, exact);
          exact = NULL;
          // Add this child's info.
          info = And(info, ci);
        } else {
          // Append to exact run.
          exact = Concat(exact, ci);
        }
      }
      info = And(info, exact);
    }
      break;

    case kRegexpAlternate:
      info = child_args[0];
      for (int i = 1; i < nchild_args; i++)
        info = Alt(info, child_args[i]);
      VLOG(10) << "Alt: " << info->ToString();
      break;

    case kRegexpStar:
      info = Star(child_args[0]);
      break;

    case kRegexpQuest:
      info = Quest(child_args[0]);
      break;

    case kRegexpPlus:
      info = Plus(child_args[0]);
      break;

    case kRegexpAnyChar:
      // Claim nothing, except that it's not empty.
      info = AnyChar();
      break;

    case kRegexpCharClass:
      info = CClass(re->cc(), latin1());
      break;

    case kRegexpCapture:
      // These don't affect the set of matching strings.
      info = child_args[0];
      break;
  }

  if (Trace) {
    VLOG(0) << "BuildInfo " << re->ToString()
            << ": " << (info ? info->ToString() : "");
  }

  return info;
}

Prefilter* Prefilter::FromRegexp(Regexp* re) {
  if (re == NULL)
    return NULL;

  Regexp* simple = re->Simplify();
  Prefilter::Info *info = BuildInfo(simple);

  simple->Decref();
  if (info == NULL)
    return NULL;

  Prefilter* m = info->TakeMatch();

  delete info;
  return m;
}

string Prefilter::DebugString() const {
  switch (op_) {
    default:
      LOG(DFATAL) << "Bad op in Prefilter::DebugString: " << op_;
      return StringPrintf("op%d", op_);
    case NONE:
      return "*no-matches*";
    case ATOM:
      return atom_;
    case ALL:
      return "";
    case AND: {
      string s = "";
      for (size_t i = 0; i < subs_->size(); i++) {
        if (i > 0)
          s += " ";
        Prefilter* sub = (*subs_)[i];
        s += sub ? sub->DebugString() : "<nil>";
      }
      return s;
    }
    case OR: {
      string s = "(";
      for (size_t i = 0; i < subs_->size(); i++) {
        if (i > 0)
          s += "|";
        Prefilter* sub = (*subs_)[i];
        s += sub ? sub->DebugString() : "<nil>";
      }
      s += ")";
      return s;
    }
  }
}

Prefilter* Prefilter::FromRE2(const RE2* re2) {
  if (re2 == NULL)
    return NULL;

  Regexp* regexp = re2->Regexp();
  if (regexp == NULL)
    return NULL;

  return FromRegexp(regexp);
}

}  // namespace re2


text:
//===-- tsan_rtl_thread.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of ThreadSanitizer (TSan), a race detector.
//
//===----------------------------------------------------------------------===//

#include "sanitizer_common/sanitizer_placement_new.h"
#include "tsan_rtl.h"
#include "tsan_mman.h"
#include "tsan_platform.h"
#include "tsan_report.h"
#include "tsan_sync.h"

namespace __tsan {

// ThreadContext implementation.

ThreadContext::ThreadContext(int tid)
  : ThreadContextBase(tid)
  , thr()
  , sync()
  , epoch0()
  , epoch1() {
}

#if !SANITIZER_GO
ThreadContext::~ThreadContext() {
}
#endif

void ThreadContext::OnDead() {
  CHECK_EQ(sync.size(), 0);
}

void ThreadContext::OnJoined(void *arg) {
  ThreadState *caller_thr = static_cast<ThreadState *>(arg);
  AcquireImpl(caller_thr, 0, &sync);
  sync.Reset(&caller_thr->proc()->clock_cache);
}

struct OnCreatedArgs {
  ThreadState *thr;
  uptr pc;
};

void ThreadContext::OnCreated(void *arg) {
  thr = 0;
  if (tid == 0)
    return;
  OnCreatedArgs *args = static_cast<OnCreatedArgs *>(arg);
  if (!args->thr)  // GCD workers don't have a parent thread.
    return;
  args->thr->fast_state.IncrementEpoch();
  // Can't increment epoch w/o writing to the trace as well.
  TraceAddEvent(args->thr, args->thr->fast_state, EventTypeMop, 0);
  ReleaseImpl(args->thr, 0, &sync);
  creation_stack_id = CurrentStackId(args->thr, args->pc);
  if (reuse_count == 0)
    StatInc(args->thr, StatThreadMaxTid);
}

void ThreadContext::OnReset() {
  CHECK_EQ(sync.size(), 0);
  uptr trace_p = GetThreadTrace(tid);
  ReleaseMemoryPagesToOS(trace_p, trace_p + TraceSize() * sizeof(Event));
  //!!! ReleaseMemoryToOS(GetThreadTraceHeader(tid), sizeof(Trace));
}

void ThreadContext::OnDetached(void *arg) {
  ThreadState *thr1 = static_cast<ThreadState*>(arg);
  sync.Reset(&thr1->proc()->clock_cache);
}

struct OnStartedArgs {
  ThreadState *thr;
  uptr stk_addr;
  uptr stk_size;
  uptr tls_addr;
  uptr tls_size;
};

void ThreadContext::OnStarted(void *arg) {
  OnStartedArgs *args = static_cast<OnStartedArgs*>(arg);
  thr = args->thr;
  // RoundUp so that one trace part does not contain events
  // from different threads.
  epoch0 = RoundUp(epoch1 + 1, kTracePartSize);
  epoch1 = (u64)-1;
  new(thr) ThreadState(ctx, tid, unique_id, epoch0, reuse_count,
      args->stk_addr, args->stk_size, args->tls_addr, args->tls_size);
#if !SANITIZER_GO
  thr->shadow_stack = &ThreadTrace(thr->tid)->shadow_stack[0];
  thr->shadow_stack_pos = thr->shadow_stack;
  thr->shadow_stack_end = thr->shadow_stack + kShadowStackSize;
#else
  // Setup dynamic shadow stack.
  const int kInitStackSize = 8;
  thr->shadow_stack = (uptr*)internal_alloc(MBlockShadowStack,
      kInitStackSize * sizeof(uptr));
  thr->shadow_stack_pos = thr->shadow_stack;
  thr->shadow_stack_end = thr->shadow_stack + kInitStackSize;
#endif
  if (common_flags()->detect_deadlocks)
    thr->dd_lt = ctx->dd->CreateLogicalThread(unique_id);
  thr->fast_state.SetHistorySize(flags()->history_size);
  // Commit switch to the new part of the trace.
  // TraceAddEvent will reset stack0/mset0 in the new part for us.
  TraceAddEvent(thr, thr->fast_state, EventTypeMop, 0);

  thr->fast_synch_epoch = epoch0;
  AcquireImpl(thr, 0, &sync);
  StatInc(thr, StatSyncAcquire);
  sync.Reset(&thr->proc()->clock_cache);
  thr->is_inited = true;
  DPrintf("#%d: ThreadStart epoch=%zu stk_addr=%zx stk_size=%zx "
          "tls_addr=%zx tls_size=%zx\n",
          tid, (uptr)epoch0, args->stk_addr, args->stk_size,
          args->tls_addr, args->tls_size);
}

void ThreadContext::OnFinished() {
#if SANITIZER_GO
  internal_free(thr->shadow_stack);
  thr->shadow_stack = nullptr;
  thr->shadow_stack_pos = nullptr;
  thr->shadow_stack_end = nullptr;
#endif
  if (!detached) {
    thr->fast_state.IncrementEpoch();
    // Can't increment epoch w/o writing to the trace as well.
    TraceAddEvent(thr, thr->fast_state, EventTypeMop, 0);
    ReleaseImpl(thr, 0, &sync);
  }
  epoch1 = thr->fast_state.epoch();

  if (common_flags()->detect_deadlocks)
    ctx->dd->DestroyLogicalThread(thr->dd_lt);
  thr->clock.ResetCached(&thr->proc()->clock_cache);
#if !SANITIZER_GO
  thr->last_sleep_clock.ResetCached(&thr->proc()->clock_cache);
#endif
#if !SANITIZER_GO
  PlatformCleanUpThreadState(thr);
#endif
  thr->~ThreadState();
#if TSAN_COLLECT_STATS
  StatAggregate(ctx->stat, thr->stat);
#endif
  thr = 0;
}

#if !SANITIZER_GO
struct ThreadLeak {
  ThreadContext *tctx;
  int count;
};

static void MaybeReportThreadLeak(ThreadContextBase *tctx_base, void *arg) {
  Vector<ThreadLeak> &leaks = *(Vector<ThreadLeak>*)arg;
  ThreadContext *tctx = static_cast<ThreadContext*>(tctx_base);
  if (tctx->detached || tctx->status != ThreadStatusFinished)
    return;
  for (uptr i = 0; i < leaks.Size(); i++) {
    if (leaks[i].tctx->creation_stack_id == tctx->creation_stack_id) {
      leaks[i].count++;
      return;
    }
  }
  ThreadLeak leak = {tctx, 1};
  leaks.PushBack(leak);
}
#endif

#if !SANITIZER_GO
static void ReportIgnoresEnabled(ThreadContext *tctx, IgnoreSet *set) {
  if (tctx->tid == 0) {
    Printf("ThreadSanitizer: main thread finished with ignores enabled\n");
  } else {
    Printf("ThreadSanitizer: thread T%d %s finished with ignores enabled,"
      " created at:\n", tctx->tid, tctx->name);
    PrintStack(SymbolizeStackId(tctx->creation_stack_id));
  }
  Printf("  One of the following ignores was not ended"
      " (in order of probability)\n");
  for (uptr i = 0; i < set->Size(); i++) {
    Printf("  Ignore was enabled at:\n");
    PrintStack(SymbolizeStackId(set->At(i)));
  }
  Die();
}

static void ThreadCheckIgnore(ThreadState *thr) {
  if (ctx->after_multithreaded_fork)
    return;
  if (thr->ignore_reads_and_writes)
    ReportIgnoresEnabled(thr->tctx, &thr->mop_ignore_set);
  if (thr->ignore_sync)
    ReportIgnoresEnabled(thr->tctx, &thr->sync_ignore_set);
}
#else
static void ThreadCheckIgnore(ThreadState *thr) {}
#endif

void ThreadFinalize(ThreadState *thr) {
  ThreadCheckIgnore(thr);
#if !SANITIZER_GO
  if (!flags()->report_thread_leaks)
    return;
  ThreadRegistryLock l(ctx->thread_registry);
  Vector<ThreadLeak> leaks;
  ctx->thread_registry->RunCallbackForEachThreadLocked(
      MaybeReportThreadLeak, &leaks);
  for (uptr i = 0; i < leaks.Size(); i++) {
    ScopedReport rep(ReportTypeThreadLeak);
    rep.AddThread(leaks[i].tctx, true);
    rep.SetCount(leaks[i].count);
    OutputReport(thr, rep);
  }
#endif
}

int ThreadCount(ThreadState *thr) {
  uptr result;
  ctx->thread_registry->GetNumberOfThreads(0, 0, &result);
  return (int)result;
}

int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached) {
  StatInc(thr, StatThreadCreate);
  OnCreatedArgs args = { thr, pc };
  u32 parent_tid = thr ? thr->tid : kInvalidTid;  // No parent for GCD workers.
  int tid =
      ctx->thread_registry->CreateThread(uid, detached, parent_tid, &args);
  DPrintf("#%d: ThreadCreate tid=%d uid=%zu\n", parent_tid, tid, uid);
  StatSet(thr, StatThreadMaxAlive, ctx->thread_registry->GetMaxAliveThreads());
  return tid;
}

void ThreadStart(ThreadState *thr, int tid, tid_t os_id,
                 ThreadType thread_type) {
  uptr stk_addr = 0;
  uptr stk_size = 0;
  uptr tls_addr = 0;
  uptr tls_size = 0;
#if !SANITIZER_GO
  if (thread_type != ThreadType::Fiber)
    GetThreadStackAndTls(tid == 0, &stk_addr, &stk_size, &tls_addr, &tls_size);

  if (tid) {
    if (stk_addr && stk_size)
      MemoryRangeImitateWrite(thr, /*pc=*/ 1, stk_addr, stk_size);

    if (tls_addr && tls_size) ImitateTlsWrite(thr, tls_addr, tls_size);
  }
#endif

  ThreadRegistry *tr = ctx->thread_registry;
  OnStartedArgs args = { thr, stk_addr, stk_size, tls_addr, tls_size };
  tr->StartThread(tid, os_id, thread_type, &args);

  tr->Lock();
  thr->tctx = (ThreadContext*)tr->GetThreadLocked(tid);
  tr->Unlock();

#if !SANITIZER_GO
  if (ctx->after_multithreaded_fork) {
    thr->ignore_interceptors++;
    ThreadIgnoreBegin(thr, 0);
    ThreadIgnoreSyncBegin(thr, 0);
  }
#endif
}

void ThreadFinish(ThreadState *thr) {
  ThreadCheckIgnore(thr);
  StatInc(thr, StatThreadFinish);
  if (thr->stk_addr && thr->stk_size)
    DontNeedShadowFor(thr->stk_addr, thr->stk_size);
  if (thr->tls_addr && thr->tls_size)
    DontNeedShadowFor(thr->tls_addr, thr->tls_size);
  thr->is_dead = true;
  ctx->thread_registry->FinishThread(thr->tid);
}

struct ConsumeThreadContext {
  uptr uid;
  ThreadContextBase *tctx;
};

static bool ConsumeThreadByUid(ThreadContextBase *tctx, void *arg) {
  ConsumeThreadContext *findCtx = (ConsumeThreadContext *)arg;
  if (tctx->user_id == findCtx->uid && tctx->status != ThreadStatusInvalid) {
    if (findCtx->tctx) {
      // Ensure that user_id is unique. If it's not the case we are screwed.
      // Something went wrong before, but now there is no way to recover.
      // Returning a wrong thread is not an option, it may lead to very hard
      // to debug false positives (e.g. if we join a wrong thread).
      Report("ThreadSanitizer: dup thread with used id 0x%zx\n", findCtx->uid);
      Die();
    }
    findCtx->tctx = tctx;
    tctx->user_id = 0;
  }
  return false;
}

int ThreadConsumeTid(ThreadState *thr, uptr pc, uptr uid) {
  ConsumeThreadContext findCtx = {uid, nullptr};
  ctx->thread_registry->FindThread(ConsumeThreadByUid, &findCtx);
  int tid = findCtx.tctx ? findCtx.tctx->tid : ThreadRegistry::kUnknownTid;
  DPrintf("#%d: ThreadTid uid=%zu tid=%d\n", thr->tid, uid, tid);
  return tid;
}

void ThreadJoin(ThreadState *thr, uptr pc, int tid) {
  CHECK_GT(tid, 0);
  CHECK_LT(tid, kMaxTid);
  DPrintf("#%d: ThreadJoin tid=%d\n", thr->tid, tid);
  ctx->thread_registry->JoinThread(tid, thr);
}

void ThreadDetach(ThreadState *thr, uptr pc, int tid) {
  CHECK_GT(tid, 0);
  CHECK_LT(tid, kMaxTid);
  ctx->thread_registry->DetachThread(tid, thr);
}

void ThreadNotJoined(ThreadState *thr, uptr pc, int tid, uptr uid) {
  CHECK_GT(tid, 0);
  CHECK_LT(tid, kMaxTid);
  ctx->thread_registry->SetThreadUserId(tid, uid);
}

void ThreadSetName(ThreadState *thr, const char *name) {
  ctx->thread_registry->SetThreadName(thr->tid, name);
}

void MemoryAccessRange(ThreadState *thr, uptr pc, uptr addr,
                       uptr size, bool is_write) {
  if (size == 0)
    return;

  u64 *shadow_mem = (u64*)MemToShadow(addr);
  DPrintf2("#%d: MemoryAccessRange: @%p %p size=%d is_write=%d\n",
      thr->tid, (void*)pc, (void*)addr,
      (int)size, is_write);

#if SANITIZER_DEBUG
  if (!IsAppMem(addr)) {
    Printf("Access to non app mem %zx\n", addr);
    DCHECK(IsAppMem(addr));
  }
  if (!IsAppMem(addr + size - 1)) {
    Printf("Access to non app mem %zx\n", addr + size - 1);
    DCHECK(IsAppMem(addr + size - 1));
  }
  if (!IsShadowMem((uptr)shadow_mem)) {
    Printf("Bad shadow addr %p (%zx)\n", shadow_mem, addr);
    DCHECK(IsShadowMem((uptr)shadow_mem));
  }
  if (!IsShadowMem((uptr)(shadow_mem + size * kShadowCnt / 8 - 1))) {
    Printf("Bad shadow addr %p (%zx)\n",
               shadow_mem + size * kShadowCnt / 8 - 1, addr + size - 1);
    DCHECK(IsShadowMem((uptr)(shadow_mem + size * kShadowCnt / 8 - 1)));
  }
#endif

  StatInc(thr, StatMopRange);

  if (*shadow_mem == kShadowRodata) {
    DCHECK(!is_write);
    // Access to .rodata section, no races here.
    // Measurements show that it can be 10-20% of all memory accesses.
    StatInc(thr, StatMopRangeRodata);
    return;
  }

  FastState fast_state = thr->fast_state;
  if (fast_state.GetIgnoreBit())
    return;

  fast_state.IncrementEpoch();
  thr->fast_state = fast_state;
  TraceAddEvent(thr, fast_state, EventTypeMop, pc);

  bool unaligned = (addr % kShadowCell) != 0;

  // Handle unaligned beginning, if any.
  for (; addr % kShadowCell && size; addr++, size--) {
    int const kAccessSizeLog = 0;
    Shadow cur(fast_state);
    cur.SetWrite(is_write);
    cur.SetAddr0AndSizeLog(addr & (kShadowCell - 1), kAccessSizeLog);
    MemoryAccessImpl(thr, addr, kAccessSizeLog, is_write, false,
        shadow_mem, cur);
  }
  if (unaligned)
    shadow_mem += kShadowCnt;
  // Handle middle part, if any.
  for (; size >= kShadowCell; addr += kShadowCell, size -= kShadowCell) {
    int const kAccessSizeLog = 3;
    Shadow cur(fast_state);
    cur.SetWrite(is_write);
    cur.SetAddr0AndSizeLog(0, kAccessSizeLog);
    MemoryAccessImpl(thr, addr, kAccessSizeLog, is_write, false,
        shadow_mem, cur);
    shadow_mem += kShadowCnt;
  }
  // Handle ending, if any.
  for (; size; addr++, size--) {
    int const kAccessSizeLog = 0;
    Shadow cur(fast_state);
    cur.SetWrite(is_write);
    cur.SetAddr0AndSizeLog(addr & (kShadowCell - 1), kAccessSizeLog);
    MemoryAccessImpl(thr, addr, kAccessSizeLog, is_write, false,
        shadow_mem, cur);
  }
}

#if !SANITIZER_GO
void FiberSwitchImpl(ThreadState *from, ThreadState *to) {
  Processor *proc = from->proc();
  ProcUnwire(proc, from);
  ProcWire(proc, to);
  set_cur_thread(to);
}

ThreadState *FiberCreate(ThreadState *thr, uptr pc, unsigned flags) {
  void *mem = internal_alloc(MBlockThreadContex, sizeof(ThreadState));
  ThreadState *fiber = static_cast<ThreadState *>(mem);
  internal_memset(fiber, 0, sizeof(*fiber));
  int tid = ThreadCreate(thr, pc, 0, true);
  FiberSwitchImpl(thr, fiber);
  ThreadStart(fiber, tid, 0, ThreadType::Fiber);
  FiberSwitchImpl(fiber, thr);
  return fiber;
}

void FiberDestroy(ThreadState *thr, uptr pc, ThreadState *fiber) {
  FiberSwitchImpl(thr, fiber);
  ThreadFinish(fiber);
  FiberSwitchImpl(fiber, thr);
  internal_free(fiber);
}

void FiberSwitch(ThreadState *thr, uptr pc,
                 ThreadState *fiber, unsigned flags) {
  if (!(flags & FiberSwitchFlagNoSync))
    Release(thr, pc, (uptr)fiber);
  FiberSwitchImpl(thr, fiber);
  if (!(flags & FiberSwitchFlagNoSync))
    Acquire(fiber, pc, (uptr)fiber);
}
#endif

}  // namespace __tsan

redpajama_set_name: RedPajamaGithub


text:
package com.heliosapm.shorthand.store;

import gnu.trove.map.hash.TObjectLongHashMap;

/**
 *
Title: IMetricDataPoint

 *
Description: Defines the datapoints of an {@link IMetric}.

 *
Company: Helios Development Group LLC

 * @author Whitehead (nwhitehead AT heliosdev DOT org)
 *
com.heliosapm.shorthand.store.IMetricDataPoint

 * @param <T> The collector type
 */

public interface IMetricDataPoint<T> {
	/**
	 * Returns the collector instance name
	 * @return the collector instance name
	 */
	public String getCollectorName();
	/**
	 * Returns the metric short name
	 * @return the metric short name
	 */
	public String getShortName();
	/**
	 * Returns the metric unit
	 * @return the metric unit
	 */
	public String getUnit();

	/**
	 * Returns the sub metric names
	 * @return the sub metric names
	 */
	public String[] getSubNames();

	/**
	 * Returns a the period data points for this metric and collector
	 * @return an array of the period data points
	 */
	public long[] getDataPoints();

}


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Saltarelle.Compiler.JSModel.Expressions;
using Saltarelle.Compiler.JSModel.Statements;

namespace Saltarelle.Compiler.JSModel.StateMachineRewrite
{
	internal static class DisposeGenerator {
		private class Node {
			public string HandlerName { get; private set; }
			public List<int> StateValues { get; private set; }
			public List<Node> Children { get; private set; }

			public Node(string handlerName) {
				this.HandlerName = handlerName;
				this.StateValues = new List<int>();
				this.Children = new List<Node>();
			}
		}

		private static void AddItem(List<Node> nodes, Tuple<int, List<string>> item, int listIndex) {
			var n = nodes.SingleOrDefault(x => x.HandlerName == item.Item2[listIndex]);
			if (n == null)
				nodes.Add(n = new Node(item.Item2[listIndex]));
			n.StateValues.Add(item.Item1);
			if (listIndex < item.Item2.Count - 1)
				AddItem(n.Children, item, listIndex + 1);
		}

		private static List<Node> GenerateHandlerTree(List<Tuple<int, List<string>>> flat) {
			var result = new List<Node>();
			foreach (var item in flat) {
				AddItem(result, item, 0);
			}

			return result;
		}

		private static JsStatement GenerateBody(string stateVariableName, List<Node> nodes) {
			if (nodes.Count == 0)
				return new JsBreakStatement();

			return new JsSwitchStatement(JsExpression.Identifier(stateVariableName),
			                             nodes.Select(n => new JsSwitchSection(n.StateValues.Select(v => JsExpression.Number(v)),
			                                                   new JsTryStatement(
			                                                       GenerateBody(stateVariableName, n.Children),
			                                                       null,
			                                                       new JsExpressionStatement(JsExpression.Invocation(JsExpression.Member(JsExpression.Identifier(n.HandlerName), "call"), JsExpression.This))))));
		}

		public static JsBlockStatement GenerateDisposer(string stateVariableName, List<Tuple<int, List<string>>> stateFinallyHandlers) {
			if (stateFinallyHandlers.Count == 0)
				return null;

			return new JsBlockStatement(
			           new JsTryStatement(
			               GenerateBody(stateVariableName, GenerateHandlerTree(stateFinallyHandlers)),
			               null,
			               new JsExpressionStatement(JsExpression.Assign(JsExpression.Identifier(stateVariableName), JsExpression.Number(-1)))
			           )
			       );
		}
	}
}


text:
'use strict';

const chai = require('chai'),
  expect = chai.expect,
  Support = require(__dirname + '/../../support'),
  Sequelize = Support.Sequelize,
  Promise = Sequelize.Promise,
  dialect = Support.getTestDialect(),
  DataTypes = require(__dirname + '/../../../../lib/data-types'),
  sequelize = require(__dirname + '/../../../../lib/sequelize');

if (dialect.match(/^postgres/)) {
  describe('[POSTGRES Specific] DAO', () => {
    beforeEach(function() {
      this.sequelize.options.quoteIdentifiers = true;
      this.User = this.sequelize.define('User', {
        username: DataTypes.STRING,
        email: { type: DataTypes.ARRAY(DataTypes.TEXT) },
        settings: DataTypes.HSTORE,
        document: { type: DataTypes.HSTORE, defaultValue: { default: "'value'" } },
        phones: DataTypes.ARRAY(DataTypes.HSTORE),
        emergency_contact: DataTypes.JSON,
        emergencyContact: DataTypes.JSON,
        friends: {
          type: DataTypes.ARRAY(DataTypes.JSON),
          defaultValue: []
        },
        magic_numbers: {
          type: DataTypes.ARRAY(DataTypes.INTEGER),
          defaultValue: []
        },
        course_period: DataTypes.RANGE(DataTypes.DATE),
        acceptable_marks: { type: DataTypes.RANGE(DataTypes.DECIMAL), defaultValue: [0.65, 1] },
        available_amount: DataTypes.RANGE,
        holidays: DataTypes.ARRAY(DataTypes.RANGE(DataTypes.DATE)),
        location: DataTypes.GEOMETRY()
      });
      return this.User.sync({ force: true });
    });

    afterEach(function() {
      this.sequelize.options.quoteIdentifiers = true;
    });

    it('should be able to search within an array', function() {
      return this.User.findAll({
        where: {
          email: ['hello', 'world']
        },
        attributes: ['id', 'username', 'email', 'settings', 'document', 'phones', 'emergency_contact', 'friends'],
        logging(sql) {
          expect(sql).to.equal('Executing (default): SELECT "id", "username", "email", "settings", "document", "phones", "emergency_contact", "friends" FROM "Users" AS "User" WHERE "User"."email" = ARRAY[\'hello\',\'world\']::TEXT[];');
        }
      });
    });

    it('should be able to update a field with type ARRAY(JSON)', function() {
      return this.User.create({
        username: 'bob',
        email: ['myemail@email.com'],
        friends: [{
          name: 'John Smith'
        }]
      }).then(userInstance => {
        expect(userInstance.friends).to.have.length(1);
        expect(userInstance.friends[0].name).to.equal('John Smith');

        return userInstance.update({
          friends: [{
            name: 'John Smythe'
          }]
        });
      }).get('friends')
        .tap(friends => {
          expect(friends).to.have.length(1);
          expect(friends[0].name).to.equal('John Smythe');
        });
    });

    it('should be able to find a record while searching in an array', function() {
      return this.User.bulkCreate([
        { username: 'bob', email: ['myemail@email.com'] },
        { username: 'tony', email: ['wrongemail@email.com'] }
      ]).then(() => {
        return this.User.findAll({ where: { email: ['myemail@email.com'] } }).then(user => {
          expect(user).to.be.instanceof(Array);
          expect(user).to.have.length(1);
          expect(user[0].username).to.equal('bob');
        });
      });
    });

    describe('json', () => {
      it('should be able to retrieve a row with ->> operator', function() {
        return this.sequelize.Promise.all([
          this.User.create({ username: 'swen', emergency_contact: { name: 'kate' } }),
          this.User.create({ username: 'anna', emergency_contact: { name: 'joe' } })])
          .then(() => {
            return this.User.find({ where: sequelize.json("emergency_contact->>'name'", 'kate'), attributes: ['username', 'emergency_contact'] });
          })
          .then(user => {
            expect(user.emergency_contact.name).to.equal('kate');
          });
      });

      it('should be able to query using the nested query language', function() {
        return this.sequelize.Promise.all([
          this.User.create({ username: 'swen', emergency_contact: { name: 'kate' } }),
          this.User.create({ username: 'anna', emergency_contact: { name: 'joe' } })])
          .then(() => {
            return this.User.find({
              where: sequelize.json({ emergency_contact: { name: 'kate' } })
            });
          })
          .then(user => {
            expect(user.emergency_contact.name).to.equal('kate');
          });
      });

      it('should be able to query using dot syntax', function() {
        return this.sequelize.Promise.all([
          this.User.create({ username: 'swen', emergency_contact: { name: 'kate' } }),
          this.User.create({ username: 'anna', emergency_contact: { name: 'joe' } })])
          .then(() => {
            return this.User.find({ where: sequelize.json('emergency_contact.name', 'joe') });
          })
          .then(user => {
            expect(user.emergency_contact.name).to.equal('joe');
          });
      });

      it('should be able to query using dot syntax with uppercase name', function() {
        return this.sequelize.Promise.all([
          this.User.create({ username: 'swen', emergencyContact: { name: 'kate' } }),
          this.User.create({ username: 'anna', emergencyContact: { name: 'joe' } })])
          .then(() => {
            return this.User.find({
              attributes: [[sequelize.json('emergencyContact.name'), 'contactName']],
              where: sequelize.json('emergencyContact.name', 'joe')
            });
          })
          .then(user => {
            expect(user.get('contactName')).to.equal('joe');
          });
      });

      it('should be able to store values that require JSON escaping', function() {
        const text = "Multi-line '$string' needing \"escaping\" for $$ and $1 type values";

        return this.User.create({ username: 'swen', emergency_contact: { value: text } })
          .then(user => {
            expect(user.isNewRecord).to.equal(false);
          })
          .then(() => {
            return this.User.find({ where: { username: 'swen' } });
          })
          .then(() => {
            return this.User.find({ where: sequelize.json('emergency_contact.value', text) });
          })
          .then(user => {
            expect(user.username).to.equal('swen');
          });
      });

      it('should be able to findOrCreate with values that require JSON escaping', function() {
        const text = "Multi-line '$string' needing \"escaping\" for $$ and $1 type values";

        return this.User.findOrCreate({ where: { username: 'swen' }, defaults: { emergency_contact: { value: text } } })
          .then(user => {
            expect(!user.isNewRecord).to.equal(true);
          })
          .then(() => {
            return this.User.find({ where: { username: 'swen' } });
          })
          .then(() => {
            return this.User.find({ where: sequelize.json('emergency_contact.value', text) });
          })
          .then(user => {
            expect(user.username).to.equal('swen');
          });
      });
    });

    describe('hstore', () => {
      it('should tell me that a column is hstore and not USER-DEFINED', function() {
        return this.sequelize.queryInterface.describeTable('Users').then(table => {
          expect(table.settings.type).to.equal('HSTORE');
          expect(table.document.type).to.equal('HSTORE');
        });
      });

      it('should stringify hstore with insert', function() {
        return this.User.create({
          username: 'bob',
          email: ['myemail@email.com'],
          settings: { mailing: false, push: 'facebook', frequency: 3 }
        }, {
          logging(sql) {
            const expected = '\'"mailing"=>"false","push"=>"facebook","frequency"=>"3"\',\'"default"=>"\'\'value\'\'"\'';
            expect(sql.indexOf(expected)).not.to.equal(-1);
          }
        });
      });

      it('should not rename hstore fields', function() {
        const Equipment = this.sequelize.define('Equipment', {
          grapplingHook: {
            type: DataTypes.STRING,
            field: 'grappling_hook'
          },
          utilityBelt: {
            type: DataTypes.HSTORE
          }
        });

        return Equipment.sync({ force: true }).then(() => {
          return Equipment.findAll({
            where: {
              utilityBelt: {
                grapplingHook: true
              }
            },
            logging(sql) {
              expect(sql).to.equal('Executing (default): SELECT "id", "grappling_hook" AS "grapplingHook", "utilityBelt", "createdAt", "updatedAt" FROM "Equipment" AS "Equipment" WHERE "Equipment"."utilityBelt" = \'"grapplingHook"=>"true"\';');
            }
          });
        });
      });

      it('should not rename json fields', function() {
        const Equipment = this.sequelize.define('Equipment', {
          grapplingHook: {
            type: DataTypes.STRING,
            field: 'grappling_hook'
          },
          utilityBelt: {
            type: DataTypes.JSON
          }
        });

        return Equipment.sync({ force: true }).then(() => {
          return Equipment.findAll({
            where: {
              utilityBelt: {
                grapplingHook: true
              }
            },
            logging(sql) {
              expect(sql).to.equal('Executing (default): SELECT "id", "grappling_hook" AS "grapplingHook", "utilityBelt", "createdAt", "updatedAt" FROM "Equipment" AS "Equipment" WHERE CAST(("Equipment"."utilityBelt"#>>\'{grapplingHook}\') AS BOOLEAN) = true;');
            }
          });
        });
      });

    });

    describe('range', () => {
      it('should tell me that a column is range and not USER-DEFINED', function() {
        return this.sequelize.queryInterface.describeTable('Users').then(table => {
          expect(table.course_period.type).to.equal('TSTZRANGE');
          expect(table.available_amount.type).to.equal('INT4RANGE');
        });
      });

    });

    describe('enums', () => {
      it('should be able to ignore enum types that already exist', function() {
        const User = this.sequelize.define('UserEnums', {
          mood: DataTypes.ENUM('happy', 'sad', 'meh')
        });

        return User.sync({ force: true }).then(() => {
          return User.sync();
        });
      });

      it('should be able to create/drop enums multiple times', function() {
        const User = this.sequelize.define('UserEnums', {
          mood: DataTypes.ENUM('happy', 'sad', 'meh')
        });

        return User.sync({ force: true }).then(() => {
          return User.sync({ force: true });
        });
      });

      it('should be able to create/drop multiple enums multiple times', function() {
        const DummyModel = this.sequelize.define('Dummy-pg', {
          username: DataTypes.STRING,
          theEnumOne: {
            type: DataTypes.ENUM,
            values: [
              'one',
              'two',
              'three'
            ]
          },
          theEnumTwo: {
            type: DataTypes.ENUM,
            values: [
              'four',
              'five',
              'six'
            ]
          }
        });

        return DummyModel.sync({ force: true }).then(() => {
          // now sync one more time:
          return DummyModel.sync({ force: true }).then(() => {
            // sync without dropping
            return DummyModel.sync();
          });
        });
      });

      it('should be able to create/drop multiple enums multiple times with field name (#7812)', function() {
        const DummyModel = this.sequelize.define('Dummy-pg', {
          username: DataTypes.STRING,
          theEnumOne: {
            field: 'oh_my_this_enum_one',
            type: DataTypes.ENUM,
            values: [
              'one',
              'two',
              'three'
            ]
          },
          theEnumTwo: {
            field: 'oh_my_this_enum_two',
            type: DataTypes.ENUM,
            values: [
              'four',
              'five',
              'six'
            ]
          }
        });

        return DummyModel.sync({ force: true }).then(() => {
          // now sync one more time:
          return DummyModel.sync({ force: true }).then(() => {
            // sync without dropping
            return DummyModel.sync();
          });
        });
      });

      it('should be able to add values to enum types', function() {
        let User = this.sequelize.define('UserEnums', {
          mood: DataTypes.ENUM('happy', 'sad', 'meh')
        });

        return User.sync({ force: true }).then(() => {
          User = this.sequelize.define('UserEnums', {
            mood: DataTypes.ENUM('neutral', 'happy', 'sad', 'ecstatic', 'meh', 'joyful')
          });

          return User.sync();
        }).then(() => {
          return this.sequelize.getQueryInterface().pgListEnums(User.getTableName());
        }).then(enums => {
          expect(enums).to.have.length(1);
          expect(enums[0].enum_value).to.equal('{neutral,happy,sad,ecstatic,meh,joyful}');
        });
      });

      describe('ARRAY(ENUM)', () => {
        it('should be able to ignore enum types that already exist', function() {
          const User = this.sequelize.define('UserEnums', {
            permissions: DataTypes.ARRAY(DataTypes.ENUM([
              'access',
              'write',
              'check',
              'delete'
            ]))
          });

          return User.sync({ force: true }).then(() => User.sync());
        });

        it('should be able to create/drop enums multiple times', function() {
          const User = this.sequelize.define('UserEnums', {
            permissions: DataTypes.ARRAY(DataTypes.ENUM([
              'access',
              'write',
              'check',
              'delete'
            ]))
          });

          return User.sync({ force: true }).then(() => User.sync({ force: true }));
        });

        it('should be able to add values to enum types', function() {
          let User = this.sequelize.define('UserEnums', {
            permissions: DataTypes.ARRAY(DataTypes.ENUM([
              'access',
              'write',
              'check',
              'delete'
            ]))
          });

          return User.sync({ force: true }).then(() => {
            User = this.sequelize.define('UserEnums', {
              permissions: DataTypes.ARRAY(
                DataTypes.ENUM('view', 'access', 'edit', 'write', 'check', 'delete')
              )
            });

            return User.sync();
          }).then(() => {
            return this.sequelize.getQueryInterface().pgListEnums(User.getTableName());
          }).then(enums => {
            expect(enums).to.have.length(1);
            expect(enums[0].enum_value).to.equal('{view,access,edit,write,check,delete}');
          });
        });

        it('should be able to insert new record', function() {
          const User = this.sequelize.define('UserEnums', {
            name: DataTypes.STRING,
            type: DataTypes.ENUM('A', 'B', 'C'),
            owners: DataTypes.ARRAY(DataTypes.STRING),
            permissions: DataTypes.ARRAY(DataTypes.ENUM([
              'access',
              'write',
              'check',
              'delete'
            ]))
          });

          return User.sync({ force: true })
            .then(() => {
              return User.create({
                name: 'file.exe',
                type: 'C',
                owners: ['userA', 'userB'],
                permissions: ['access', 'write']
              });
            })
            .then(user => {
              expect(user.name).to.equal('file.exe');
              expect(user.type).to.equal('C');
              expect(user.owners).to.deep.equal(['userA', 'userB']);
              expect(user.permissions).to.deep.equal(['access', 'write']);
            });
        });

        it('should fail when trying to insert foreign element on ARRAY(ENUM)', function() {
          const User = this.sequelize.define('UserEnums', {
            name: DataTypes.STRING,
            type: DataTypes.ENUM('A', 'B', 'C'),
            owners: DataTypes.ARRAY(DataTypes.STRING),
            permissions: DataTypes.ARRAY(DataTypes.ENUM([
              'access',
              'write',
              'check',
              'delete'
            ]))
          });

          return expect(User.sync({ force: true }).then(() => {
            return User.create({
              name: 'file.exe',
              type: 'C',
              owners: ['userA', 'userB'],
              permissions: ['cosmic_ray_disk_access']
            });
          })).to.be.rejectedWith(/invalid input value for enum "enum_UserEnums_permissions": "cosmic_ray_disk_access"/);
        });

        it('should be able to find records', function() {
          const User = this.sequelize.define('UserEnums', {
            name: DataTypes.STRING,
            type: DataTypes.ENUM('A', 'B', 'C'),
            permissions: DataTypes.ARRAY(DataTypes.ENUM([
              'access',
              'write',
              'check',
              'delete'
            ]))
          });

          return User.sync({ force: true })
            .then(() => {
              return User.bulkCreate([{
                name: 'file1.exe',
                type: 'C',
                permissions: ['access', 'write']
              }, {
                name: 'file2.exe',
                type: 'A',
                permissions: ['access', 'check']
              }, {
                name: 'file3.exe',
                type: 'B',
                permissions: ['access', 'write', 'delete']
              }]);
            })
            .then(() => {
              return User.findAll({
                where: {
                  type: {
                    $in: ['A', 'C']
                  },
                  permissions: {
                    $contains: ['write']
                  }
                }
              });
            })
            .then(users => {
              expect(users.length).to.equal(1);
              expect(users[0].name).to.equal('file1.exe');
              expect(users[0].type).to.equal('C');
              expect(users[0].permissions).to.deep.equal(['access', 'write']);
            });
        });
      });
    });

    describe('integers', () => {
      describe('integer', () => {
        beforeEach(function() {
          this.User = this.sequelize.define('User', {
            aNumber: DataTypes.INTEGER
          });

          return this.User.sync({ force: true });
        });

        it('positive', function() {
          const User = this.User;

          return User.create({ aNumber: 2147483647 }).then(user => {
            expect(user.aNumber).to.equal(2147483647);
            return User.find({ where: { aNumber: 2147483647 } }).then(_user => {
              expect(_user.aNumber).to.equal(2147483647);
            });
          });
        });

        it('negative', function() {
          const User = this.User;

          return User.create({ aNumber: -2147483647 }).then(user => {
            expect(user.aNumber).to.equal(-2147483647);
            return User.find({ where: { aNumber: -2147483647 } }).then(_user => {
              expect(_user.aNumber).to.equal(-2147483647);
            });
          });
        });
      });

      describe('bigint', () => {
        beforeEach(function() {
          this.User = this.sequelize.define('User', {
            aNumber: DataTypes.BIGINT
          });

          return this.User.sync({ force: true });
        });

        it('positive', function() {
          const User = this.User;

          return User.create({ aNumber: '9223372036854775807' }).then(user => {
            expect(user.aNumber).to.equal('9223372036854775807');
            return User.find({ where: { aNumber: '9223372036854775807' } }).then(_user => {
              expect(_user.aNumber).to.equal('9223372036854775807');
            });
          });
        });

        it('negative', function() {
          const User = this.User;

          return User.create({ aNumber: '-9223372036854775807' }).then(user => {
            expect(user.aNumber).to.equal('-9223372036854775807');
            return User.find({ where: { aNumber: '-9223372036854775807' } }).then(_user => {
              expect(_user.aNumber).to.equal('-9223372036854775807');
            });
          });
        });
      });
    });

    describe('timestamps', () => {
      beforeEach(function() {
        this.User = this.sequelize.define('User', {
          dates: DataTypes.ARRAY(DataTypes.DATE)
        });
        return this.User.sync({ force: true });
      });

      it('should use postgres "TIMESTAMP WITH TIME ZONE" instead of "DATETIME"', function() {
        return this.User.create({
          dates: []
        }, {
          logging(sql) {
            expect(sql.indexOf('TIMESTAMP WITH TIME ZONE')).to.be.greaterThan(0);
          }
        });
      });
    });

    describe('model', () => {
      it('create handles array correctly', function() {
        return this.User
          .create({ username: 'user', email: ['foo@bar.com', 'bar@baz.com'] })
          .then(oldUser => {
            expect(oldUser.email).to.contain.members(['foo@bar.com', 'bar@baz.com']);
          });
      });

      it('should save hstore correctly', function() {
        return this.User.create({ username: 'user', email: ['foo@bar.com'], settings: { created: '"value"' } }).then(newUser => {
          // Check to see if the default value for an hstore field works
          expect(newUser.document).to.deep.equal({ default: "'value'" });
          expect(newUser.settings).to.deep.equal({ created: '"value"' });

          // Check to see if updating an hstore field works
          return newUser.updateAttributes({ settings: { should: 'update', to: 'this', first: 'place' } }).then(oldUser => {
            // Postgres always returns keys in alphabetical order (ascending)
            expect(oldUser.settings).to.deep.equal({ first: 'place', should: 'update', to: 'this' });
          });
        });
      });

      it('should save hstore array correctly', function() {
        const User = this.User;

        return this.User.create({
          username: 'bob',
          email: ['myemail@email.com'],
          phones: [{ number: '123456789', type: 'mobile' }, { number: '987654321', type: 'landline' }, { number: '8675309', type: "Jenny's" }, { number: '5555554321', type: '"home\n"' }]
        }).then(() => {
          return User.findById(1).then(user => {
            expect(user.phones.length).to.equal(4);
            expect(user.phones[1].number).to.equal('987654321');
            expect(user.phones[2].type).to.equal("Jenny's");
            expect(user.phones[3].type).to.equal('"home\n"');
          });
        });
      });

      it('should bulkCreate with hstore property', function() {
        const User = this.User;

        return this.User.bulkCreate([{
          username: 'bob',
          email: ['myemail@email.com'],
          settings: { mailing: true, push: 'facebook', frequency: 3 }
        }]).then(() => {
          return User.findById(1).then(user => {
            expect(user.settings.mailing).to.equal('true');
          });
        });
      });

      it('should update hstore correctly', function() {
        return this.User.create({ username: 'user', email: ['foo@bar.com'], settings: { test: '"value"' } }).then(newUser => {
          // Check to see if the default value for an hstore field works
          expect(newUser.document).to.deep.equal({ default: "'value'" });
          expect(newUser.settings).to.deep.equal({ test: '"value"' });

          // Check to see if updating an hstore field works
          return this.User.update({ settings: { should: 'update', to: 'this', first: 'place' } }, { where: newUser.where() }).then(() => {
            return newUser.reload().then(() => {
              // Postgres always returns keys in alphabetical order (ascending)
              expect(newUser.settings).to.deep.equal({ first: 'place', should: 'update', to: 'this' });
            });
          });
        });
      });

      it('should update hstore correctly and return the affected rows', function() {
        return this.User.create({ username: 'user', email: ['foo@bar.com'], settings: { test: '"value"' } }).then(oldUser => {
          // Update the user and check that the returned object's fields have been parsed by the hstore library
          return this.User.update({ settings: { should: 'update', to: 'this', first: 'place' } }, { where: oldUser.where(), returning: true }).spread((count, users) => {
            expect(count).to.equal(1);
            expect(users[0].settings).to.deep.equal({ should: 'update', to: 'this', first: 'place' });
          });
        });
      });

      it('should read hstore correctly', function() {
        const data = { username: 'user', email: ['foo@bar.com'], settings: { test: '"value"' } };

        return this.User.create(data)
          .then(() => {
            return this.User.find({ where: { username: 'user' } });
          })
          .then(user => {
            // Check that the hstore fields are the same when retrieving the user
            expect(user.settings).to.deep.equal(data.settings);
          });
      });

      it('should read an hstore array correctly', function() {
        const data = { username: 'user', email: ['foo@bar.com'], phones: [{ number: '123456789', type: 'mobile' }, { number: '987654321', type: 'landline' }] };

        return this.User.create(data)
          .then(() => {
            // Check that the hstore fields are the same when retrieving the user
            return this.User.find({ where: { username: 'user' } });
          }).then(user => {
            expect(user.phones).to.deep.equal(data.phones);
          });
      });

      it('should read hstore correctly from multiple rows', function() {
        return this.User
          .create({ username: 'user1', email: ['foo@bar.com'], settings: { test: '"value"' } })
          .then(() => {
            return this.User.create({ username: 'user2', email: ['foo2@bar.com'], settings: { another: '"example"' } });
          })
          .then(() => {
            // Check that the hstore fields are the same when retrieving the user
            return this.User.findAll({ order: ['username'] });
          })
          .then(users => {
            expect(users[0].settings).to.deep.equal({ test: '"value"' });
            expect(users[1].settings).to.deep.equal({ another: '"example"' });
          });
      });

      it('should read hstore correctly from included models as well', function() {
        const HstoreSubmodel = this.sequelize.define('hstoreSubmodel', {
          someValue: DataTypes.HSTORE
        });
        const submodelValue = { testing: '"hstore"' };

        this.User.hasMany(HstoreSubmodel);

        return this.sequelize
          .sync({ force: true })
          .then(() => {
            return this.User.create({ username: 'user1' })
              .then(user => {
                return HstoreSubmodel.create({ someValue: submodelValue })
                  .then(submodel => {
                    return user.setHstoreSubmodels([submodel]);
                  });
              });
          })
          .then(() => {
            return this.User.find({ where: { username: 'user1' }, include: [HstoreSubmodel] });
          })
          .then(user => {
            expect(user.hasOwnProperty('hstoreSubmodels')).to.be.ok;
            expect(user.hstoreSubmodels.length).to.equal(1);
            expect(user.hstoreSubmodels[0].someValue).to.deep.equal(submodelValue);
          });
      });

      it('should save range correctly', function() {
        const period = [new Date(2015, 0, 1), new Date(2015, 11, 31)];
        return this.User.create({ username: 'user', email: ['foo@bar.com'], course_period: period }).then(newUser => {
          // Check to see if the default value for a range field works

          expect(newUser.acceptable_marks.length).to.equal(2);
          expect(newUser.acceptable_marks[0]).to.equal('0.65'); // lower bound
          expect(newUser.acceptable_marks[1]).to.equal('1'); // upper bound
          expect(newUser.acceptable_marks.inclusive).to.deep.equal([true, false]); // inclusive, exclusive
          expect(newUser.course_period[0] instanceof Date).to.be.ok; // lower bound
          expect(newUser.course_period[1] instanceof Date).to.be.ok; // upper bound
          expect(newUser.course_period[0]).to.equalTime(period[0]); // lower bound
          expect(newUser.course_period[1]).to.equalTime(period[1]); // upper bound
          expect(newUser.course_period.inclusive).to.deep.equal([true, false]); // inclusive, exclusive

          // Check to see if updating a range field works
          return newUser.updateAttributes({ acceptable_marks: [0.8, 0.9] }).then(() => {
            expect(newUser.acceptable_marks.length).to.equal(2);
            expect(newUser.acceptable_marks[0]).to.equal(0.8); // lower bound
            expect(newUser.acceptable_marks[1]).to.equal(0.9); // upper bound
          });
        });
      });

      it('should save range array correctly', function() {
        const User = this.User;
        const holidays = [
          [new Date(2015, 3, 1), new Date(2015, 3, 15)],
          [new Date(2015, 8, 1), new Date(2015, 9, 15)]
        ];

        return User.create({
          username: 'bob',
          email: ['myemail@email.com'],
          holidays
        }).then(() => {
          return User.findById(1).then(user => {
            expect(user.holidays.length).to.equal(2);
            expect(user.holidays[0].length).to.equal(2);
            expect(user.holidays[0][0] instanceof Date).to.be.ok;
            expect(user.holidays[0][1] instanceof Date).to.be.ok;
            expect(user.holidays[0][0]).to.equalTime(holidays[0][0]);
            expect(user.holidays[0][1]).to.equalTime(holidays[0][1]);
            expect(user.holidays[1].length).to.equal(2);
            expect(user.holidays[1][0] instanceof Date).to.be.ok;
            expect(user.holidays[1][1] instanceof Date).to.be.ok;
            expect(user.holidays[1][0]).to.equalTime(holidays[1][0]);
            expect(user.holidays[1][1]).to.equalTime(holidays[1][1]);
          });
        });
      });

      it('should bulkCreate with range property', function() {
        const User = this.User;
        const period = [new Date(2015, 0, 1), new Date(2015, 11, 31)];

        return User.bulkCreate([{
          username: 'bob',
          email: ['myemail@email.com'],
          course_period: period
        }]).then(() => {
          return User.findById(1).then(user => {
            expect(user.course_period[0] instanceof Date).to.be.ok;
            expect(user.course_period[1] instanceof Date).to.be.ok;
            expect(user.course_period[0]).to.equalTime(period[0]); // lower bound
            expect(user.course_period[1]).to.equalTime(period[1]); // upper bound
            expect(user.course_period.inclusive).to.deep.equal([true, false]); // inclusive, exclusive
          });
        });
      });

      it('should update range correctly', function() {
        const User = this.User;
        const period = [new Date(2015, 0, 1), new Date(2015, 11, 31)];

        return User.create({ username: 'user', email: ['foo@bar.com'], course_period: period }).then(newUser => {
          // Check to see if the default value for a range field works
          expect(newUser.acceptable_marks.length).to.equal(2);
          expect(newUser.acceptable_marks[0]).to.equal('0.65'); // lower bound
          expect(newUser.acceptable_marks[1]).to.equal('1'); // upper bound
          expect(newUser.acceptable_marks.inclusive).to.deep.equal([true, false]); // inclusive, exclusive
          expect(newUser.course_period[0] instanceof Date).to.be.ok;
          expect(newUser.course_period[1] instanceof Date).to.be.ok;
          expect(newUser.course_period[0]).to.equalTime(period[0]); // lower bound
          expect(newUser.course_period[1]).to.equalTime(period[1]); // upper bound
          expect(newUser.course_period.inclusive).to.deep.equal([true, false]); // inclusive, exclusive

          const period2 = [new Date(2015, 1, 1), new Date(2015, 10, 30)];

          // Check to see if updating a range field works
          return User.update({ course_period: period2 }, { where: newUser.where() }).then(() => {
            return newUser.reload().then(() => {
              expect(newUser.course_period[0] instanceof Date).to.be.ok;
              expect(newUser.course_period[1] instanceof Date).to.be.ok;
              expect(newUser.course_period[0]).to.equalTime(period2[0]); // lower bound
              expect(newUser.course_period[1]).to.equalTime(period2[1]); // upper bound
              expect(newUser.course_period.inclusive).to.deep.equal([true, false]); // inclusive, exclusive
            });
          });
        });
      });

      it('should update range correctly and return the affected rows', function() {
        const User = this.User;
        const period = [new Date(2015, 1, 1), new Date(2015, 10, 30)];

        return User.create({
          username: 'user',
          email: ['foo@bar.com'],
          course_period: [new Date(2015, 0, 1), new Date(2015, 11, 31)]
        }).then(oldUser => {
          // Update the user and check that the returned object's fields have been parsed by the range parser
          return User.update({ course_period: period }, { where: oldUser.where(), returning: true })
            .spread((count, users) => {
              expect(count).to.equal(1);
              expect(users[0].course_period[0] instanceof Date).to.be.ok;
              expect(users[0].course_period[1] instanceof Date).to.be.ok;
              expect(users[0].course_period[0]).to.equalTime(period[0]); // lower bound
              expect(users[0].course_period[1]).to.equalTime(period[1]); // upper bound
              expect(users[0].course_period.inclusive).to.deep.equal([true, false]); // inclusive, exclusive
            });
        });
      });

      it('should read range correctly', function() {
        const User = this.User;

        const course_period = [new Date(2015, 1, 1), new Date(2015, 10, 30)];
        course_period.inclusive = [false, false];

        const data = { username: 'user', email: ['foo@bar.com'], course_period };

        return User.create(data)
          .then(() => {
            return User.find({ where: { username: 'user' } });
          })
          .then(user => {
            // Check that the range fields are the same when retrieving the user
            expect(user.course_period).to.deep.equal(data.course_period);
          });
      });

      it('should read range array correctly', function() {
        const User = this.User;
        const holidays = [
          [new Date(2015, 3, 1, 10), new Date(2015, 3, 15)],
          [new Date(2015, 8, 1), new Date(2015, 9, 15)]
        ];

        holidays[0].inclusive = [true, true];
        holidays[1].inclusive = [true, true];

        const data = { username: 'user', email: ['foo@bar.com'], holidays };

        return User.create(data)
          .then(() => {
            // Check that the range fields are the same when retrieving the user
            return User.find({ where: { username: 'user' } });
          }).then(user => {
            expect(user.holidays).to.deep.equal(data.holidays);
          });
      });

      it('should read range correctly from multiple rows', function() {
        const User = this.User;
        const periods = [
          [new Date(2015, 0, 1), new Date(2015, 11, 31)],
          [new Date(2016, 0, 1), new Date(2016, 11, 31)]
        ];

        return User
          .create({ username: 'user1', email: ['foo@bar.com'], course_period: periods[0] })
          .then(() => {
            return User.create({ username: 'user2', email: ['foo2@bar.com'], course_period: periods[1] });
          })
          .then(() => {
            // Check that the range fields are the same when retrieving the user
            return User.findAll({ order: ['username'] });
          })
          .then(users => {
            expect(users[0].course_period[0]).to.equalTime(periods[0][0]); // lower bound
            expect(users[0].course_period[1]).to.equalTime(periods[0][1]); // upper bound
            expect(users[0].course_period.inclusive).to.deep.equal([true, false]); // inclusive, exclusive
            expect(users[1].course_period[0]).to.equalTime(periods[1][0]); // lower bound
            expect(users[1].course_period[1]).to.equalTime(periods[1][1]); // upper bound
            expect(users[1].course_period.inclusive).to.deep.equal([true, false]); // inclusive, exclusive
          });
      });

      it('should read range correctly from included models as well', function() {
        const period = [new Date(2016, 0, 1), new Date(2016, 11, 31)];
        const HolidayDate = this.sequelize.define('holidayDate', {
          period: DataTypes.RANGE(DataTypes.DATE)
        });

        this.User.hasMany(HolidayDate);

        return this.sequelize
          .sync({ force: true })
          .then(() => {
            return this.User
              .create({ username: 'user', email: ['foo@bar.com'] })
              .then(user => {
                return HolidayDate.create({ period })
                  .then(holidayDate => {
                    return user.setHolidayDates([holidayDate]);
                  });
              });
          })
          .then(() => {
            return this.User.find({ where: { username: 'user' }, include: [HolidayDate] });
          })
          .then(user => {
            expect(user.hasOwnProperty('holidayDates')).to.be.ok;
            expect(user.holidayDates.length).to.equal(1);
            expect(user.holidayDates[0].period.length).to.equal(2);
            expect(user.holidayDates[0].period[0]).to.equalTime(period[0]);
            expect(user.holidayDates[0].period[1]).to.equalTime(period[1]);
          });
      });
    });

    it('should save geometry correctly', function() {
      const point = { type: 'Point', coordinates: [39.807222, -76.984722] };
      return this.User.create({ username: 'user', email: ['foo@bar.com'], location: point }).then(newUser => {
        expect(newUser.location).to.deep.eql(point);
      });
    });

    it('should update geometry correctly', function() {
      const User = this.User;
      const point1 = { type: 'Point', coordinates: [39.807222, -76.984722] };
      const point2 = { type: 'Point', coordinates: [39.828333, -77.232222] };
      return User.create({ username: 'user', email: ['foo@bar.com'], location: point1 }).then(oldUser => {
        return User.update({ location: point2 }, { where: { username: oldUser.username }, returning: true }).spread((count, updatedUsers) => {
          expect(updatedUsers[0].location).to.deep.eql(point2);
        });
      });
    });

    it('should read geometry correctly', function() {
      const User = this.User;
      const point = { type: 'Point', coordinates: [39.807222, -76.984722] };

      return User.create({ username: 'user', email: ['foo@bar.com'], location: point }).then(user => {
        return User.find({ where: { username: user.username } });
      }).then(user => {
        expect(user.location).to.deep.eql(point);
      });
    });

    describe('[POSTGRES] Unquoted identifiers', () => {
      it('can insert and select', function() {
        this.sequelize.options.quoteIdentifiers = false;
        this.sequelize.getQueryInterface().QueryGenerator.options.quoteIdentifiers = false;

        this.User = this.sequelize.define('Userxs', {
          username: DataTypes.STRING,
          fullName: DataTypes.STRING // Note mixed case
        }, {
          quoteIdentifiers: false
        });

        return this.User.sync({ force: true }).then(() => {
          return this.User
            .create({ username: 'user', fullName: 'John Smith' })
            .then(user => {
              // We can insert into a table with non-quoted identifiers
              expect(user.id).to.exist;
              expect(user.id).not.to.be.null;
              expect(user.username).to.equal('user');
              expect(user.fullName).to.equal('John Smith');

              // We can query by non-quoted identifiers
              return this.User.find({
                where: { fullName: 'John Smith' }
              }).then(user2 => {
                // We can map values back to non-quoted identifiers
                expect(user2.id).to.equal(user.id);
                expect(user2.username).to.equal('user');
                expect(user2.fullName).to.equal('John Smith');

                // We can query and aggregate by non-quoted identifiers
                return this.User
                  .count({
                    where: { fullName: 'John Smith' }
                  })
                  .then(count => {
                    this.sequelize.options.quoteIndentifiers = true;
                    this.sequelize.getQueryInterface().QueryGenerator.options.quoteIdentifiers = true;
                    this.sequelize.options.logging = false;
                    expect(count).to.equal(1);
                  });
              });
            });
        });
      });

      it('can select nested include', function() {
        this.sequelize.options.quoteIdentifiers = false;
        this.sequelize.getQueryInterface().QueryGenerator.options.quoteIdentifiers = false;
        this.Professor = this.sequelize.define('Professor', {
          fullName: DataTypes.STRING
        }, {
          quoteIdentifiers: false
        });
        this.Class = this.sequelize.define('Class', {
          name: DataTypes.STRING
        }, {
          quoteIdentifiers: false
        });
        this.Student = this.sequelize.define('Student', {
          fullName: DataTypes.STRING
        }, {
          quoteIdentifiers: false
        });
        this.ClassStudent = this.sequelize.define('ClassStudent', {
        }, {
          quoteIdentifiers: false,
          tableName: 'class_student'
        });
        this.Professor.hasMany(this.Class);
        this.Class.belongsTo(this.Professor);
        this.Class.belongsToMany(this.Student, { through: this.ClassStudent });
        this.Student.belongsToMany(this.Class, { through: this.ClassStudent });
        return this.Professor.sync({ force: true })
          .then(() => {
            return this.Student.sync({ force: true });
          })
          .then(() => {
            return this.Class.sync({ force: true });
          })
          .then(() => {
            return this.ClassStudent.sync({ force: true });
          })
          .then(() => {
            return this.Professor.bulkCreate([
              {
                id: 1,
                fullName: 'Albus Dumbledore'
              },
              {
                id: 2,
                fullName: 'Severus Snape'
              }
            ]);
          })
          .then(() => {
            return this.Class.bulkCreate([
              {
                id: 1,
                name: 'Transfiguration',
                ProfessorId: 1
              },
              {
                id: 2,
                name: 'Potions',
                ProfessorId: 2
              },
              {
                id: 3,
                name: 'Defence Against the Dark Arts',
                ProfessorId: 2
              }
            ]);
          })
          .then(() => {
            return this.Student.bulkCreate([
              {
                id: 1,
                fullName: 'Harry Potter'
              },
              {
                id: 2,
                fullName: 'Ron Weasley'
              },
              {
                id: 3,
                fullName: 'Ginny Weasley'
              },
              {
                id: 4,
                fullName: 'Hermione Granger'
              }
            ]);
          })
          .then(() => {
            return Promise.all([
              this.Student.findById(1)
                .then(Harry => {
                  return Harry.setClasses([1, 2, 3]);
                }),
              this.Student.findById(2)
                .then(Ron => {
                  return Ron.setClasses([1, 2]);
                }),
              this.Student.findById(3)
                .then(Ginny => {
                  return Ginny.setClasses([2, 3]);
                }),
              this.Student.findById(4)
                .then(Hermione => {
                  return Hermione.setClasses([1, 2, 3]);
                })
            ]);
          })
          .then(() => {
            return this.Professor.findAll({
              include: [
                {
                  model: this.Class,
                  include: [
                    {
                      model: this.Student
                    }
                  ]
                }
              ],
              order: [
                ['id'],
                [this.Class, 'id'],
                [this.Class, this.Student, 'id']
              ]
            });
          })
          .then(professors => {
            expect(professors.length).to.eql(2);
            expect(professors[0].fullName).to.eql('Albus Dumbledore');
            expect(professors[0].Classes.length).to.eql(1);
            expect(professors[0].Classes[0].Students.length).to.eql(3);
          })
          .finally(() => {
            this.sequelize.getQueryInterface().QueryGenerator.options.quoteIdentifiers = true;
          });
      });
    });
  });
}


text:
mv ledger3.texi keep-ledger3.texi
rm ledger3.*
mv keep-ledger3.texi ledger3.texi


text: <?php echo "Logueo Necesario"; ?>


text:
#ifndef CallData_h
#define CallData_h

#include "JSValue.h"

namespace JSC {

    class ArgList;
    class ExecState;
    class FunctionExecutable;
    class JSObject;
    class ScopeChainNode;

    enum CallType {
        CallTypeNone,
        CallTypeHost,
        CallTypeJS
    };

    typedef EncodedJSValue (JSC_HOST_CALL *NativeFunction)(ExecState*);

    union CallData {
        struct {
            NativeFunction function;
        } native;
        struct {
            FunctionExecutable* functionExecutable;
            ScopeChainNode* scopeChain;
        } js;
    };

    JSValue call(ExecState*, JSValue functionObject, CallType, const CallData&, JSValue thisValue, const ArgList&);

} // namespace JSC

#endif // CallData_h


text:
import angular from 'angular';
import 'angular-route';
import 'angular-resource';
import 'angular-bootstrap';
import 'angular-ui-router';

import './directives';
import controllers from './controllers/index';
import services from './services/index';
import factories from './factories/index';
import compileProvider from './config/compileProvider';
import route from './config/route';

export const name = 'app';

angular.module('myApp',['ngRoute', 'ngResource', 'ui.bootstrap', 'ui.router', factories, services, controllers])
  .config(compileProvider)
  .config(route);


text:
#include <boost/asio.hpp>
#include <future>

#include "EmptyPort.hpp"
#include "TestServer.hpp"
#include "catch.hpp"

#include "bredis/Connection.hpp"
#include "bredis/MarkerHelpers.hpp"

#include "bredis/Extract.hpp"

#include "SocketWithLogging.hpp"

namespace r = bredis;
namespace asio = boost::asio;
namespace ep = empty_port;
namespace ts = test_server;

TEST_CASE("stream", "[connection]") {
    using socket_t = asio::ip::tcp::socket;
#ifdef BREDIS_DEBUG
    using next_layer_t = r::test::SocketWithLogging<socket_t>;
#else
    using next_layer_t = socket_t;
#endif
    using Buffer = boost::asio::streambuf;
    using Iterator = typename r::to_iterator<Buffer>::iterator_t;
    using Extractor = r::extractor<Iterator>;

    std::chrono::milliseconds sleep_delay(1);

    uint16_t port = ep::get_random<ep::Kind::TCP>();
    auto port_str = boost::lexical_cast<std::string>(port);
    auto server = ts::make_server({"redis-server", "--port", port_str});
    ep::wait_port<ep::Kind::TCP>(port);
    asio::io_context io_service;

    asio::ip::tcp::endpoint end_point(
        asio::ip::make_address("127.0.0.1"), port);
    socket_t socket(io_service, end_point.protocol());
    socket.connect(end_point);

    r::Connection<next_layer_t> c(std::move(socket));

    Buffer rx_buff;
    c.write(r::single_command_t{ "INFO" });
    auto parse_result0 = c.read(rx_buff);
    auto extract0 = boost::apply_visitor(Extractor(), parse_result0.result);
    auto info = boost::get<r::extracts::string_t>(extract0);
    rx_buff.consume(parse_result0.consumed);
    std::string version_str = "redis_version:5.";
    if (info.str.find("redis_version:5.") == std::string::npos) {
        /* not supported by earlier redis versions */
        return;
    }

    c.write(r::single_command_t{ "XADD", "mystream", "*", "cpu-temp", "23.4", "load", "2.3" });
    auto parse_result1 = c.read(rx_buff);
    auto extract1 = boost::apply_visitor(Extractor(), parse_result1.result);
    auto id1 = boost::get<r::extracts::string_t>(extract1);
    rx_buff.consume(parse_result1.consumed);

    c.write(r::single_command_t{ "XADD", "mystream", "*", "cpu-temp", "23.2", "load", "2.1" });
    auto parse_result2 = c.read(rx_buff);
    auto extract2 = boost::apply_visitor(Extractor(), parse_result2.result);
    auto id2 = boost::get<r::extracts::string_t>(extract2);
    rx_buff.consume(parse_result2.consumed);

    c.write(r::single_command_t{ "XRANGE" , "mystream",  id1.str, id2.str});
    auto parse_result3 = c.read(rx_buff);
    auto extract3 = boost::apply_visitor(Extractor(), parse_result3.result);
    rx_buff.consume(parse_result3.consumed);

    auto& outer_arr = boost::get<r::extracts::array_holder_t>(extract3);
    auto& inner_arr1 = boost::get<r::extracts::array_holder_t>(outer_arr.elements[0]);
    auto& inner_arr2 = boost::get<r::extracts::array_holder_t>(outer_arr.elements[1]);

    REQUIRE(boost::get<r::extracts::string_t>(inner_arr1.elements[0]).str == id1.str);
    auto& arr1 = boost::get<r::extracts::array_holder_t>(inner_arr1.elements[1]);
    REQUIRE(boost::get<r::extracts::string_t>(arr1.elements[0]).str == "cpu-temp");
    REQUIRE(boost::get<r::extracts::string_t>(arr1.elements[1]).str == "23.4");
    REQUIRE(boost::get<r::extracts::string_t>(arr1.elements[2]).str == "load");
    REQUIRE(boost::get<r::extracts::string_t>(arr1.elements[3]).str == "2.3");

    REQUIRE(boost::get<r::extracts::string_t>(inner_arr2.elements[0]).str == id2.str);
    auto& arr2 = boost::get<r::extracts::array_holder_t>(inner_arr2.elements[1]);
    REQUIRE(boost::get<r::extracts::string_t>(arr2.elements[0]).str == "cpu-temp");
    REQUIRE(boost::get<r::extracts::string_t>(arr2.elements[1]).str == "23.2");
    REQUIRE(boost::get<r::extracts::string_t>(arr2.elements[2]).str == "load");
    REQUIRE(boost::get<r::extracts::string_t>(arr2.elements[3]).str == "2.1");
}


text:
namespace org {
  namespace apache {
    namespace lucene {
      namespace util {
        class Version;
      }
    }
  }
}
namespace java {
  namespace lang {
    class Class;
  }
}
template<class T> class JArray;

namespace org {
  namespace apache {
    namespace lucene {
      namespace analysis {
        namespace core {

          class SimpleAnalyzer : public ::org::apache::lucene::analysis::Analyzer {
          public:
            enum {
              mid_init$_0d96cf33,
              mid_createComponents_1be39cae,
              max_mid
            };

            static ::java::lang::Class *class$;
            static jmethodID *mids$;
            static bool live$;
            static jclass initializeClass(bool);

            explicit SimpleAnalyzer(jobject obj) : ::org::apache::lucene::analysis::Analyzer(obj) {
              if (obj != NULL)
                env->getClass(initializeClass);
            }
            SimpleAnalyzer(const SimpleAnalyzer& obj) : ::org::apache::lucene::analysis::Analyzer(obj) {}

            SimpleAnalyzer(const ::org::apache::lucene::util::Version &);
          };
        }
      }
    }
  }
}

#include <Python.h>

namespace org {
  namespace apache {
    namespace lucene {
      namespace analysis {
        namespace core {
          extern PyTypeObject PY_TYPE(SimpleAnalyzer);

          class t_SimpleAnalyzer {
          public:
            PyObject_HEAD
            SimpleAnalyzer object;
            static PyObject *wrap_Object(const SimpleAnalyzer&);
            static PyObject *wrap_jobject(const jobject&);
            static void install(PyObject *module);
            static void initialize(PyObject *module);
          };
        }
      }
    }
  }
}

#endif


text:
/* jslint undef: true */
/* global window, document, $ */

/* ----------------------------------------------------------------
 * server.js
 *
 * Delegates routes to routes.js
 * ---------------------------------------------------------------- */

(function() {

	'use strict';

	/* ----------------------------------------------------------------
	 * Imports
	 * ---------------------------------------------------------------- */
	var http        = require('http');
	var fs          = require('fs');
	var mime        = require('mime');
	var path        = require('path');
	var crypto      = require('crypto');
	var handlebars  = require('handlebars');
	var querystring = require('querystring');
	var Cookies     = require('cookies');
	var serverUtils = require('./utils.js');
	var _           = require('underscore');
	var config      = require('../config.js');

	var getArray   = [];
	var postArray  = [];
	var allArray   = [];

	// Default middleware
	var middleware = {
		cookie : function(req, res) {
			var cookie = new Cookies(req, res, config.cookieSecret);
			req.cookie = cookie.get(config.cookieName);
			return {
				req : req,
				res : res
			};
		},
		query : function(req, res) {
			var result = false;
			var arr = req.url.split('/');
			var chunk = arr[arr.length-1];
			if(chunk[0] === '?') {
				chunk = chunk.substr(1);
				result = querystring.parse(chunk);
			}
			req.query = result;
			return {
				req : req,
				res : res
			};
		}
	};

	/* ----------------------------------------------------------------
	 * Utility functions
	 * ---------------------------------------------------------------- */
	function containsParam(url, truncate) {
		var arr = url.split('/');
		var text = arr[arr.length-1];

		if(text.indexOf(':') > -1) {
			if(truncate) {
				arr.pop();
				return arr.join('/') || '/';
			} else {
				return text.slice(1);
			}
		} else {
			return false;
		}
	}

	// Checks route, assigns request functions and middlewares
	function checkRoute(req, res, arr) {

		var routeFound = false;

		// Optimize the looping mechanism
		arr.map(function(data) {
			if(data.route === req.url && !data.param) {

				// adds middleware here
				data.middleware.map(function(mw) {
					var obj = middleware[mw](req, res);
					req = obj.req;
					res = obj.res;
				});
				data.callback(req, res);
				routeFound = true;
			}
			if(data.param && data.route === path.dirname(req.url) && !routeFound) {

				// adds middleware here
				data.middleware.map(function(mw) {
					var obj = middleware[mw](req, res);
					req = obj.req;
					res = obj.res;
				});
				req[data.param] = path.basename(req.url);
				data.callback(req, res);
				routeFound = true;
			}
		});

		return routeFound;
	}

	/*
	 * Exported utility functions
	 */
	var utils = {
		containsFile : function(url) {
			var arr = url.split('/');
			var text = arr[arr.length-1];

			if(text.indexOf('.') > -1) {
				return text;
			} else {
				return false;
			}
		},
		send404 : function(res) {
			res.writeHead(404, {
				'Content-Type' : 'text/html'
			});
			res.write('
404 Not found
');
			res.end();
		},
		send500 : function(res) {
			res.writeHead(500, {
				'Content-Type' : 'text/html'
			});
			res.write('
404 Not found
');
			res.end();
		},
		redirect : function(res, url, code) {
			code = code || 301;
			res.writeHead(code, {
				'Location' : url
			});
			res.end();
		},
		serveFile : function(filePath, res) {
			fs.exists(filePath, function(exists) {
				if(exists) {
					// Add optional ut8 parameter in function
					fs.readFile(filePath, /* 'utf8',*/ function(err, file) {
						if(file) {
							res.writeHead(200, {
								'Content-Type' : mime.lookup(filePath)
							});
							res.write(file, 'binary');
							res.end();
						} else {
							send500(res);
						}
					});
				} else {
					send404(res);
				}
			});
		},
		serveJson : function(obj, res, code) {
			code = code || 200;
			res.writeHead(code, {
				'Content-Type' : 'application/json'
			});
			res.write(JSON.stringify(obj));
			res.end();
		},
		parseQuery : function(req) {
			var result = false;
			var arr = req.url.split('/');
			var chunk = arr[arr.length-1];
			if(chunk[0] === '?') {
				chunk = chunk.substr(1);
				result = querystring.parse(chunk);
			}
			return result;
		}
	};

	/* ----------------------------------------------------------------
	 * Public functions
	 * ---------------------------------------------------------------- */
	module.exports = function() {

		/* The next four public functions add the callbacks, params, middlewares
		 * and routes inside the above arrays
		 */
		// Adds route functions for GET method
		function get(route, callback, middleware) {
			var obj = {};
			var param = containsParam(route);
			if(param) {
				obj.param      = param;
				obj.route      = containsParam(route, true);
			} else {
				obj.route = route;
			}
			obj.middleware = middleware || [];
			obj.callback   = callback;
			getArray.push(obj);
		}

		// Adds route functions for POST method
		function post(route, callback, middleware) {
			var obj = {};
			var param = containsParam(route);
			if(param) {
				obj.param = param;
				obj.route = containsParam(route, true);
			} else {
				obj.route = route;
			}
			obj.middleware = middleware || [];
			obj.callback   = callback;
			postArray.push(obj);
		}

		// Adds route functions for all methods
		function all(route, callback, middleware) {
			var obj = {};
			var param = containsParam(route);
			if(param) {
				obj.param = param;
				obj.route = containsParam(route, true);
			} else {
				obj.route = route;
			}
			obj.middleware = middleware || [];
			obj.callback   = callback;
			allArray.push(obj);
		}

		// Adds middleware
		function use(name, callback) {
			middleware[name] = callback;
		}

		// Main call to start the http server
		function start(port) {

			port = port || 80;
			http.createServer(function(req, res) {

				var routeFound = false;

				if(req.method === 'GET') {
					routeFound = checkRoute(req, res, getArray);
				} else if(req.method === 'POST') {
					routeFound = checkRoute(req, res, postArray);
				} else {
					routeFound = checkRoute(req, res, allArray);
				}

				/* Add 404 here */
				if(!routeFound) {
					res.end();
				}

			}).listen(port);
		}

	/* ----------------------------------------------------------------
	 * Exports
	 * ---------------------------------------------------------------- */
		return {
			get   : get,
			post  : post,
			all   : all,
			start : start,
			use   : use,
			utils : utils
		};
	};

})();


text:
{% extends "messages/base.html" %}
{% from "messages/includes/macros.html" import outbox_message with context %}
{% set title = _('Read Sent Message') %}
{% set crumbs = [(url('messages.inbox'), _('Messages')),
                 (url('messages.outbox'), _('Sent Messages')),
                 (None, title)] %}

{% block content %}

{{ title }}

      {{ outbox_message(message) }}

{% endblock %}