text:
void
Elaborator::overload(Overload& ovl, Decl* curr)
{
  // Check to make sure that curr does not conflict with any
  // declarations in the current overload set.
  for (Decl* prev : ovl) {
    // If the two declarations have the same type, this
    // is not overloading. It is redefinition.
    if (prev->type() == curr->type()) {
      std::stringstream ss;
      ss << "redefinition of " << *curr->name() << '\n';
      throw Type_error({}, ss.str());
    }

    if (!can_overload(prev, curr)) {
      std::stringstream ss;
      ss << "cannot overload " << *curr->name() << '\n';
      throw Type_error({}, ss.str());
    }
  }

  ovl.push_back(curr);
}

// Create a declarative binding for d. This also checks
// that the we are not redefining a symbol in the current
// scope.
void
Elaborator::declare(Decl* d)
{
  Scope& scope = stack.current();

  // Set d's declaration context.
  d->cxt_ = stack.context();

  // If we've already seen the name, we should
  // determine if it can be overloaded.
  if (Scope::Binding* bind = scope.lookup(d->name()))
    return overload(bind->second, d);

  // Create a new overload set.
  Scope::Binding& bind = scope.bind(d->name(), {});
  Overload& ovl = bind.second;
  ovl.push_back(d);
}

// When opening the scope of a previously declared
// entity, simply push the declaration into its
// overload set.
void
Elaborator::redeclare(Decl* d)
{
  Scope& scope = stack.current();
  Overload* ovl;
  if (Scope::Binding* bind = scope.lookup(d->name()))
    ovl = &bind->second;
  else
    ovl = &scope.bind(d->name(), {}).second;
  ovl->push_back(d);
}

// Perform lookup of an unqualified identifier. This
// will search enclosing scopes for the innermost
// binding of the identifier.
Overload*
Elaborator::unqualified_lookup(Symbol const* sym)
{
  if (Scope::Binding* bind = stack.lookup(sym))
    return &bind->second;
  else
    return nullptr;
}

// Perform a qualified lookup of a name in the given scope.
// This searches only that scope for a binding for the identifier.
// If the scope is that of a record, the name may be a member of
// a base class.
Overload*
Elaborator::qualified_lookup(Scope* s, Symbol const* sym)
{
  if (Record_decl* d = as<Record_decl>(s->decl))
    return member_lookup(d, sym);

  if (Scope::Binding* bind = s->lookup(sym))
    return &bind->second;

  return nullptr;
}

Overload*
Elaborator::member_lookup(Record_decl* d, Symbol const* sym)
{
  do {
    if (Scope::Binding* bind = d->scope()->lookup(sym))
      return &bind->second;
    d = d->base_declaration();
  } while (d);
  return nullptr;
}

// -------------------------------------------------------------------------- //
// Elaboration of types

inline bool
requires_definition(Type const* t)
{
  // A type T[n] requires a definition iff T requires
  // a definition.
  if (Array_type const* a = as<Array_type>(t))
    return requires_definition(a->type());

  // A user-defined type T requires a definition iff it
  // is not a reference or block type.
  if (is<Record_type>(t))
    return true;
  return false;
}

// Elaborate a type. If the type is requried to be a complete
// type then recursively elaborate it.
Type const*
Elaborator::elaborate_type(Type const* t)
{
  Type const* t1 = elaborate(t);
  if (requires_definition(t1))
    t1 = elaborate_def(t1);
  return t1;
}

Type const*
Elaborator::elaborate_def(Type const* t)
{
  if (Record_type const* r = as<Record_type>(t)) {
    elaborate_def(r->declaration());
    return t;
  }
  lingo_unreachable();
}

Type const*
Elaborator::elaborate(Type const* t)
{
  struct Fn
  {
    Elaborator& elab;

    Type const* operator()(Id_type const* t) { return elab.elaborate(t); }
    Type const* operator()(Boolean_type const* t) { return elab.elaborate(t); }
    Type const* operator()(Character_type const* t) { return elab.elaborate(t); }
    Type const* operator()(Integer_type const* t) { return elab.elaborate(t); }
    Type const* operator()(Float_type const* t) { return elab.elaborate(t); }
    Type const* operator()(Double_type const* t) { return elab.elaborate(t); }
    Type const* operator()(Function_type const* t) { return elab.elaborate(t); }
    Type const* operator()(Block_type const* t) { return elab.elaborate(t); }
    Type const* operator()(Array_type const* t) { return elab.elaborate(t); }
    Type const* operator()(Reference_type const* t) { return elab.elaborate(t); }
    Type const* operator()(Record_type const* t) { return elab.elaborate(t); }
  };
  return apply(t, Fn{*this});
}

// The elaboration of an identifer as a type performs
// unqualified name lookup. The declaration associated
// with the name shall be a user-defined type or an
// alias.
//
// TODO: Support type aliases.
Type const*
Elaborator::elaborate(Id_type const* t)
{
  // Perform unqualified lookup.
  Overload* ovl = unqualified_lookup(t->symbol());
  if (!ovl) {
    String msg = format("no matching declaration for '{}'", *t);
    throw Lookup_error(locate(t), msg);
  }

  // We can't currently overload types, so this could
  // only mean that we found a funtion overload set.
  if (ovl->size() > 1) {
    String msg = format("'{}' does not name a type", *t);
    throw Lookup_error(locate(t), msg);
  }

  // Determine if the name is a type declaration.
  Decl* d = ovl->front();
  if (Record_decl* r = as<Record_decl>(d))
    return get_record_type(r);

  String msg = format("'{}' does not name a type", *t);
  throw Lookup_error(locate(t), msg);
}

Type const*
Elaborator::elaborate(Boolean_type const* t)
{
  return t;
}

Type const*
Elaborator::elaborate(Character_type const* t)
{
  return t;
}

Type const*
Elaborator::elaborate(Integer_type const* t)
{
  return t;
}

Type const*
Elaborator::elaborate(Float_type const* t)
{
  return t;
}

Type const*
Elaborator::elaborate(Double_type const* t)
{
  return t;
}

// Elaborate each type in the function type.
Type const*
Elaborator::elaborate(Function_type const* t)
{
  Type_seq ts;
  ts.reserve(t->parameter_types().size());
  for (Type const* t1 : t->parameter_types()){

    // HERE! we are checking function paramters for
    // function type and elaborating them as references to function types instead
    if(is<Function_type>(t1)){
      Type const * tempType = elaborate(t1);
      ts.push_back(elaborate(tempType->ref()));
    }
    else{
      ts.push_back(elaborate(t1));
    }

  }
  Type const* r = elaborate(t->return_type());
  return get_function_type(ts, r);
}

Type const*
Elaborator::elaborate(Array_type const* t)
{
  Type const* t1 = elaborate(t->type());
  Expr* e = elaborate(t->extent());
  Expr* n = reduce(e);
  if (!n)
    throw Type_error({}, "non-constant array extent");
  return get_array_type(t1, n);
}

Type const*
Elaborator::elaborate(Block_type const* t)
{
  Type const* t1 = elaborate(t->type());
  return get_block_type(t1);
}

Type const*
Elaborator::elaborate(Reference_type const* t)
{
  Type const* t1 = elaborate(t->type());
  return get_reference_type(t1);
}

// No further elaboration is needed.
Type const*
Elaborator::elaborate(Record_type const* t)
{
  return t;
}

// -------------------------------------------------------------------------- //
// Elaboration of expressions

// Returns the type of an expression. This also annotates
// the expression by saving the computed type as part of
// the expression.
Expr*
Elaborator::elaborate(Expr* e)
{
  struct Fn
  {
    Elaborator& elab;

    Expr* operator()(Literal_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Id_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Decl_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Lambda_expr * e) const { return elab.elaborate(e); }
    Expr* operator()(Add_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Sub_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Mul_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Div_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Rem_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Neg_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Pos_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Eq_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Ne_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Lt_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Gt_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Le_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Ge_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(And_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Or_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Not_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Call_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Dot_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Field_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Method_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Index_expr* e) const { return elab.elaborate(e); }
    Expr* operator()(Value_conv* e) const { return elab.elaborate(e); }
    Expr* operator()(Block_conv* e) const { return elab.elaborate(e); }
    Expr* operator()(Base_conv* e) const { return elab.elaborate(e); }
    Expr* operator()(Promote_conv* e) const { return elab.elaborate(e); }
    Expr* operator()(Default_init* e) const { return elab.elaborate(e); }
    Expr* operator()(Trivial_init* e) const { return elab.elaborate(e); }
    Expr* operator()(Copy_init* e) const { return elab.elaborate(e); }
    Expr* operator()(Reference_init* e) const { return elab.elaborate(e); }
  };

  return apply(e, Fn{*this});
}

// Literal expressions are fully elaborated at the point
// of construction.
Expr*
Elaborator::elaborate(Literal_expr* e)
{
  return e;
}

// The elaboration of an identifier requires performs
// unqualified name lookup. The associated declaration
// shall not declare a type.
//
// If lookup associates a single declaration D, with
// declared type T, with the name, then the type of
// the expression is determined as follows:
//
//  - if D is an object, the  type of the expression
//    is T&;
//  - otherwise, then the type is T.
//
// Lookup may associate a set of declarations (an
// overload set). A single declaration is selected
// by overload resolution (see call expressions).
//
// TODO: Allow overload sets of templates?
Expr*
Elaborator::elaborate(Id_expr* e)
{
  Location loc = locate(e);

  // Lookup the declaration for the identifier.
  Overload* ovl = unqualified_lookup(e->symbol());
  if (!ovl) {
    std::stringstream ss;
    ss << "no matching declaration for '" << *e->symbol() << '\'';
    throw Lookup_error(locs.get(e), ss.str());
  }

  // We can't resolve an overload without context,
  // so return the resolved overload set.
  if (ovl->size() > 1) {
    Expr* ret = new Overload_expr(ovl);
    locate(ret, loc);
    return ret;
  }

  // Get the declaration named by the symbol.
  Decl* d = ovl->front();

  // An identifier always refers to an object, so
  // these expressions have reference type.
  Type const* t = d->type();
  if (is_object(d))
    t = t->ref();

  // Return a new expression.
  Expr* ret = new Decl_expr(t, d);
  locate(ret, loc);
  return ret;
}

// This deoes not require elaboration.
Expr*
Elaborator::elaborate(Decl_expr* e)
{
  return e;
}

Expr*
Elaborator::elaborate(Lambda_expr* e)
{
  // Create the new lambda expression.
  Function_decl* f_decl = new Function_decl(e->symbol(), e->type(), e->parameters(), e->body());
  elaborate_decl(f_decl);
  elaborate_def(f_decl);

  // Build the new lambda expression.
  Decl_expr* d_expr = new Decl_expr(f_decl->type()->ref(), f_decl);
  lambda_decls_[d_expr] = f_decl;
  return d_expr;
}

namespace
{

// Used to require the conversion of a reference to a
// value. Essentially, this unwraps the reference if
// needed.
Expr*
require_value(Elaborator& elab, Expr* e)
{
  e = elab.elaborate(e);
  e = convert_to_value(e);
  return e;
}

// Used to require the conversion of an expression
// to a given type. This returns nullptr if the convesion
// fails.
Expr*
require_converted(Elaborator& elab, Expr* e, Type const* t)
{
  Expr* e1 = elab.elaborate(e);
  Expr* e2 = convert(e1, t);
  return e2;
}

// The operands of a binary arithmetic expression are
// converted to rvalues. The converted operands shall have
// type int. The result of an arithmetic expression is an
// rvalue with type int.
template<typename T>
Expr*
check_binary_arithmetic_expr(Elaborator& elab, T* e)
{
  Type const* t = get_promotion_target(e->first, e->second);
  Expr* c1 = require_converted(elab, e->first, t);
  Expr* c2 = require_converted(elab, e->second, t);
  if (!c1)
    throw Type_error({}, "left operand cannot be converted");
  if (!c2)
    throw Type_error({}, "right operand cannot be converted");

  // Rebuild the expression with the
  // converted operands.
  e->type_ = t;
  e->first = c1;
  e->second = c2;
  return e;
}

// The operands of a unary arithmetic expression are
// converted to rvalues. The converted operands shall
// have type int. The result of an arithmetic expression
// is an rvalue of type int.
template<typename T>
Expr*
check_unary_arithmetic_expr(Elaborator& elab, T* e)
{
  // Apply conversions
  Type const* t = get_promotion_target(e->first);
  Expr* c = require_converted(elab, e->first, t);
  if (!c)
    throw Type_error({}, "operand cannot be converted");

  // Rebuild the expression with the converted operands.
  e->type_ = t;
  e->first = c;
  return e;
}

} // namespace

Expr*
Elaborator::elaborate(Add_expr* e)
{
  return check_binary_arithmetic_expr(*this, e);
}

Expr*
Elaborator::elaborate(Sub_expr* e)
{
  return check_binary_arithmetic_expr(*this, e);
}

Expr*
Elaborator::elaborate(Mul_expr* e)
{
  return check_binary_arithmetic_expr(*this, e);
}

Expr*
Elaborator::elaborate(Div_expr* e)
{
  return check_binary_arithmetic_expr(*this, e);
}

Expr*
Elaborator::elaborate(Rem_expr* e)
{
  return check_binary_arithmetic_expr(*this, e);
}

//
Expr*
Elaborator::elaborate(Neg_expr* e)
{
  return check_unary_arithmetic_expr(*this, e);
}

Expr*
Elaborator::elaborate(Pos_expr* e)
{
  return check_unary_arithmetic_expr(*this, e);
}

namespace
{

// The operands of an equality expression are converted
// to rvalues. The operands shall have the same type. The
// result of an equality expression is an rvalue of type
// bool.
//
// TODO: Update equality comparison for new types.
Expr*
check_equality_expr(Elaborator& elab, Binary_expr* e)
{
  // Apply conversions.
  Type const* b = get_boolean_type();
  Expr* e1 = require_value(elab, e->first);
  Expr* e2 = require_value(elab, e->second);

  // Check types.
  if (e1->type() != e2->type())
    throw Type_error({}, "operands have different types");

  e->type_ = b;
  e->first = e1;
  e->second = e2;
  return e;
}

} // naespace

Expr*
Elaborator::elaborate(Eq_expr* e)
{
  return check_equality_expr(*this, e);
}

Expr*
Elaborator::elaborate(Ne_expr* e)
{
  return check_equality_expr(*this, e);
}

namespace
{

// The operands of an ordering expression are converted
// to rvalues. The operands shall have type int. The
// result of an equality expression is an rvalue of type
// bool.
//
// TODO: Update the ordering operands for new types.
Expr*
check_ordering_expr(Elaborator& elab, Binary_expr* e)
{
  // Apply conversions.
  Type const* t = get_promotion_target(e->first, e->second);
  Type const* b = get_boolean_type();
  Expr* c1 = require_converted(elab, e->first, t);
  Expr* c2 = require_converted(elab, e->second, t);
  if (!c1)
    throw Type_error({}, "left operand cannot be converted");
  if (!c2)
    throw Type_error({}, "right operand cannot be converted");

  // Rebuild the expression with the converted
  // operands.
  e->type_ = b;
  e->first = c1;
  e->second = c2;
  return e;
}

} // naespace

Expr*
Elaborator::elaborate(Lt_expr* e)
{
  return check_ordering_expr(*this, e);
}

Expr*
Elaborator::elaborate(Gt_expr* e)
{
  return check_ordering_expr(*this, e);
}

Expr*
Elaborator::elaborate(Le_expr* e)
{
  return check_ordering_expr(*this, e);
}

Expr*
Elaborator::elaborate(Ge_expr* e)
{
  return check_ordering_expr(*this, e);
}

namespace
{

// TODO: Document me!
Expr*
check_binary_logical_expr(Elaborator& elab, Binary_expr* e)
{
  // Apply conversions.
  Type const* b = get_boolean_type();
  Expr* c1 = require_converted(elab, e->first, b);
  Expr* c2 = require_converted(elab, e->second, b);
  if (!c1)
    throw Type_error({}, "left operand cannot be converted to 'bool'");
  if (!c2)
    throw Type_error({}, "right operand cannot be converted to 'bool'");

  // Rebuild the expression with the converted
  // operands.
  e->type_ = b;
  e->first = c1;
  e->second = c2;
  return e;
}

// TODO: Document me!
Expr*
check_unary_logical_expr(Elaborator& elab, Unary_expr* e)
{
  Type const* b = get_boolean_type();
  Expr* c = require_converted(elab, e->first, b);
  if (!c)
    throw Type_error({}, "operand cannot be converted to 'bool'");

  // Rebuild the expression with the converted
  // operand.
  e->type_ = b;
  e->first = c;
  return e;
}

} // namespace

Expr*
Elaborator::elaborate(And_expr* e)
{
  return check_binary_logical_expr(*this, e);
}

Expr*
Elaborator::elaborate(Or_expr* e)
{
  return check_binary_logical_expr(*this, e);
}

Expr*
Elaborator::elaborate(Not_expr* e)
{
  return check_unary_logical_expr(*this, e);
}

// Diagnose failures of argument conversion for
// function calls.
void
Elaborator::on_call_error(Expr_seq const& conv,
                          Expr_seq const& args,
                          Type_seq const& parms)
{
  if (args.size() < parms.size())
    throw Type_error({}, "too few arguments");
  if (parms.size() < args.size())
    throw Type_error({}, "too many arguments");

  for (std::size_t i = 0; i < parms.size(); ++i) {
    Expr const* c = conv[i];
    if (!c) {
      Expr const* a = args[i];
      Type const* p = parms[i];
      String s = format(
        "type mismatch in argument {} (expected {} but got {})",
        i + 1,
        *a->type(),
        *p);

      // FIXME: Don't fail on the first error.
      throw Type_error({}, s);
    }
  }
}

namespace
{

// Returns a dot-expr if e is of the form x.ovl.
// Otherwise, returns nullptr.
inline Dot_expr*
as_method_overload(Dot_expr* e)
{
  if (is<Overload_expr>(e->member()))
    return e;
  return nullptr;
}

inline Dot_expr*
as_method_overload(Expr* e)
{
  if (Dot_expr* dot = as<Dot_expr>(e))
    return as_method_overload(dot);
  return nullptr;
}

// Returns a dot-expr if e is of the form x.m or
// x.ovl. Otherwise, returns nullptr.
inline Dot_expr*
as_method(Expr* e)
{
  if (Dot_expr* dot = as<Dot_expr>(e)) {
    // x.y refers to a method.
    if (Method_expr* m = as<Method_expr>(dot))
      return m;

    // x.y refers to a field.
    if (is<Field_expr>(dot))
      return nullptr;

    // By elimination of cases, it must be a
    // method overload.
    lingo_assert(as_method_overload(dot));
    return dot;
  }
  return nullptr;
}

} // namespace

Expr*
Elaborator::call(Function_decl* d, Expr_seq const& args)
{
  Function_type const* t = d->type();

  // Perform argument conversion.
  Type_seq const& parms = t->parameter_types();
  Expr_seq conv = convert(args, parms);
  if (std::any_of(conv.begin(), conv.end(), [](Expr const* p) { return !p; }))
    return nullptr;

  // Update the expression with the return type
  // of the named function.
  Expr* ref = new Decl_expr(t, d);
  return new Call_expr(t->return_type(), ref, conv);
}

Expr*
Elaborator::resolve(Overload_expr* ovl, Expr_seq const& args)
{
  // Build a set of call expressions to the
  // declarations in the overload set.
  Expr_seq cands;
  Overload& decls = ovl->declarations();
  cands.reserve(decls.size());
  for (Decl* d : decls) {
    if (Expr* e = call(cast<Function_decl>(d), args))
      cands.push_back(e);
  }

  // FIXME: If the call is to a method, then write
  // out the method format for the call. Same as below.
  if (cands.empty()) {
    Location loc = locate(ovl);
    String msg = format("{}: no matching function for '{}'", loc, *ovl->name());
    std::cerr << msg << '\n';
    std::cerr << loc << ": candidates are:\n";
    for (Decl* d : decls) {
      std::cerr << format("{}: {}\n", locate(d), *d);
    }
    throw Type_error(locate(ovl), msg);
  }

  // TODO: Select the best candidate.
  if (cands.size() > 1) {
    String msg = format("call to function '{}' is ambiguous", *ovl->name());
  }

  return cands.front();
}

// Resolve a function call. The target of a function
// may be one of the following:
//
//    - a function f(args...)
//    - a function overload set ovl(args...)
//    - a method x.m(args...)
//    - a method overload set x.ovl(args...)
//
// In the case where the target is a method or
// member overload set of the form x.y(args...)
// the containing object x is added to the front
// of the argument list, and the funtion target
// is simply the method or overlaod set. That is,
// the following transformation is made:
//
//    x.y(args...) ~> y(x.args...)
//
// Let y be the new function target.
//
// If the function target is an overload set, select
// a function by overload resolution.
//
// TODO: If we support function objects by way of
// overloading the call operator, then the target
// could be an object or field of class type with
// one or more member call operators.
//
// TODO: Would it be better to differentiate
// function and method call and have those dealt
// with separately on the back end(s)?
//
// TODO: Support the lookup of member funtions using
// free-function notation:
//
//    f(x, args...) ~> x.f(args...)
//
// Applying this transformation might just entail
// the creation of a fake expression and its elaboration
// to resolve a method or overload set.
Expr*
Elaborator::elaborate(Call_expr* e)
{

  // Apply lvalue to rvalue conversion and ensure that
  // the target (ultimately) has function type.
  Expr* f = require_value(*this, e->target());
  if (!is_callable(f))
    throw Type_error({}, "object is not callable");

  // Elaborate the arguments (in place) prior to
  // conversion. Do it now so we don't re-elaborate
  // arguments during overload resolution.
  Expr_seq& args = e->arguments();
  for (Expr*& a : args)
    a = elaborate(a);

  // If the target is of the form x.m or x.ovl, insert x
  // into the argument list and update the function target.
  if (Dot_expr* dot = as_method(f)) {
      // Build the "this" argument.
      //Method_expr* m = dynamic_cast<Method_expr*>(dot);

      Expr* self = dot->container();

      //Expr* self = m->container();
      args.insert(args.begin(), self);

    // Adjust the function target.
    f = dot->member();
  }

  // Handle the case where f is an overload set.
  if (Overload_expr* ovl = as<Overload_expr>(f)) {
    return resolve(ovl, args);
  } else {
    // If it's not an overload set, it has function type.
    Function_type const* t = cast<Function_type>(f->type());

    // Perform argument conversion.
    Type_seq const& parms = t->parameter_types();
    Expr_seq conv = convert(args, parms);
    if (std::any_of(conv.begin(), conv.end(), [](Expr const* p) { return !p; }))
      on_call_error(conv, args, parms);

    // Check for value conversion nodes
    // This is the case for lambda initialized variables and parameters
    if(is<Value_conv>(f)){
      f = cast<Value_conv>(f)->first;
      auto decl = cast<Decl_expr>(f)->declaration();
      if(auto var = as<Variable_decl>(decl)) {
        auto f_decl = cast<Reference_init>(var->init())->first;
        f = f_decl;
      }
    }
    // Update the expression with the return type
    // of the named function.
    e->type_ = t->return_type();
    e->first = f;
    e->second = conv;
  }

  // Guarantee that f is an expression that refers
  // to a declaration.
  //lingo_assert(is<Decl_expr>(f) &&
  //              is<Function_decl>(cast<Decl_expr>(f)->declaration()));

  // Update the call expression before returning.
  return e;
}

namespace
{

// Search the base classes for the given field.
//
// TODO: Support multiple base classes.
void
get_path(Record_decl* r, Field_decl* f, Field_path& p)
{
  // Search the record for the given fields.
  Decl_seq const& fs = r->fields();
  auto iter = std::find(fs.begin(), fs.end(), f);
  if (iter != fs.end()) {
    // Compute the offset adjustment for this member.
    // A virtual table reference counts as a subobject, and
    // so does a base class sub-object.
    int a = 0;
    if (r->vref())
      ++a;
    if (r->base())
      ++a;
    p.push_back(std::distance(fs.begin(), iter) + a);
    return;
  }

  // Recursively search the base class.
  if (r->base()) {
    p.push_back(0);
    get_path(r->base()->declaration(), f, p);
  }
}

// Construct a sequence of indexes through the record and
// up to the given field. The resulting path shall be
// a non-empty sequence of indexes.
Field_path
get_path(Record_decl* r, Field_decl* f)
{
  Field_path p;
  get_path(r, f, p);
  lingo_assert(!p.empty());
  return p;
}

//Method_path
//get_path(Record_decl* r, Method_decl* m){
//  Method_path p;
//  get_path(r, m, p);
//  lingo_assert(!p.empty());
//  return p;
//}

} // namespace

// TODO: Document the semantics of member access.
Expr*
Elaborator::elaborate(Dot_expr* e)
{
  Expr* e1 = elaborate(e->container());
  if (!is<Reference_type>(e1->type())) {
    std::stringstream ss;
    ss << "cannot access a member of a non-object";
    throw Type_error({}, ss.str());
  }

  // Get the non-reference type of the outer object
  // so we can perform qualified lookup.
  //
  // TODO: If we support modules, we would need to allow
  // for different kinds of scopes here.
  Record_type const* t1 = as<Record_type>(e1->type()->nonref());
  if (!t1) {
    std::stringstream ss;
    ss << "object does not have record type";
    throw Type_error({}, ss.str());
  }
  Scope* s = t1->declaration()->scope();

  // We expect the member to be an unresolved id expression.
  // If it isn't, there's not much we can do with it.
  //
  // TODO: Maybe allow a literal value in this position
  // to support tuple access?
  //
  //    t.0 -- get the first tuple element?
  Expr* e2 = e->member();
  if (!is<Id_expr>(e2)) {
    String msg = format("invalid member '{}'", *e2);
    throw Type_error(locate(e2), msg);
  }
  Id_expr* id = cast<Id_expr>(e2);

  // Perform qualified lookup on the member.
  Overload* ovl = qualified_lookup(s, id->symbol());
  if (!ovl) {
    String msg = format("no member matching '{}'", *id);
    throw Lookup_error(locate(id), msg);
  }

  // If we get a single declaration, return a corresponding
  // expression.
  if (ovl->size() == 1) {
    Decl*d = ovl->front();
    e2 = new Decl_expr(d->type(), d);
    if (Field_decl* f = as<Field_decl>(d)) {
      Type const* t2 = e2->type()->ref();
      Field_path p = get_path(t1->declaration(), f);
      return new Field_expr(t2, e1, e2, f, p);
    }
    if (Method_decl* m = as<Method_decl>(d)) {
      return new Method_expr(e1, e2, m);
    }
  }

  // Otherwise, if the name resolves to a set of declarations,
  // then the declaration is still unresolved. Update the
  // expression with the overload set and defer until we find
  // a function call.
  else {
    e->first = e1;
    e->second = new Overload_expr(ovl);
    return e;
  }

  // Otherwise, this is an error.
  std::stringstream ss;
  ss << "invalid member reference";
  throw Type_error({}, ss.str());
}

Expr*
Elaborator::elaborate(Field_expr* e)
{
  return e;
}

Expr*
Elaborator::elaborate(Method_expr* e)
{
  return e;
}

// In the expression e1[e2], e1 shall be an object of
// array type T[N] (for some N) or block type T[]. The
// expression e2 shall be an integer value. The result
// type of the expressions is ref T.
//
// Note that e1 is not converted to a value, and in fact
// *must* be a reference to an object. Converting to a
// value will prevent me from creating element pointers
// in code gen, because we need the base pointer from
// which to compute offsets.
Expr*
Elaborator::elaborate(Index_expr* e)
{
  Expr* e1 = elaborate(e->first);
  if (!is<Reference_type>(e1->type())) {
    std::stringstream ss;
    ss << "cannot index into a value";
    throw Type_error({}, ss.str());
  }

  // Get the non-reference type of the array.
  //
  // FIXME: Does this require a value transformation?
  // We don't (yet?) have array literals, so I generally
  // expect that this *must* be a reference to an array.
  //
  // TODO: Allow block type.
  Array_type const* t = as<Array_type>(e1->type()->nonref());
  if (!t) {
    std::stringstream ss;
    ss << "object does not have array type";
    throw Type_error({}, ss.str());
  }

  // The index shall be an integer value.
  Expr* e2 = require_converted(*this, e->second, get_integer_type());

  // The result type shall be ref T.
  e->type_ = get_reference_type(t->type());
  e->first = e1;
  e->second = e2;

  return e;
}

// NOTE: Conversions are created after their source
// expressions  have been elaborated. No action is
// required.

Expr*
Elaborator::elaborate(Value_conv* e)
{
  return e;
}

Expr*
Elaborator::elaborate(Block_conv* e)
{
  return e;
}

Expr*
Elaborator::elaborate(Base_conv* e)
{
  return e;
}

Expr*
Elaborator::elaborate(Promote_conv* e)
{
  return e;
}

// TODO: I probably need to elaborate the type.
Expr*
Elaborator::elaborate(Default_init* e)
{
  e->type_ = elaborate(e->type_);
  return e;
}

Expr*
Elaborator::elaborate(Trivial_init* e)
{
  e->type_ = elaborate(e->type_);
  return e;
}

Expr*
Elaborator::elaborate(Copy_init* e)
{
  // Elaborate the type.
  e->type_ = elaborate(e->type_);

  // If copying into a reference, we're actually
  // performing reference initialization. Create
  // a new node and elaborate it.
  if (is<Reference_type>(e->type())) {
    Reference_init* init = new Reference_init(e->type(), e->value());
    return elaborate(init);
  }

  // Otherwise, this actually a copy.
  //
  // TOOD: This should perform a lookup to find a
  // function that implements copies. It could be
  // bitwise copy, a memberwise copy, or a copy
  // constructor.

  // Convert the value to the resulting type.
  Expr* c = require_converted(*this, e->first, e->type_);
  if (!c) {
    std::stringstream ss;
    ss << "type mismatch in copy initializer (expected "
       << *e->type() << " but got " << *e->value()->type() << ')';
    throw Type_error({}, ss.str());
  }
  e->first = c;

  return e;
}

// Note that this is only ever called from the
// elaborator for copy initialization. The type must
// already be elaborated.
Expr*
Elaborator::elaborate(Reference_init* e)
{
  Expr* obj = elaborate(e->object());

  // A reference can only be bound to an object.
  if (!is<Reference_type>(obj->type())) {
    throw Type_error({}, "binding reference to temporary");
  }

  // TODO: Allow t2 to be derived from t1.
  //
  //    struct B { };
  //    struct D : B { };
  //
  //    var obj : D;
  //    var ref : B& = obj;
  //
  // TODO: Allow t2 to be less cv qualified than t1.
  // That would allow bindings to constants:
  //
  //    var T x;
  //    var T const& c = x;
  Type const* t1 = e->type();
  Type const* t2 = obj->type();
  if (t1->nonref() != t2->nonref()) {
    std::stringstream ss;
    ss << "binding reference to an object of a different type"
       << "(expected " << *t1 << " but got " << *t2 << ')';
    throw Type_error({}, ss.str());
  }

  // Update the expression.
  e->first = obj;

  return e;
}

// -------------------------------------------------------------------------- //
// Elaboration of declarations

// Elaborate a declaration. This returns true if
// elaboration succeeds and false otherwise.
Decl*
Elaborator::elaborate(Decl* d)
{
  struct Fn
  {
    Elaborator& elab;
    Decl* operator()(Variable_decl* d) const { return elab.elaborate(d); }
    Decl* operator()(Function_decl* d) const { return elab.elaborate(d); }
    Decl* operator()(Parameter_decl* d) const { return elab.elaborate(d); }
    Decl* operator()(Record_decl* d) const { return elab.elaborate(d); }
    Decl* operator()(Field_decl* d) const { return elab.elaborate(d); }
    Decl* operator()(Method_decl* d) const { return elab.elaborate(d); }
    Decl* operator()(Module_decl* d) const { return elab.elaborate(d); }
  };

  return apply(d, Fn{*this});
}

// The type of the initializer shall match the declared type
// of the variable.
//
// The variable is declared prior to the elaboration of its
// initializer.
Decl*
Elaborator::elaborate(Variable_decl* d)
{
  d->type_ = elaborate_type(d->type_);

  if(is<Function_type>(d->type_))
  {
    d->type_ = d->type_->ref();
    cast<Init>(d->init_)->type_ = d->type_;
  }
  // Declare the variable.
  declare(d);

  // Elaborate the initializer. Note that the initializers
  // type must be the same as that of the declaration.
  d->init_ = elaborate(d->init());

  // Annotate the initializer with the declared
  // object.
  //
  // TODO: This will probably be an expression in
  // the future.
  cast<Init>(d->init())->decl_ = d;

  return d;
}

// The types of return expressions shall match the declared
// return type of the function.
Decl*
Elaborator::elaborate(Function_decl* d)
{
  throw Type_error(locate(d), "function declaration in block scope");
}

// Elaborate a parameter declaration. This simply declares
// the parameter in the current scope.
Decl*
Elaborator::elaborate(Parameter_decl* d)
{
  d->type_ = elaborate_type(d->type_);
  // Check for function type and set to reference to function type
  if(is<Function_type>(d->type_))
    d->type_ = d->type_->ref();

  declare(d);

  Function_decl* fn = stack.function();

  // Check for virtual parameters. A parameter can only be
  // declared virtual if t has polymorphic type (or is a reference
  // to an object of polymorphic type).
  if (d->is_virtual()) {
    Type const* t0 = d->type()->nonref();
    if (!is<Record_type>(t0))
      throw Type_error(locate(d), "type of virtual parameter is not a record type");
    Record_type const* t1 = cast<Record_type>(t0);
    Record_decl const* rec = t1->declaration();
    if (!rec->is_polymorphic())
      throw Type_error(locate(d), "type of virtual parameter is not polymorphic");

    // Mark the function as being virtual.
    fn->spec_ |= virtual_spec;

    // Save virtual parameter.
    //
    // TODO: What are we actually going to do with
    // this thing?
    if (!fn->vparms_)
      fn->vparms_ = new Decl_seq {d};
    else
      fn->vparms_->push_back(d);
  }

  return d;
}

// FIXME: Allow records in block scope?
Decl*
Elaborator::elaborate(Record_decl* d)
{
  throw Type_error(locate(d), "record declaration in block scope");
}

// There is no single pass elaborator for fields.
Decl*
Elaborator::elaborate(Field_decl* d)
{
  lingo_unreachable();
}

// There is no single pass elaborator for methods.
Decl*
Elaborator::elaborate(Method_decl* d)
{
  lingo_unreachable();
}

// Elaborate the module. Modules use a two phase
// lookup mechanism.
Decl*
Elaborator::elaborate(Module_decl* m)
{
  Scope_sentinel scope(*this, m);
  for (Decl*& d : m->decls_)
    d = elaborate_decl(d);
  for (Decl*& d : m->decls_)
    d = elaborate_def(d);

  for(auto && a : lambda_decls_)
    m->decls_.insert(m->decls_.begin(), a.second);

  return m;

}

// -------------------------------------------------------------------------- //
// Elaboration of declarations (but not definitions)

namespace
{

// Defined here because of the member template.
struct Elab_decl_fn
{
  Elaborator& elab;
  Decl* operator()(Variable_decl* d) const { return elab.elaborate_decl(d); }
  Decl* operator()(Function_decl* d) const { return elab.elaborate_decl(d); }
  Decl* operator()(Parameter_decl* d) const { return elab.elaborate_decl(d); }
  Decl* operator()(Record_decl* d) const { return elab.elaborate_decl(d); }
  Decl* operator()(Field_decl* d) const { return elab.elaborate_decl(d); }
  Decl* operator()(Method_decl* d) const { return elab.elaborate_decl(d); }
  Decl* operator()(Module_decl* d) const { return elab.elaborate_decl(d); }
};

} // namespace

Decl*
Elaborator::elaborate_decl(Decl* d)
{
  return apply(d, Elab_decl_fn{*this});
}

Decl*
Elaborator::elaborate_decl(Variable_decl* d)
{
  if(is<Function_type>(d->type_))
  {
    d->type_ = d->type()->ref();
  }
  d->type_ = elaborate_type(d->type_);
  declare(d);
  return d;
}

Decl*
Elaborator::elaborate_decl(Function_decl* d)
{
  d->type_ = elaborate_type(d->type_);
  declare(d);

  // Remember if we've seen a function named main().
  //
  // FIXME: This seems dumb. Is there a better way
  // of handling the discovery and elaboration of
  // main?
  if (d->name() == syms.get("main")) {
    main = d;

    // Ensure that main has foreign linkage.
    d->spec_ |= foreign_spec;

    // TODO: Check that main conforms to the
    // expected return type and arguments.
  }

  return d;
}

Decl*
Elaborator::elaborate_decl(Parameter_decl* d)
{
  lingo_unreachable();
}

Decl*
Elaborator::elaborate_decl(Field_decl* d)
{
  d->type_ = elaborate_type(d->type_);
  declare(d);
  return d;
}

Decl*
Elaborator::elaborate_decl(Record_decl* d)
{
  declare(d);
  return d;
}

namespace
{

// Returns true if m1 is an override of m2. This is the
// case when m1 has the same name and type as m2.
//
// TODO: Allow for covariant return types.
//
// TODO: Consider allowing contravariant argument types?
bool
is_override(Method_decl const* m1, Method_decl const* m2)
{
  // Different name? Not an overrider.
  if (m1->name() != m2->name())
    return false;

  // Different return types? Not an overrider.
  //
  // TODO: Support covariant return types here.
  Function_type const* t1 = m1->type();
  Function_type const* t2 = m2->type();
  if (t1->return_type() != t2->return_type())
    return false;

  // Compare all parameter types except the implicit this
  // parameter. Those differ by definition (m1's this is
  // derived from m2's this).
  Type_seq const& p1 = m1->type()->parameter_types();
  Type_seq const& p2 = m2->type()->parameter_types();
  if (p1.size() != p2.size())
    return false;
  for (std::size_t i = 1; i < p1.size(); ++i) {
    // TODO: Support covariant return types here.
    if (p1[i] != p2[i])
      return false;
  }
  return true;
}

// Find the method in d that m overrides anmd return the
// offset in the virtual table. If the record is not polymorphic
// then this cannot be an overrider.
int
find_override(Record_decl const* d, Method_decl const* m)
{
  Decl_seq const& ms = *d->vtable();
  auto iter = std::find_if(ms.begin(), ms.end(), [m](Decl const* m2) {
    return is_override(m, cast<Method_decl>(m2));
  });
  if (iter != ms.end())
    return std::distance(ms.begin(), iter);
  else
    return -1;
}

} // namespace

// Insert the implicit this parameter and adjust the
// type of the declaration.
Decl*
Elaborator::elaborate_decl(Method_decl* d)
{
  Record_decl* rec = stack.record();
  Decl_seq* vtable = rec->vtable();

  // Generate the type of the implicit this parameter.
  //
  // TODO: Handle constant references.
  Type const* type = get_reference_type(get_record_type(rec));

  // Re-build the function type.
  //
  // TODO: Factor this out as an operation on a method.
  Function_type const* ft = cast<Function_type>(elaborate(d->type()));
  Type_seq pt = ft->parameter_types();
  pt.insert(pt.begin(), type);
  Type const* rt = ft->return_type();
  Type const* mt = get_function_type(pt, rt);
  d->type_ = mt;

  // Actually build the implicit this parameter and add it
  // to the front of the list of parameters.
  Symbol const* name = syms.get("this");
  Parameter_decl* self = new Parameter_decl(name, type);
  d->parms_.insert(d->parms_.begin(), self);

  // Propagate virtual/abstract specifiers to the class.
  // Build a new virtual table as needed.
  if (d->is_virtual())
    rec->spec_ |= virtual_spec;
  if (d->is_abstract())
    rec->spec_ |= abstract_spec;
  if (rec->is_polymorphic() && !vtable)
    rec->vtbl_ = vtable = new Decl_seq();

  // This function may be an override of a previous
  // virtual function -- even if it wasn't declared as
  // such. Propagate flags from an overrider if there
  // was one.
  if (vtable) {
    int ent = find_override(rec, d);
    if (ent >= 0) {
      // Update the method (and class) with the state
      // from the overrider.
      //
      // TODO: Actually save the overriden function with
      // the current declaration?
      //
      // TODO: Can I declare an abstract overrider?
      Method_decl const* m = cast<Method_decl>((*vtable)[ent]);
      if (m->is_polymorphic()) {
        d->spec_ |= virtual_spec;
        rec->spec_ |= virtual_spec;
      }

      // Overwrite the overrider in the vtable.
      (*vtable)[ent] = d;
    } else {
      // Extend the virtual table.
      ent = vtable->size();
      vtable->push_back(d);
    }
    d->vtent_ = ent;
  }

  // Note that we don't need to elaborate or declare
  // the funciton parameters because they're only visible
  // within the function body (see the def elaborator for
  // function definitions).

  // Now declare the method.
  declare(d);

  return d;
}

// Since modules aren't nested, we should never get here.
Decl*
Elaborator::elaborate_decl(Module_decl* d)
{
  lingo_unreachable();
}

// -------------------------------------------------------------------------- //
// Elaboration of definitions

namespace
{

// Defined here because of the member template.
struct Elab_def_fn
{
  Elaborator& elab;
  Decl* operator()(Variable_decl* d) const { return elab.elaborate_def(d); }
  Decl* operator()(Function_decl* d) const { return elab.elaborate_def(d); }
  Decl* operator()(Parameter_decl* d) const { return elab.elaborate_def(d); }
  Decl* operator()(Record_decl* d) const { return elab.elaborate_def(d); }
  Decl* operator()(Field_decl* d) const { return elab.elaborate_def(d); }
  Decl* operator()(Method_decl* d) const { return elab.elaborate_def(d); }
  Decl* operator()(Module_decl* d) const { return elab.elaborate_def(d); }
};

} // namespace

Decl*
Elaborator::elaborate_def(Decl* d)
{
  return apply(d, Elab_def_fn{*this});
}

Decl*
Elaborator::elaborate_def(Variable_decl* d)
{
  // Elaborate the initializer.
  d->init_ = elaborate(d->init());

  // Annotate the initializer with the declared
  // object.
  //
  // FIXME: This needs to be rethought.
  cast<Init>(d->init())->decl_ = d;
  return d;
}

Decl*
Elaborator::elaborate_def(Function_decl* d)
{
  // Enter the function scope and declare all of
  // the parameters (by way of elaboration).
  //
  // Note that this modifies the original parameters.
  Scope_sentinel scope(*this, d);

  for (Decl*& p : d->parms_)
  {
    p = elaborate(p);
  }

  // Check the body of the function, if present.
  if (d->body())
    d->body_ = elaborate(d->body());

  // TODO: Are we actually checking returns match
  // the return type?

  // TODO: Build a control flow graph and ensure that
  // every branch returns a value.
  return d;
}

Decl*
Elaborator::elaborate_def(Parameter_decl* d)
{
  lingo_unreachable();
}

// Returns true if we are currently defining the declaration d.
// That is te case when the declaraiton appears in the decl
// stack.
bool
Elaborator::is_defining(Decl const* d) const
{
  return count(defining.begin(), defining.end(), d);
}

// FIXME: If the type of a member variable requires the
// definition of a user-defined type, then we need to
// recursively elaborate that. However, we need to be
// careful that we don't generate cycles.
Decl*
Elaborator::elaborate_def(Record_decl* d)
{
  // If the declaration has already been declared,
  // then don't re-elaborate it.
  if (defined.count(d))
    return d;

  // Prevent recursive type definitions.
  if (is_defining(d)) {
    std::cerr << format("cyclic definition of '{}'\n", *d->name());
    for (auto iter = defining.rbegin(); iter != defining.rend(); ++iter) {
      if (*iter == d)
        break;
      std::cerr << format("  referenced in the definition of '{}'\n", *(*iter)->name());
    }
    throw Type_error(locate(d), format("cyclic definition of '{}'", *d->name()));
  }
  Defining_sentinel def(*this, d);

  // Elaborate base class.
  if (d->base_)
    d->base_ = elaborate(d->base_);

  // If the base class is polymorphic, then so is the
  // derived class. Propagate the virtual table to this
  // class.
  //
  // FIXME: A derived class is abstract only if it fails
  // to provide overriders for each all abstract methods.
  // Think of a better way for this to work.
  Record_decl const* base = d->base_declaration();
  if (base) {
    if (base->is_virtual())
      d->spec_ |= virtual_spec;
    if (base->is_abstract())
      d->spec_ |= abstract_spec;
    if (base->is_polymorphic())
      d->vtbl_ = new Decl_seq(*base->vtable());
  }

  // Elaborate member declarations, fields first.
  //
  // TODO: What are the lookup rules for default
  // member initializers. If we do this:
  //
  //    struct S {
  //      x : int = 1;
  //      y : int = x + 2; // Seems resonable.
  //
  //      a : int = b - 1; // OK?
  //      b : int = 0;
  //      // Making this okay could impose an alternative
  //      // initialization order.
  //
  //      g : int = f();   // OK?
  //      def f() -> int { ... }
  //      // What if f() refers to an uninitialized fiedl?
  //    }
  Scope_sentinel scope(*this, d->scope());
  for (Decl*& f : d->fields_)
    f = elaborate_decl(f);
  for (Decl*& m : d->members_)
    m = elaborate_decl(m);

  // Elaborate member definitions. See comments
  // above about handling member defintions.
  for (Decl*& m : d->members_)
    m = elaborate_def(m);

  // Determine if we need a vtable reference. This is the case
  // when:
  //    - there is no base class or
  //    - the base is not polymorphic
  //
  // TODO: We may need to perform this transformation
  // before elaborating any fields. It depends on whether
  // or not we allow a member's type to refer to member
  // variables (a la decltype).
  //
  // TODO: For multiple base classes, we probably want
  // multiple vtable references (one for each base).
  if (d->is_polymorphic()) {
    if (!base || !base->is_polymorphic()) {
      Symbol const* n = syms.get("vref");
      Type const* p = get_reference_type(get_character_type());
      d->vref_ = new Field_decl(n, p);
    }
  }

  defined.insert(d);
  return d;
}

// Nothing to do here now...
Decl*
Elaborator::elaborate_def(Field_decl* d)
{
  return d;
}

// Elaborate the method as a function. Note that we pre-declare
// the implicit "this" parameter during the first pass.
Decl*
Elaborator::elaborate_def(Method_decl* d)
{
  elaborate_def(cast<Function_decl>(d));
  return d;
}

Decl*
Elaborator::elaborate_def(Module_decl* d)
{
  // We should never get here.
  lingo_unreachable();
}

// -------------------------------------------------------------------------- //
// Elaboration of statements

// Elaborate a statement. This returns true if elaboration
// succeeds and false otherwise.
Stmt*
Elaborator::elaborate(Stmt* s)
{
  struct Fn
  {
    Elaborator& elab;

    Stmt* operator()(Empty_stmt* d) const { return elab.elaborate(d); }
    Stmt* operator()(Block_stmt* d) const { return elab.elaborate(d); }
    Stmt* operator()(Assign_stmt* d) const { return elab.elaborate(d); }
    Stmt* operator()(Return_stmt* d) const { return elab.elaborate(d); }
    Stmt* operator()(If_then_stmt* d) const { return elab.elaborate(d); }
    Stmt* operator()(If_else_stmt* d) const { return elab.elaborate(d); }
    Stmt* operator()(While_stmt* d) const { return elab.elaborate(d); }
    Stmt* operator()(Break_stmt* d) const { return elab.elaborate(d); }
    Stmt* operator()(Continue_stmt* d) const { return elab.elaborate(d); }
    Stmt* operator()(Expression_stmt* d) const { return elab.elaborate(d); }
    Stmt* operator()(Declaration_stmt* d) const { return elab.elaborate(d); }
  };

  return apply(s, Fn{*this});
}

Stmt*
Elaborator::elaborate(Empty_stmt* s)
{
  return s;
}

Stmt*
Elaborator::elaborate(Block_stmt* s)
{
  Scope_sentinel scope = *this;
  for (Stmt*& s1 : s->first)
    s1 = elaborate(s1);
  return s;
}

// In an assignment expression, the left operand shall
// refer to a mutable object. The types of the left and
// right operands shall match.
//
// TODO: If we have const types, then we'd have to add this
// checking.
Stmt*
Elaborator::elaborate(Assign_stmt* s)
{
  // FIXME: Write a better predicate?
  Expr* lhs = elaborate(s->object());
  if (!is<Reference_type>(lhs->type()))
    throw Type_error({}, "assignment to rvalue");

  // Apply rvalue conversion to the value and update the
  // expression.
  Expr *rhs = require_value(*this, s->second);

  // The types shall match. Compare t1 using the non-reference
  // type of the object.
  Type const* t1 = lhs->type()->nonref();
  Type const* t2 = rhs->type();
  if (t1 != t2)
    throw Type_error({}, "assignment to an object of a different type");

  s->first = lhs;
  s->second = rhs;
  return s;
}

// The type of the returned expression shall match the declared
// return type of the enclosing function.
//
// TODO: Implement me.
Stmt*
Elaborator::elaborate(Return_stmt* s)
{
  Function_decl* fn = stack.function();
  Type const* t = fn->return_type();

  // Check that the return type matches the returned value.
  Expr* e = elaborate(s->value());
  Expr* c = convert(e, t);
  if (!c) {
    std::stringstream ss;
    ss << "return type mismatch (expected "
       << *t << " but got " << *s->value()->type() << ")";
    throw std::runtime_error(ss.str());
  }

  s->first = c;
  return s;
}

// The condition must must be a boolean expression.
Stmt*
Elaborator::elaborate(If_then_stmt* s)
{
  Expr* c = require_converted(*this, s->first, get_boolean_type());
  if (!c)
    throw Type_error({}, "if condition does not have type 'bool'");
  Stmt* b = elaborate(s->body());

  s->first = c;
  s->second = b;
  return s;
}

// The condition must must be a boolean expression.
Stmt*
Elaborator::elaborate(If_else_stmt* s)
{
  Expr* c = require_converted(*this, s->first, get_boolean_type());
  if (!c)
    throw Type_error({}, "if condition does not have type 'bool'");
  Stmt* t = elaborate(s->true_branch());
  Stmt* f = elaborate(s->false_branch());

  s->first = c;
  s->second = t;
  s->third = f;
  return s;
}

Stmt*
Elaborator::elaborate(While_stmt* s)
{
  Expr* c = require_converted(*this, s->first, get_boolean_type());
  if (!c)
    throw Type_error({}, "loop condition does not have type 'bool'");
  Stmt* b = elaborate(s->body());

  s->first = c;
  s->second = b;
  return s;
}

Stmt*
Elaborator::elaborate(Break_stmt* s)
{
  // TODO: Verify that a break occurs within an
  // appropriate context.
  return s;
}

Stmt*
Elaborator::elaborate(Continue_stmt* s)
{
  // TODO: Verify that a continue occurs within an
  // appropriate context.
  return s;
}

Stmt*
Elaborator::elaborate(Expression_stmt* s)
{
  s->first = elaborate(s->expression());
  return s;
}

Stmt*
Elaborator::elaborate(Declaration_stmt* s)
{

  s->first = elaborate(s->declaration());
  return s;
}


text: java -jar ~/closure-compiler/compiler.jar --js uncomp.js  --js_output_file comp.min.js

redpajama_set_name: RedPajamaGithub


text:
package net.opengis.gml.impl;

import net.opengis.gml.CircleType;
import net.opengis.gml.GmlPackage;

import org.eclipse.emf.ecore.EClass;

/**
 *
 * An implementation of the model object 'Circle Type'.
 *
 *

 *

 *
 * @generated
 */
public class CircleTypeImpl extends ArcTypeImpl implements CircleType {
	/**
	 *
	 *
	 * @generated
	 */
	protected CircleTypeImpl() {
		super();
	}

	/**
	 *
	 *
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return GmlPackage.eINSTANCE.getCircleType();
	}

} //CircleTypeImpl


text:
/*
    Simple example of sending an OSC message using oscpack.
*/
#include "test.h"
#include "/oscpack/osc/OscOutboundPacketStream.h"
#include "/oscpack/ip/UdpSocket.h"

#define ADDRESS "127.0.0.1"
#define PORT 7000

#define OUTPUT_BUFFER_SIZE 1024

int test()
{
    UdpTransmitSocket transmitSocket( IpEndpointName( ADDRESS, PORT ) );

    char buffer[OUTPUT_BUFFER_SIZE];
    osc::OutboundPacketStream p( buffer, OUTPUT_BUFFER_SIZE );

    p << osc::BeginBundleImmediate
        << osc::BeginMessage( "/test1" )
            << true << 23 << (float)3.1415 << "hello" << osc::EndMessage
        << osc::BeginMessage( "/test2" )
            << true << 24 << (float)10.8 << "world" << osc::EndMessage
        << osc::EndBundle;

    transmitSocket.Send( p.Data(), p.Size() );
}


text:
module.exports = {
  // Enforce return after a callback
  'callback-return': ['error', ['callback', 'cb', 'next']],
  // Disallow require() outside of the top-level module scope
  'global-require': 'off',
  // Enforces error handling in callbacks
  'handle-callback-err': ['error', '^.*(e|E)rr(or)?$'],
  // Disallow use of the Buffer() constructor
  'no-buffer-constructor': 'error',
  // Disallow mixing regular variable and require declarations
  'no-mixed-requires': 'off',
  // Disallow use of new operator with the require function
  'no-new-require': 'error',
  // Disallow string concatenation with __dirname and __filename
  'no-path-concat': 'error',
  // Disallow process.exit()
  'no-process-exit': 'off',
  // Restrict usage of specified node imports
  'no-restricted-imports': 'off',
  // Restrict usage of specified node modules
  'no-restricted-modules': 'off',
  // Disallow use of synchronous methods
  'no-sync': 'off',
  // Disallow import declarations of extraneous packages
  // defer to import/no-extraneous-dependencies
  'node/no-extraneous-import': 'off',
  // Disallow require() expressions of extraneous packages
  'node/no-extraneous-require': 'error',
  // Enforce either module.exports or exports.
  'node/exports-style': ['error', 'module.exports'],
  // enforce either Buffer or require("buffer").Buffer
  'node/prefer-global/buffer': 'error',
  //	enforce either console or require("console")
  'node/prefer-global/console': 'error',
  // enforce either process or require("process")
  'node/prefer-global/process': 'error',
  // enforce either URLSearchParams or require("url").URLSearchParams
  'node/prefer-global/url-search-params': 'error',
  // enforce either URL or require("url").URL
  'node/prefer-global/url': 'error',
  // Disallow deprecated API.
  'node/no-deprecated-api': 'error',
  // Disallow import and export declarations for files that don't exist.
  'node/no-missing-import': 'off',
  // Disallow require()s for files that don't exist.
  'node/no-missing-require': 'off',
  // Disallow import and export declarations for files that are not published.
  'node/no-unpublished-import': 'off',
  // Disallow bin files that npm ignores.
  'node/no-unpublished-bin': 'error',
  // Disallow require()s for files that are not published.
  'node/no-unpublished-require': 'off',
  // disallow unsupported ECMAScript built-ins on the specified version
  'node/no-unsupported-features/es-builtins': 'off',
  // disallow unsupported ECMAScript syntax on the specified version
  'node/no-unsupported-features/es-syntax': 'off',
  // disallow unsupported Node.js built-in APIs on the specified version
  'node/no-unsupported-features/node-builtins': 'error',
  // If you turn this rule on, ESLint comes to address process.exit() as throw in code path analysis.
  'node/process-exit-as-throw': 'off',
  // Suggest correct usage of shebang.
  'node/shebang': 'error',
};


text:
package com.muaavin.webservices.rest;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

@Path("/Users")
public class UserQueryClass {

	List<User> users = new ArrayList<>();
	List<User> infringing_users = new ArrayList<>();

	@GET
	@Path("/GetUsers")
	@Produces(MediaType.APPLICATION_JSON)
	public String getUsers() throws Exception
	{
		infringing_users = new ArrayList<User>();
		MySqlDb db = new MySqlDb();
		Connection conn = db.connect();
		Statement st = conn.createStatement();
		ResultSet rs = null;
		String sql = "select name  , id , profilePic  ,state from users;";
		rs = (ResultSet) st.executeQuery(sql);
		getTwitterAndFacebookUsersFromDB(rs ,  false , false);
		rs = (ResultSet) st.executeQuery("select distinct id , name  , profilePic , state from twitterUsers ;");
		getTwitterAndFacebookUsersFromDB(rs ,  false , true);
		return AesEncryption.encrypt(infringing_users.toString());
	}

	@GET
	@Path("/BlockUser")
	@Produces(MediaType.APPLICATION_JSON)
	public String BlockUser(@QueryParam("user_id") String user_id, @QueryParam("isTwitterUser") boolean isTwitterUser) throws Exception
	{
		user_id = AesEncryption.decrypt(user_id);
		MySqlDb Db = new MySqlDb();

		Connection conn = Db.connect();
		Statement st = conn.createStatement();
		String sql = "select* from BlockedUsers;";
		ResultSet rs = (ResultSet) st.executeQuery(sql);
		if(isTwitterUser)
		{
			st.executeUpdate("UPDATE TwitterUsers SET state ='Blocked' where id = '"+user_id+"';");
			st.executeUpdate("UPDATE Twitter_InfringingUsers SET state ='Blocked' where id = '"+user_id+"';");
			return AesEncryption.encrypt("User Successfully Blocked");
		}
		else
		{
			st.executeUpdate("UPDATE infringingUsers SET state ='Blocked' where User_ID = '"+user_id+"';");
			st.executeUpdate("UPDATE Users SET state ='Blocked' where id = '"+user_id+"';");
			return AesEncryption.encrypt("User Successfully Blocked");
		}
	}

	// Check if user is already blocked
	public boolean isUserAlreadyBlocked(ResultSet rs, String user_id) throws SQLException
	{
		while(rs.next())
		{
		   String User_id = rs.getString("User_ID");
		   if((User_id.equals(user_id ))){ return true ; }
		}
		return false;
	}

	public List<User> getBlockedUsersList(ResultSet rs ,List<User> Users, boolean isTwitterData) throws SQLException // Get List of Blocked Users
	{
		users = Users;
		while(rs.next())
		{
		   User user = User.initializeUser("", rs.getString("User_ID"), "","",isTwitterData);
		   users.add(user);
		}
		//return users.toString() ;
		return users;
	}

	@GET
	@Path("/checkIfUserBlocked")
	@Produces(MediaType.APPLICATION_JSON)
	public String checkIfUserIsAlreadyBlocked(@QueryParam("user_id") String user_id) throws Exception
	{
		user_id = AesEncryption.decrypt(user_id);
		MySqlDb Db = new MySqlDb();

		Connection conn = Db.connect();
		Statement st = conn.createStatement();
		String sql = "select* from BlockedUsers;";
		ResultSet rs = (ResultSet) st.executeQuery(sql);
		if(isUserAlreadyBlocked(rs, user_id)== true)
		return AesEncryption.encrypt("User Already Blocked");
		return AesEncryption.encrypt("User not Blocked");
	}

	@GET
	@Path("/getBlockedUsers")
	@Produces(MediaType.APPLICATION_JSON)
	public String getBlockedUsers() throws Exception
	{

		MySqlDb Db = new MySqlDb();

		Connection conn = Db.connect();
		Statement st = conn.createStatement();
		ResultSet rs = (ResultSet) st.executeQuery("select* from BlockedUsers;");
		List<User> Users = getBlockedUsersList(rs,new ArrayList<User>(),false);
		rs = (ResultSet) st.executeQuery("select * from BlockedTwitterUsers;");
		Users = getBlockedUsersList(rs,Users,true);
		//String JsonResponseUsers = getBlockedUsersList(rs,new ArrayList<User>(),false).toString();
		return AesEncryption.encrypt(Users.toString());
	}
	@GET
	@Path("/UnBlockUser")
	@Produces(MediaType.APPLICATION_JSON)
	public String UnBlockUser(@QueryParam("user_id") String user_id, @QueryParam("isTwitterUser") boolean isTwitterUser) throws Exception
	{
		user_id = AesEncryption.decrypt(user_id);
		MySqlDb Db = new MySqlDb();
		Connection conn = Db.connect();
		Statement st = conn.createStatement();
		if(isTwitterUser)
		{
			st.executeUpdate("UPDATE TwitterUsers SET state ='UnBlocked' where id = '"+user_id+"';");
			st.executeUpdate("UPDATE Twitter_InfringingUsers SET state ='UnBlocked' where id = '"+user_id+"';");
			return AesEncryption.encrypt("User Unblocked");
		}
		else
		{
			st.executeUpdate("UPDATE infringingUsers SET state ='UnBlocked' where User_ID = '"+user_id+"';");
			st.executeUpdate("UPDATE Users SET state ='UnBlocked' where id = '"+user_id+"';");
			System.out.println("User unBlocked"); return AesEncryption.encrypt("User Unblocked");
		}
	}
	////////////////////////////////////////////////////////////////////////////
	@GET
	@Path("/Highlights")
	@Produces(MediaType.APPLICATION_JSON)
	public String get_InfringingUsers(@QueryParam("name") String Group_name ,@QueryParam("user_id") String user_id ,@QueryParam("specificUserFriends") boolean specificUserFriends , @QueryParam("isTwitterData") boolean getTwitterData) throws Exception
	{
		System.out.println("getTwitterData "+getTwitterData);
		if(Group_name!=null) {Group_name = AesEncryption.decrypt(Group_name); }
		if(user_id!=null) {user_id = AesEncryption.decrypt(user_id); }

		MySqlDb db = new MySqlDb();
		String response = "";
		Connection conn = db.connect();
		Statement st = conn.createStatement();
		ResultSet rs = null;

		if(Group_name == null) { response = "No Parameters Passed.."; }
		if(specificUserFriends == false)
		{
			getAllInfringingUsersFromDB(Group_name,  st, rs);
		}
		else
		{
			rs = getInfringingUsersFromDB(Group_name,user_id,st,rs,getTwitterData );
			getTwitterAndFacebookUsersFromDB(rs,getTwitterData,getTwitterData);
		}

		System.out.println("QUERY SUCCESSFULL EXECUTED");
		conn.close();
		return AesEncryption.encrypt(infringing_users.toString());
	}

	@GET
	@Path("/UnReportUser")
	@Produces(MediaType.APPLICATION_JSON)
	public void UnReportUsers(@QueryParam("user_id") String User_ID,@QueryParam("isTwitterData") boolean isTwitterData) throws Exception
	{
		User_ID = AesEncryption.decrypt(User_ID);
		MySqlDb db = new MySqlDb();
		Connection conn = db.connect();
		Statement st = conn.createStatement();
		deleteInfringingUserFromDB(User_ID, st, isTwitterData );
		conn.close();
		System.out.print("isTwitterData :"+isTwitterData);
	}
	/////////// Get All InfringingUsers From DB
	public ResultSet getAllInfringingUsersFromDB(String Group_name, Statement st, ResultSet rs ) throws SQLException
	{

		if(Group_name.equals("All"))
		{
			rs = (ResultSet) st.executeQuery("select distinct id , name , profilePic , state from TwitterInfringingUsers;");
			getTwitterAndFacebookUsersFromDB(rs , false,true);
			rs = (ResultSet) st.executeQuery("select distinct id , name ,  Profile_pic as profilePic , state from FacebookInfringingUsers;");
			getTwitterAndFacebookUsersFromDB(rs , false,false);
			System.out.print("Get All infringing Users Function Group Name : All");
		}

		else
		{
			rs = (ResultSet) st.executeQuery("select distinct id  , name , profilePic , state from TwitterInfringingUsers where Group_Name = '"+Group_name+"';");
			getTwitterAndFacebookUsersFromDB(rs , false,true);
			rs = (ResultSet) st.executeQuery("select distinct id , name ,Profile_pic as profilePic  ,state from FacebookInfringingUsers where Group_Name = '"+Group_name+"';");
			getTwitterAndFacebookUsersFromDB(rs , false,false);
			System.out.print("Get All infringing Users Function Group Name : Specific");
		}
		return rs;
	}

	// Get Selective InfringingUsers From DB
	public ResultSet getInfringingUsersFromDB(String Group_name, String user_id ,Statement st, ResultSet rs, boolean isTwitterData ) throws SQLException
	{
		if(isTwitterData)
		{
			if(Group_name.equals("All"))
			{
				rs = (ResultSet) st.executeQuery("select distinct id, name , profilePic ,state from TwitterInfringingUsers where User_ID = '"+user_id+"';");
			}
			else
			{
				rs = (ResultSet) st.executeQuery("select distinct id, name , profilePic, state from TwitterInfringingUsers where Group_Name = '"+Group_name+"' and User_ID = '"+user_id+"';");
			}
		}
		else
		{
			if(Group_name.equals("All"))
			{
				rs = (ResultSet) st.executeQuery(" select distinct id, name, Profile_pic as profilePic,state from FacebookInfringingUsers where state = 'UnBlocked' and User_ID = '"+user_id+"';");
			}
			else
			{
				rs = (ResultSet) st.executeQuery(" select distinct id, name, Profile_pic as profilePic,state from FacebookInfringingUsers where state = 'UnBlocked' and User_ID = '"+user_id+"' and group_name='"+Group_name+"';");
			}
		}
		return rs;
	}
	// Delete InfringingUsers From DB
	public void deleteInfringingUserFromDB(String UserID , Statement st, boolean isTwitterData) throws SQLException
	{
		if(isTwitterData)
		{
			st.executeUpdate("delete from TwitterFeedBack where TweetID in (select TweetID from TweetTable where Infringing_User_ID = '"+UserID+"');");
			st.executeUpdate("delete from TwitterThumbsDown where TweetID in (select TweetID from TweetTable where Infringing_User_ID = '"+UserID+"');");
			st.executeUpdate("delete from TweetTable where Infringing_User_ID = '"+UserID+"';");
			st.executeUpdate("delete from Twitter_InfringingUsers where id  = '"+UserID+"';");
			System.out.println("User UnReported");
		}
		else
		{
			st.executeUpdate("delete from commentsThumbDown where InfringingUserId = '"+UserID+"';");
			st.executeUpdate("delete from commentFeedBack where InfriningUserId = '"+UserID+"';");
			st.executeUpdate("delete from PostTable where   InfringingUserId = '"+UserID+"';");
			st.executeUpdate("delete from comments where   InfringingUserId = '"+UserID+"';");
			st.executeUpdate("delete from infringingUsers where User_ID = '"+UserID+"';");

		}
	}

	public void getTwitterAndFacebookUsersFromDB(ResultSet rs , boolean getTwitterData , boolean twitterData) throws SQLException
	{
		while(rs.next())
		{
			User user = User.initializeUser(rs.getString("name") ,rs.getString("id") , rs.getString("profilePic"),rs.getString("state"),twitterData);
			infringing_users.add(user);
		}
	}
}


text:
///import core
///commands 清空文档
///commandsName  ClearDoc
///commandsTitle  清空文档
/**
 *
 * 清空文档
 * @function
 * @name baidu.editor.execCommand
 * @param   {String}   cmdName     cleardoc清空文档
 */

UE.commands['cleardoc'] = {
    execCommand : function( cmdName) {
        var me = this,
            enterTag = me.options.enterTag,
            range = me.selection.getRange();
        if(enterTag == "br"){
            me.body.innerHTML = "
";
            range.setStart(me.body,0).setCursor();
        }else{
            me.body.innerHTML = "
"+(ie ? "" : "
")+"
";
            range.setStart(me.body.firstChild,0).setCursor(false,true);
        }
        me.fireEvent("clearDoc");
    }
};


text:
(function () {
    document.getElementById('test').className = 'selected';
    document.getElementById('test').href = 'http://www.softonic.com';
    $(document.getElementById('test')).bind('click', function () {
        this.parentNode.removeChild(this);
    });
}());

// 261


text:
module Plugin1 where

import qualified API
action :: API.PluginAPI
action i = show i


text:
package org.drip.regression.curve;

/*
 * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 */

/*!
 * Copyright (C) 2017 Lakshmi Krishnamurthy
 * Copyright (C) 2016 Lakshmi Krishnamurthy
 * Copyright (C) 2015 Lakshmi Krishnamurthy
 * Copyright (C) 2014 Lakshmi Krishnamurthy
 * Copyright (C) 2013 Lakshmi Krishnamurthy
 * Copyright (C) 2012 Lakshmi Krishnamurthy
 *
 *  This file is part of DRIP, a free-software/open-source library for buy/side financial/trading model
 *  	libraries targeting analysts and developers
 *  	https://lakshmidrip.github.io/DRIP/
 *
 *  DRIP is composed of four main libraries:
 *
 *  - DRIP Fixed Income - https://lakshmidrip.github.io/DRIP-Fixed-Income/
 *  - DRIP Asset Allocation - https://lakshmidrip.github.io/DRIP-Asset-Allocation/
 *  - DRIP Numerical Optimizer - https://lakshmidrip.github.io/DRIP-Numerical-Optimizer/
 *  - DRIP Statistical Learning - https://lakshmidrip.github.io/DRIP-Statistical-Learning/
 *
 *  - DRIP Fixed Income: Library for Instrument/Trading Conventions, Treasury Futures/Options,
 *  	Funding/Forward/Overnight Curves, Multi-Curve Construction/Valuation, Collateral Valuation and XVA
 *  	Metric Generation, Calibration and Hedge Attributions, Statistical Curve Construction, Bond RV
 *  	Metrics, Stochastic Evolution and Option Pricing, Interest Rate Dynamics and Option Pricing, LMM
 *  	Extensions/Calibrations/Greeks, Algorithmic Differentiation, and Asset Backed Models and Analytics.
 *
 *  - DRIP Asset Allocation: Library for model libraries for MPT framework, Black Litterman Strategy
 *  	Incorporator, Holdings Constraint, and Transaction Costs.
 *
 *  - DRIP Numerical Optimizer: Library for Numerical Optimization and Spline Functionality.
 *
 *  - DRIP Statistical Learning: Library for Statistical Evaluation and Machine Learning.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *   	you may not use this file except in compliance with the License.
 *
 *  You may obtain a copy of the License at
 *  	http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  	distributed under the License is distributed on an "AS IS" BASIS,
 *  	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 *  See the License for the specific language governing permissions and
 *  	limitations under the License.
 */

/**
 * ZeroCurveRegressor implements the regression analysis set for the Zero Curve. The  regression tests do the
 *  consists of the following:
 *  - Build a discount curve, followed by the zero curve
 *  - Regressor #1: Compute zero curve discount factors
 *  - Regressor #2: Compute zero curve zero rates
 *
 * @author Lakshmi Krishnamurthy
 */

public class ZeroCurveRegressor implements org.drip.regression.core.RegressorSet {
	private org.drip.state.discount.ZeroCurve _zc = null;
	private java.lang.String _strRegressionScenario = "org.drip.analytics.curve.ZeroCurve";

	private java.util.List<org.drip.regression.core.UnitRegressor> _setRegressors = new
		java.util.ArrayList<org.drip.regression.core.UnitRegressor>();

	/**
	 * ZeroCurveRegressor constructor - Creates the base zero curve and initializes the regression objects
	 */

	public ZeroCurveRegressor()
	{
	}

	/*
	 * Setting up of the zero curve regressor set
	 */

	@Override public boolean setupRegressors()
	{
		/*
		 * Zero Curve Creation unit regressor - implements the pre-regression, the post-regression, and the
		 * 	actual regression functionality of the UnitRegressorExecutor class.
		 */

		try {
			_setRegressors.add (new org.drip.regression.core.UnitRegressionExecutor
				("CreateZeroCurveFromPeriods", _strRegressionScenario)
			{
				private static final double s_dblZSpread = 0.01;

				private org.drip.analytics.date.JulianDate _dtStart = null;
				private org.drip.state.discount.ExplicitBootDiscountCurve _dc = null;

				private java.util.List<org.drip.analytics.cashflow.CompositePeriod> _lsCouponPeriod = new
					java.util.ArrayList<org.drip.analytics.cashflow.CompositePeriod>();

				@Override public boolean preRegression()
				{
					if (null == (_dtStart = org.drip.analytics.date.DateUtil.CreateFromYMD (2010,
						org.drip.analytics.date.DateUtil.MAY, 12)))
						return false;

					final int NUM_DC_NODES = 5;
					final int NUM_PERIOD_NODES  = 40;
					int aiDate[] = new int[NUM_DC_NODES];
					double adblRate[] = new double[NUM_DC_NODES];

					for (int i = 0; i < NUM_DC_NODES; ++i) {
						aiDate[i] = _dtStart.addYears (2 * i + 1).julian();

						adblRate[i] = 0.05 + 0.001 * (NUM_DC_NODES - i);
					}

					if (null == (_dc = org.drip.state.creator.ScenarioDiscountCurveBuilder.PiecewiseForward
						(_dtStart, "CHF", aiDate, adblRate)))
						return false;

					try {
						org.drip.param.period.UnitCouponAccrualSetting ucas = new
							org.drip.param.period.UnitCouponAccrualSetting (2, "30/360", false, "30/360",
								false, "ZAR", false,
									org.drip.analytics.support.CompositePeriodBuilder.ACCRUAL_COMPOUNDING_RULE_GEOMETRIC);

						org.drip.param.period.ComposableFixedUnitSetting cfus = new
							org.drip.param.period.ComposableFixedUnitSetting ("6M",
								org.drip.analytics.support.CompositePeriodBuilder.EDGE_DATE_SEQUENCE_REGULAR,
							null, s_dblZSpread, 0., "ZAR");

						org.drip.param.period.CompositePeriodSetting cps = new
							org.drip.param.period.CompositePeriodSetting (2, "6M", "ZAR", null, 1., null,
								null, null, null);

						java.util.List<java.lang.Integer> lsStreamEdgeDate =
							org.drip.analytics.support.CompositePeriodBuilder.RegularEdgeDates (_dtStart,
								"6M", (NUM_PERIOD_NODES * 6) + "M", null);

						_lsCouponPeriod =
							org.drip.analytics.support.CompositePeriodBuilder.FixedCompositeUnit (
								lsStreamEdgeDate, cps, ucas, cfus);
					} catch (java.lang.Exception e) {
						e.printStackTrace();

						return false;
					}

					return true;
				}

				@Override public boolean execRegression()
				{
					try {
						if (null == (_zc = org.drip.state.curve.DerivedZeroRate.FromBaseCurve (2, "30/360",
							_dc.currency(), true, _lsCouponPeriod, _lsCouponPeriod.get
								(_lsCouponPeriod.size() - 1).endDate(), _dtStart.julian(), _dtStart.addDays
									(2).julian(), _dc, s_dblZSpread, null, new
										org.drip.spline.params.SegmentCustomBuilderControl
											(org.drip.spline.stretch.MultiSegmentSequenceBuilder.BASIS_SPLINE_POLYNOMIAL,
							new org.drip.spline.basis.PolynomialFunctionSetParams (4),
								org.drip.spline.params.SegmentInelasticDesignControl.Create (2, 2), new
									org.drip.spline.params.ResponseScalingShapeControl (true, new
										org.drip.function.r1tor1.QuadraticRationalShapeControl (0.)),
											null))))
							return false;
					} catch (java.lang.Exception e) {
						e.printStackTrace();

						return false;
					}

					return true;
				}
			});

			/*
			 * Get Zero Discount Factor unit regressor - implements the pre-regression, the post-regression,
			 *	and the actual regression functionality of the UnitRegressorExecutor class.
			 */

			_setRegressors.add (new org.drip.regression.core.UnitRegressionExecutor ("getZeroDF",
				_strRegressionScenario)
			{
				private static final int NUM_DF_NODES = 30;

				private int _aiDate[] = new int[NUM_DF_NODES];
				private double _adblDiscFactor[] = new double[NUM_DF_NODES];

				@Override public boolean preRegression()
				{
					org.drip.analytics.date.JulianDate dtStart =
						org.drip.analytics.date.DateUtil.CreateFromYMD (2008,
							org.drip.analytics.date.DateUtil.SEPTEMBER, 25);

					for (int i = 0; i < NUM_DF_NODES; ++i)
						_aiDate[i] = dtStart.addMonths (6 * i + 6).julian();

					return true;
				}

				@Override public boolean execRegression()
				{
					try {
						for (int i = 0; i < NUM_DF_NODES; ++i)
							_adblDiscFactor[i] = _zc.df (_aiDate[i]);
					} catch (java.lang.Exception e) {
						e.printStackTrace();

						return false;
					}

					return true;
				}

				@Override public boolean postRegression (
					final org.drip.regression.core.RegressionRunDetail rnvd)
				{
					try {
						for (int i = 0; i < NUM_DF_NODES; ++i)
							rnvd.set ("ZeroDF[" + new org.drip.analytics.date.JulianDate (_aiDate[i]) +
								"]", "" + _adblDiscFactor[i]);
					} catch (java.lang.Exception e) {
						e.printStackTrace();

						return false;
					}

					return true;
				}
			});

			/*
			 * Get Zero Rate unit regressor - implements the pre-regression, the post-regression, and the
			 * 	actual regression functionality of the UnitRegressorExecutor class.
			 */

			_setRegressors.add (new org.drip.regression.core.UnitRegressionExecutor ("getZeroRate",
				_strRegressionScenario)
			{
				private static final int NUM_DF_NODES = 30;

				private int _aiDate[] = new int[NUM_DF_NODES];
				private double _adblRate[] = new double[NUM_DF_NODES];

				@Override public boolean preRegression()
				{
					org.drip.analytics.date.JulianDate dtStart =
						org.drip.analytics.date.DateUtil.CreateFromYMD (2008,
							org.drip.analytics.date.DateUtil.SEPTEMBER, 25);

					for (int i = 0; i < NUM_DF_NODES; ++i)
						_aiDate[i] = dtStart.addMonths (6 * i + 6).julian();

					return true;
				}

				@Override public boolean execRegression()
				{
					try {
						for (int i = 0; i < NUM_DF_NODES; ++i)
							_adblRate[i] = _zc.zeroRate (_aiDate[i]);
					} catch (java.lang.Exception e) {
						e.printStackTrace();

						return false;
					}

					return true;
				}

				@Override public boolean postRegression (
					final org.drip.regression.core.RegressionRunDetail rnvd)
				{
					try {
						for (int i = 0; i < NUM_DF_NODES; ++i)
							rnvd.set ("ZeroRate[" + new org.drip.analytics.date.JulianDate (_aiDate[i]) +
								"]", "" + _adblRate[i]);
					} catch (java.lang.Exception e) {
						e.printStackTrace();

						return false;
					}

					return true;
				}
			});
		} catch (java.lang.Exception e) {
			e.printStackTrace();

			return false;
		}

		return true;
	}

	@Override public java.util.List<org.drip.regression.core.UnitRegressor> getRegressorSet()
	{
		return _setRegressors;
	}

	@Override public java.lang.String getSetName()
	{
		return _strRegressionScenario;
	}
}


text:
require 'spec_helper'

describe Gitlab::UrlBuilder do
  describe '.build' do
    context 'when passing a Commit' do
      it 'returns a proper URL' do
        commit = build_stubbed(:commit)

        url = described_class.build(commit)

        expect(url).to eq "#{Settings.gitlab['url']}/#{commit.project.full_path}/commit/#{commit.id}"
      end
    end

    context 'when passing an Issue' do
      it 'returns a proper URL' do
        issue = build_stubbed(:issue, iid: 42)

        url = described_class.build(issue)

        expect(url).to eq "#{Settings.gitlab['url']}/#{issue.project.full_path}/issues/#{issue.iid}"
      end
    end

    context 'when passing a Milestone' do
      let(:group) { create(:group) }
      let(:project) { create(:project, :public, namespace: group) }

      context 'belonging to a project' do
        it 'returns a proper URL' do
          milestone = create(:milestone, project: project)

          url = described_class.build(milestone)

          expect(url).to eq "#{Settings.gitlab['url']}/#{milestone.project.full_path}/milestones/#{milestone.iid}"
        end
      end

      context 'belonging to a group' do
        it 'returns a proper URL' do
          milestone = create(:milestone, group: group)

          url = described_class.build(milestone)

          expect(url).to eq "#{Settings.gitlab['url']}/groups/#{milestone.group.full_path}/-/milestones/#{milestone.iid}"
        end
      end
    end

    context 'when passing a MergeRequest' do
      it 'returns a proper URL' do
        merge_request = build_stubbed(:merge_request, iid: 42)

        url = described_class.build(merge_request)

        expect(url).to eq "#{Settings.gitlab['url']}/#{merge_request.project.full_path}/merge_requests/#{merge_request.iid}"
      end
    end

    context 'when passing a Note' do
      context 'on a Commit' do
        it 'returns a proper URL' do
          note = build_stubbed(:note_on_commit)

          url = described_class.build(note)

          expect(url).to eq "#{Settings.gitlab['url']}/#{note.project.full_path}/commit/#{note.commit_id}#note_#{note.id}"
        end
      end

      context 'on a Commit Diff' do
        it 'returns a proper URL' do
          note = build_stubbed(:diff_note_on_commit)

          url = described_class.build(note)

          expect(url).to eq "#{Settings.gitlab['url']}/#{note.project.full_path}/commit/#{note.commit_id}#note_#{note.id}"
        end
      end

      context 'on an Issue' do
        it 'returns a proper URL' do
          issue = create(:issue, iid: 42)
          note = build_stubbed(:note_on_issue, noteable: issue)

          url = described_class.build(note)

          expect(url).to eq "#{Settings.gitlab['url']}/#{issue.project.full_path}/issues/#{issue.iid}#note_#{note.id}"
        end
      end

      context 'on a MergeRequest' do
        it 'returns a proper URL' do
          merge_request = create(:merge_request, iid: 42)
          note = build_stubbed(:note_on_merge_request, noteable: merge_request)

          url = described_class.build(note)

          expect(url).to eq "#{Settings.gitlab['url']}/#{merge_request.project.full_path}/merge_requests/#{merge_request.iid}#note_#{note.id}"
        end
      end

      context 'on a MergeRequest Diff' do
        it 'returns a proper URL' do
          merge_request = create(:merge_request, iid: 42)
          note = build_stubbed(:diff_note_on_merge_request, noteable: merge_request)

          url = described_class.build(note)

          expect(url).to eq "#{Settings.gitlab['url']}/#{merge_request.project.full_path}/merge_requests/#{merge_request.iid}#note_#{note.id}"
        end
      end

      context 'on a ProjectSnippet' do
        it 'returns a proper URL' do
          project_snippet = create(:project_snippet)
          note = build_stubbed(:note_on_project_snippet, noteable: project_snippet)

          url = described_class.build(note)

          expect(url).to eq "#{Settings.gitlab['url']}/#{project_snippet.project.full_path}/snippets/#{note.noteable_id}#note_#{note.id}"
        end
      end

      context 'on a PersonalSnippet' do
        it 'returns a proper URL' do
          personal_snippet = create(:personal_snippet)
          note = build_stubbed(:note_on_personal_snippet, noteable: personal_snippet)

          url = described_class.build(note)

          expect(url).to eq "#{Settings.gitlab['url']}/snippets/#{note.noteable_id}#note_#{note.id}"
        end
      end

      context 'on another object' do
        it 'returns a proper URL' do
          project = build_stubbed(:project)

          expect { described_class.build(project) }
            .to raise_error(NotImplementedError, 'No URL builder defined for Project')
        end
      end
    end

    context 'when passing a WikiPage' do
      it 'returns a proper URL' do
        wiki_page = build(:wiki_page)
        url = described_class.build(wiki_page)

        expect(url).to eq "#{Gitlab.config.gitlab.url}#{wiki_page.wiki.wiki_base_path}/#{wiki_page.slug}"
      end
    end
  end
end


text:
const markdown = require('./markdown.md');

const data = {
  title: 'PORTFOLIO',
  image: '/assets/images/hydrasquid_1492207826341.png',
  body: markdown.body,
};

export default data;


text:
require 'cases/helper'
require 'models/admin'
require 'models/admin/user'

class StoreTest < ActiveRecord::TestCase
  setup do
    @john = Admin::User.create(:name => 'John Doe', :color => 'black', :remember_login => true)
  end

  test "reading store attributes through accessors" do
    assert_equal 'black', @john.color
    assert_nil @john.homepage
  end

  test "writing store attributes through accessors" do
    @john.color = 'red'
    @john.homepage = '37signals.com'

    assert_equal 'red', @john.color
    assert_equal '37signals.com', @john.homepage
  end

  test "accessing attributes not exposed by accessors" do
    @john.settings[:icecream] = 'graeters'
    @john.save

    assert_equal 'graeters', @john.reload.settings[:icecream]
  end

  test "updating the store will mark it as changed" do
    @john.color = 'red'
    assert @john.settings_changed?
  end

  test "object initialization with not nullable column" do
    assert_equal true, @john.remember_login
  end

  test "writing with not nullable column" do
    @john.remember_login = false
    assert_equal false, @john.remember_login
  end
end


text:
package org.sakaiproject.portal.render.portlet.servlet;

import org.sakaiproject.authz.api.Role;
import org.sakaiproject.authz.cover.SecurityService;
import org.sakaiproject.exception.IdUnusedException;
import org.sakaiproject.portal.render.portlet.services.state.PortletState;
import org.sakaiproject.site.api.Site;
import org.sakaiproject.site.api.ToolConfiguration;
import org.sakaiproject.site.cover.SiteService;
import org.sakaiproject.tool.api.Session;
import org.sakaiproject.tool.cover.SessionManager;

// This utility class is so that the different servlet wrappers can share code

/**
 * @author ddwolf
 * @author ieb
 * @since Sakai 2.4
 * @version $Rev$
 */
public class SakaiServletUtil
{

	public static boolean isUserInRole(String string, PortletState state)
	{
		if (string == null) return false;
		if (string.equalsIgnoreCase("admin") && SecurityService.isSuperUser())
			return true;
		// Gridsphere convention
		if (string.equalsIgnoreCase("super") && SecurityService.isSuperUser())
			return true;

		String placementId = state.getId();

		// find the tool from some site
		ToolConfiguration siteTool = SiteService.findTool(placementId);
		if (siteTool == null) return false;

		String siteId = siteTool.getSiteId();

		String siteReference = SiteService.siteReference(siteId);

		if (SecurityService.unlock(string, siteReference)) return true;

		Session session = SessionManager.getCurrentSession();

		if (session == null) return false;

		String userId = session.getUserId();

		// Fall through to roles
		try
		{
			Site site = SiteService.getSite(siteId);
			Role role = site.getUserRole(userId);
			if (role == null) return false;
			if ( string.equalsIgnoreCase(role.getId()) ) return true;
		}
		catch (IdUnusedException e)
		{
			return false;
		}

		// One last mapping for IMS Enterprise Role compatibility

		// "Admin" is handled above

		// The ideal way to handle Student and Instructor is to
		// Make functions or roles in the site - this allows the
		// support of any IMS Enterprise role such as Observer
		// or Mentor.  However this will be uncommon and project
		// sites will never have these defined - so if we encounter
		// The IMS Standard roles "Student" or "Instructor" and
		// we have fallen down to here, we fall back to the venerable
		// "site.upd" and "site.visit"

		if (string.equalsIgnoreCase("student") &&
		    SecurityService.unlock(SiteService.SITE_VISIT, siteReference) ) return true;

		if (string.equalsIgnoreCase("instructor") &&
		    SecurityService.unlock(SiteService.SECURE_UPDATE_SITE, siteReference) ) return true;

		// So sorry - no matter how hard we tried - you are not in this role
		return false;
	}
}


text:
package pt.mashashi.javaroles.test.composition;

import pt.mashashi.javaroles.annotations.InjObjRigid;
import pt.mashashi.javaroles.annotations.ObjRole;
import pt.mashashi.javaroles.annotations.Player;
import static org.junit.Assert.assertEquals;

public class TestStaticRole {

	interface Human{ String hello(String[] a); String hello2(); }
	interface Monkey{ String hello(String[] a); }

	static class Bonobo implements Monkey{
		@InjObjRigid Object obj;
		@Override public String hello(String[] a) { return obj.toString(); }
	}

	static class Bonobo2 extends Bonobo{
		@Override public String hello(String[] a) { return obj.toString(); }
	}

	@Player
	static class AnimalRolesSwaped implements Monkey{
		@ObjRole public Monkey monkey;
		public AnimalRolesSwaped(Monkey monkey){
			this.monkey = monkey;
		}
		@Override
		public String hello(String[] a) { return "Default hello "+this.getClass().getName(); }
	}

	@Player
	static class AnimalRolesSwaped2 implements Monkey{
		@ObjRole private Monkey monkey;
		public AnimalRolesSwaped2(Monkey monkey){
			this.monkey = monkey;
		}
		@Override
		public String hello(String[] a) { return "Default hello "+this.getClass().getName(); }
	}

	//@Player
	static class AnimalRolesSwaped3 extends AnimalRolesSwaped2{

		public AnimalRolesSwaped3(Monkey monkey) {
			super(monkey);
		}

	}

	@Player
	static class AnimalRolesSwaped4 implements Monkey{
		@ObjRole private static Monkey monkey;
		public AnimalRolesSwaped4(Monkey monkey){
			this.monkey = monkey;
		}
		@Override
		public String hello(String[] a) { return "Default hello "+this.getClass().getName(); }
	}

	public static void test(){

		Bonobo bonobo = new Bonobo();

		AnimalRolesSwaped a = new AnimalRolesSwaped(bonobo);
		String vala = a.hello(null);
		assertEquals(vala, a.toString());
		AnimalRolesSwaped b = new AnimalRolesSwaped(bonobo);
		String valb = b.hello(null);
		assertEquals(valb, a.toString());

		bonobo = new Bonobo();
		AnimalRolesSwaped2 a2 = new AnimalRolesSwaped2(bonobo);
		String vala2 = a2.hello(null);
		assertEquals(vala2, a2.toString());
		AnimalRolesSwaped2 b2 = new AnimalRolesSwaped2(bonobo);
		String valb2 = b2.hello(null);
		assertEquals(valb2, a2.toString());

		bonobo = new Bonobo2();
		AnimalRolesSwaped2 a3 = new AnimalRolesSwaped2(bonobo);
		String vala3 = a3.hello(null);
		assertEquals(vala3, a3.toString());
		AnimalRolesSwaped2 b3 = new AnimalRolesSwaped2(bonobo);
		String valb3 = b3.hello(null);
		assertEquals(valb3, a3.toString());

		bonobo = new Bonobo2();
		AnimalRolesSwaped3 a4 = new AnimalRolesSwaped3(bonobo);
		String vala4 = a4.hello(null);
		assertEquals(vala4, a4.toString());
		AnimalRolesSwaped3 b4 = new AnimalRolesSwaped3(bonobo);
		String valb4 = b4.hello(null);
		assertEquals(valb4, a4.toString());

		bonobo = new Bonobo();
		AnimalRolesSwaped4 a5 = new AnimalRolesSwaped4(bonobo);
		String vala5 = a5.hello(null);
		assertEquals(vala5, a5.toString());
		AnimalRolesSwaped4 b5 = new AnimalRolesSwaped4(bonobo);
		String valb5 = b5.hello(null);
		assertEquals(valb5, b5.toString());

	}

}


text:
import React from "react"

import Card from "./material/Card"
import { makeVideoSubtitleUrl } from "../lib/urls"

import type { Video, VideoSubtitle } from "../flow/videoTypes"
import Filefield from "./material/Filefield"

export default class VideoSubtitleCard extends React.Component<*, void> {
  props: {
    video: Video,
    isAdmin: boolean,
    uploadVideoSubtitle: Function,
    deleteVideoSubtitle: Function
  }

  render() {
    const {
      video,
      isAdmin,
      uploadVideoSubtitle,
      deleteVideoSubtitle
    } = this.props
    return (
      <Card className="video-subtitle-card">

Subtitles / CC

              {video.videosubtitle_set.map(
                (subtitle: VideoSubtitle, key) => (

                      {subtitle.s3_object_key
                        .split("/")
                        .slice(-1)[0]
                        .slice(0, 10)}..._{subtitle.language}.vtt

                      ({subtitle.language_name})

                        file_download

                    {isAdmin && (

                         deleteVideoSubtitle(subtitle.id)}
                        >
                          delete

                    )}

                ),
                this
              )}

              {isAdmin && (
                <Filefield
                  id="video-subtitle"
                  accept=".vtt"
                  label="Add subtitles (.vtt file)"
                  onChange={uploadVideoSubtitle}
                />
              )}

      </Card>
    )
  }
}


text:
using namespace log4cplus;
using namespace log4cplus::helpers;

//////////////////////////////////////////////////////////////////////////////
// log4cplus::HierarchyLocker ctor and dtor
//////////////////////////////////////////////////////////////////////////////

HierarchyLocker::HierarchyLocker(Hierarchy& _h)
: h(_h),
  hierarchyLocker(h.hashtable_mutex),
  loggerList()
{
    // Get a copy of all of the Hierarchy's Loggers (except the Root Logger)
    h.initializeLoggerList(loggerList);

    // Lock all of the Hierarchy's Loggers' mutexs
    try {
            for(LoggerListIterator it=loggerList.begin(); it!=loggerList.end(); ++it) {
                LOG4CPLUS_MUTEX_LOCK( (*it).value->appender_list_mutex ) ;
            }
        }
        catch(...) {
            h.getLogLog().error(LOG4CPLUS_TEXT("HierarchyLocker::ctor()- An error occurred while locking"));
            // TODO --> We need to unlock any Logger mutex that we were able to lock
            throw;
        }
    }

    HierarchyLocker::~HierarchyLocker()
    {
        try {
            for(LoggerListIterator it=loggerList.begin(); it!=loggerList.end(); ++it) {
            LOG4CPLUS_MUTEX_UNLOCK( (*it).value->appender_list_mutex ) ;
        }
    }
    catch(...) {
        h.getLogLog().error(LOG4CPLUS_TEXT("HierarchyLocker::dtor()- An error occurred while unlocking"));
        throw;
    }
}

void
HierarchyLocker::resetConfiguration()
{
    Logger root = h.getRoot();
    h.disable(log4cplus::Hierarchy::DISABLE_OFF);

    // begin by closing nested appenders
    // then, remove all appenders
    root.setLogLevel(DEBUG_LOG_LEVEL);
    root.closeNestedAppenders();
    root.removeAllAppenders();

    // repeat
    for(LoggerListIterator it=loggerList.begin(); it!=loggerList.end(); ++it) {
        LOG4CPLUS_MUTEX_UNLOCK( (*it).value->appender_list_mutex ) ;
        (*it).closeNestedAppenders();
        (*it).removeAllAppenders();
        LOG4CPLUS_MUTEX_LOCK( (*it).value->appender_list_mutex ) ;
        (*it).setLogLevel(NOT_SET_LOG_LEVEL);
        (*it).setAdditivity(true);
    }
}

Logger
HierarchyLocker::getInstance(const log4cplus::tstring& name)
{
    return h.getInstanceImpl(name, *h.getLoggerFactory());
}

Logger
HierarchyLocker::getInstance(const log4cplus::tstring& name, spi::LoggerFactory& factory)
{
    return h.getInstanceImpl(name, factory);
}

void
HierarchyLocker::addAppender(Logger& logger, log4cplus::SharedAppenderPtr& appender)
{
    for(LoggerListIterator it=loggerList.begin(); it!=loggerList.end(); ++it) {
        if((*it).value == logger.value) {
            LOG4CPLUS_MUTEX_UNLOCK( logger.value->appender_list_mutex );
            logger.addAppender(appender);
            LOG4CPLUS_MUTEX_LOCK( logger.value->appender_list_mutex );
            return;
        }
    }

    // I don't have this Logger locked
    logger.addAppender(appender);
}