Modifier and Type | Method and Description |
---|---|
Binding |
ResultSet.nextBinding()
Move to the next binding (low level)
|
Modifier and Type | Method and Description |
---|---|
List<Binding> |
Query.getValuesData()
VALUES data - null for a Node means undef
|
Modifier and Type | Method and Description |
---|---|
static Plan |
QueryExecutionFactory.createPlan(Query query,
DatasetGraph dataset,
Binding input) |
static Plan |
QueryExecutionFactory.createPlan(Query query,
DatasetGraph dataset,
Binding input,
Context context) |
Modifier and Type | Method and Description |
---|---|
void |
Query.setValuesDataBlock(List<Var> variables,
List<Binding> values) |
Modifier and Type | Method and Description |
---|---|
static Binding |
Algebra.merge(Binding bindingLeft,
Binding bindingRight) |
Modifier and Type | Method and Description |
---|---|
void |
Table.addBinding(Binding binding) |
static boolean |
Algebra.compatible(Binding bindingLeft,
Binding bindingRight) |
boolean |
Table.contains(Binding binding) |
static boolean |
Algebra.disjoint(Binding binding1,
Binding binding2) |
QueryIterator |
Table.matchRightLeft(Binding bindingLeft,
boolean includeOnNoMatch,
ExprList condition,
ExecutionContext execCxt) |
static Binding |
Algebra.merge(Binding bindingLeft,
Binding bindingRight) |
Modifier and Type | Method and Description |
---|---|
List<Binding> |
TableData.getRows() |
Modifier and Type | Method and Description |
---|---|
void |
TableData.addBinding(Binding binding) |
void |
TableBase.addBinding(Binding binding) |
void |
TableN.addBinding(Binding binding) |
boolean |
TableBase.contains(Binding b) |
boolean |
TableEmpty.contains(Binding binding) |
QueryIterator |
Table1.matchRightLeft(Binding bindingLeft,
boolean includeOnNoMatch,
ExprList conditions,
ExecutionContext execContext) |
QueryIterator |
TableUnit.matchRightLeft(Binding bindingLeft,
boolean includeOnNoMatch,
ExprList conditions,
ExecutionContext execCxt) |
QueryIterator |
TableEmpty.matchRightLeft(Binding bindingLeft,
boolean includeOnNoMatch,
ExprList conditions,
ExecutionContext execContext) |
QueryIterator |
TableN.matchRightLeft(Binding bindingLeft,
boolean includeOnNoMatch,
ExprList conditions,
ExecutionContext execContext) |
Constructor and Description |
---|
TableData(List<Var> variables,
List<Binding> rows) |
Modifier and Type | Method and Description |
---|---|
Binding |
ResultBinding.getBinding() |
Modifier and Type | Method and Description |
---|---|
Node |
VarExprList.get(Var var,
Binding binding,
FunctionEnv funcEnv) |
static Node |
Var.lookup(Binding binding,
Node node) |
static Node |
Var.lookup(Binding binding,
Var var) |
static BasicPattern |
Substitute.substitute(BasicPattern bgp,
Binding binding) |
static Expr |
Substitute.substitute(Expr expr,
Binding binding) |
static ExprList |
Substitute.substitute(ExprList exprList,
Binding binding) |
static Node |
Substitute.substitute(Node n,
Binding b) |
static Op |
Substitute.substitute(Op op,
Binding binding) |
static PropFuncArg |
Substitute.substitute(PropFuncArg propFuncArg,
Binding binding) |
static Quad |
Substitute.substitute(Quad quad,
Binding binding) |
static Triple |
Substitute.substitute(Triple triple,
Binding binding) |
static TriplePath |
Substitute.substitute(TriplePath triplePath,
Binding binding) |
Constructor and Description |
---|
ResultBinding(Model _model,
Binding _binding) |
Modifier and Type | Method and Description |
---|---|
Binding |
ResultSetStream.nextBinding() |
Binding |
QueryIterator.nextBinding()
Get next binding
|
Modifier and Type | Method and Description |
---|---|
Plan |
QueryEngineFactory.create(Op op,
DatasetGraph dataset,
Binding inputBinding,
Context context) |
Plan |
QueryEngineFactory.create(Query query,
DatasetGraph dataset,
Binding inputBinding,
Context context) |
QueryIterator |
OpEval.evaluate(Op op,
DatasetGraph dsg,
Binding binding,
Context context) |
QueryIterator |
QueryEngineBase.evaluate(Op op,
DatasetGraph dsg,
Binding binding,
Context context) |
Constructor and Description |
---|
ResultSetStream(List<String> resultVars,
Model m,
Iterator<Binding> iter) |
Modifier and Type | Interface and Description |
---|---|
interface |
BindingMap
Bindings are immutable, and are equal-by-value, but
they have to be constructed
somehow and this interface captures that.
|
interface |
BindingMutable |
Modifier and Type | Class and Description |
---|---|
class |
Binding0
Special purpose binding for nothing.
|
class |
Binding1
Special purpose binding for adding just one name/value slot.
|
class |
BindingBase
Machinary encapsulating a mapping from a name to a value.
|
class |
BindingFixed
A binding that is fixed - used in calculating DISTINCT result sets.
|
class |
BindingHashMap
A muatable mapping from a name to a value such that we can create a tree of levels
with higher (earlier levels) being shared.
|
class |
BindingProject |
class |
BindingProjectBase |
class |
BindingProjectNamed |
class |
BindingRoot
Special purpose binding for the root of all bindings.
|
class |
BindingWrapped
A binding that wraps another.
|
Modifier and Type | Field and Description |
---|---|
static Binding |
BindingFactory.noParent |
Modifier and Type | Method and Description |
---|---|
static Binding |
BindingUtils.asBinding(QuerySolution qSolution)
Convert a query solution to a binding
|
static Binding |
BindingFactory.binding()
Create a binding of no pairs
|
static Binding |
BindingFactory.binding(Binding parent)
Create a binding of no pairs
|
static Binding |
BindingFactory.binding(Binding parent,
Var var,
Node node)
Create a binding of one (var, value) pair
|
static Binding |
BindingFactory.binding(Var var,
Node node) |
static Binding |
BindingRoot.create() |
Binding |
BindingBase.getParent() |
Binding |
BindingWrapped.getWrapped() |
static Binding |
BindingFactory.materialize(Binding b)
Create a new Binding as a copy of an existing one.
|
Binding |
BindingInputStream.next() |
static Binding |
BindingFactory.root() |
Modifier and Type | Method and Description |
---|---|
void |
BindingMutable.addAll(Binding key)
Add all the var/node pairs from another binding
|
void |
BindingMap.addAll(Binding other)
Add all the (var, value) pairs from another binding
|
void |
BindingHashMap.addAll(Binding other) |
static void |
BindingUtils.addAll(BindingMap dest,
Binding src) |
static Binding |
BindingFactory.binding(Binding parent)
Create a binding of no pairs
|
static Binding |
BindingFactory.binding(Binding parent,
Var var,
Node node)
Create a binding of one (var, value) pair
|
int |
BindingComparator.compare(Binding bind1,
Binding bind2) |
static int |
BindingComparator.compareBindingsSyntactic(Binding bind1,
Binding bind2) |
static BindingMap |
BindingFactory.create(Binding parent) |
static boolean |
BindingUtils.equals(Binding b1,
Binding b2) |
static boolean |
BindingBase.equals(Binding bind1,
Binding bind2) |
static int |
BindingBase.hashCode(Binding bind) |
static Binding |
BindingFactory.materialize(Binding b)
Create a new Binding as a copy of an existing one.
|
void |
BindingOutputStream.send(Binding binding) |
void |
BindingOutputStream.write(Binding binding) |
Constructor and Description |
---|
BindingFixed(Binding binding) |
BindingHashMap(Binding parent)
Using BindingFactory.create is better
|
BindingProject(Collection<Var> vars,
Binding bind) |
BindingProject(Collection<Var> vars,
Binding bind,
Binding parent) |
BindingProjectBase(Binding bind) |
BindingProjectBase(Binding bind,
Binding parent) |
BindingProjectNamed(Binding bind) |
BindingProjectNamed(Binding bind,
Binding parent) |
BindingWrapped(Binding other) |
Modifier and Type | Method and Description |
---|---|
boolean |
HashIndexTable.containsCompatibleWithSharedDomain(Binding binding) |
boolean |
IndexTable.containsCompatibleWithSharedDomain(Binding binding) |
boolean |
LinearIndex.containsCompatibleWithSharedDomain(Binding bindingLeft) |
Modifier and Type | Method and Description |
---|---|
Binding |
QueryIterFilterExpr.accept(Binding binding) |
Binding |
QueryIterAssign.accept(Binding binding) |
Binding |
QueryIterAssignVarValue.accept(Binding binding) |
abstract Binding |
QueryIterProcessBinding.accept(Binding binding) |
Binding |
QueryIterConvert.Converter.convert(Binding obj) |
Binding |
QueryIterYieldN.getBinding() |
Binding |
QueryIterConvert.moveToNextBinding() |
Binding |
QueryIterProcessBinding.moveToNextBinding()
The next acceptable object in the iterator.
|
Binding |
QueryIteratorBase.next()
final - autoclose and registration relies on it - implement moveToNextBinding()
|
Binding |
QueryIteratorBase.nextBinding()
final - subclasses implement moveToNextBinding()
|
Binding |
QueryIterPeek.peek()
Returns the next binding without moving on.
|
Modifier and Type | Method and Description |
---|---|
Binding |
QueryIterFilterExpr.accept(Binding binding) |
Binding |
QueryIterAssign.accept(Binding binding) |
Binding |
QueryIterAssignVarValue.accept(Binding binding) |
abstract Binding |
QueryIterProcessBinding.accept(Binding binding) |
Binding |
QueryIterConvert.Converter.convert(Binding obj) |
static QueryIterSingleton |
QueryIterSingleton.create(Binding binding,
ExecutionContext execCxt) |
static QueryIterRoot |
QueryIterRoot.create(Binding binding,
ExecutionContext execCxt) |
static QueryIterSingleton |
QueryIterSingleton.create(Binding parent,
Var var,
Node value,
ExecutionContext execCxt) |
Modifier and Type | Method and Description |
---|---|
void |
QueryIterPlainWrapper.setIterator(Iterator<Binding> iterator)
Preferrable to use a constructor - but sometimes that is inconvenient
so pass null in the constructor and then call this before the iterator is
used.
|
Constructor and Description |
---|
QueryIterCommonParent(QueryIterator input,
Binding binding,
ExecutionContext execCxt) |
QueryIterDefaulting(QueryIterator cIter,
Binding _defaultObject,
ExecutionContext qCxt) |
QueryIterExtendByVar(Binding binding,
Var var,
Iterator<Node> members,
ExecutionContext execCxt) |
QueryIterYieldN(int num,
Binding b) |
QueryIterYieldN(int num,
Binding b,
ExecutionContext context) |
Constructor and Description |
---|
QueryIterPlainWrapper(Iterator<Binding> iter) |
QueryIterPlainWrapper(Iterator<Binding> iter,
ExecutionContext context) |
QueryIterSort(QueryIterator qIter,
Comparator<Binding> comparator,
ExecutionContext context) |
QueryIterTopN(QueryIterator qIter,
Comparator<Binding> comparator,
long numItems,
boolean distinct,
ExecutionContext context) |
Modifier and Type | Method and Description |
---|---|
QueryIterator |
QueryEngineMain.eval(Op op,
DatasetGraph dsg,
Binding input,
Context context) |
static QueryIterator |
QC.execute(Op op,
Binding binding,
ExecutionContext execCxt) |
static Op |
QC.substitute(Op op,
Binding binding) |
Constructor and Description |
---|
QueryEngineMain(Op op,
DatasetGraph dataset,
Binding input,
Context context) |
QueryEngineMain(Query query,
DatasetGraph dataset,
Binding input,
Context context) |
QueryEngineMainQuad(Op op,
DatasetGraph dataset,
Binding input,
Context context) |
QueryEngineMainQuad(Query query,
DatasetGraph dataset,
Binding input,
Context context) |
Modifier and Type | Method and Description |
---|---|
QueryIterator |
QueryEngineRef.eval(Op op,
DatasetGraph dsg,
Binding binding,
Context context) |
Constructor and Description |
---|
QueryEngineRef(Op op,
DatasetGraph dataset,
Binding input,
Context context) |
QueryEngineRefQuad(Op op,
DatasetGraph dataset,
Binding input,
Context context) |
Modifier and Type | Method and Description |
---|---|
Expr |
Expr.copySubstitute(Binding binding)
Deep copy with substitution
|
Expr |
ExprNode.copySubstitute(Binding binding) |
ExprList |
ExprList.copySubstitute(Binding binding) |
Expr |
ExprVar.copySubstitute(Binding binding,
boolean foldConstants) |
ExprAggregator |
ExprAggregator.copySubstitute(Binding binding,
boolean foldConstants) |
Expr |
Expr.copySubstitute(Binding binding,
boolean foldConstants) |
abstract Expr |
ExprNode.copySubstitute(Binding binding,
boolean foldConstants) |
Expr |
ExprFunction1.copySubstitute(Binding binding,
boolean foldConstants) |
Expr |
ExprFunctionN.copySubstitute(Binding binding,
boolean foldConstants) |
Expr |
E_Scalar.copySubstitute(Binding binding,
boolean foldConstants) |
Expr |
E_NotExists.copySubstitute(Binding binding,
boolean foldConstants) |
Expr |
ExprFunction0.copySubstitute(Binding binding,
boolean foldConstants) |
Expr |
ExprFunction2.copySubstitute(Binding binding,
boolean foldConstants) |
Expr |
NodeValue.copySubstitute(Binding binding,
boolean foldConstants) |
Expr |
E_Exists.copySubstitute(Binding binding,
boolean foldConstants) |
Expr |
ExprFunction3.copySubstitute(Binding binding,
boolean foldConstants) |
ExprList |
ExprList.copySubstitute(Binding binding,
boolean foldConstants) |
NodeValue |
ExprVar.eval(Binding binding,
FunctionEnv env) |
NodeValue |
ExprAggregator.eval(Binding binding,
FunctionEnv env) |
NodeValue |
Expr.eval(Binding binding,
FunctionEnv env)
Evaluate this expression against the binding
|
abstract NodeValue |
ExprNode.eval(Binding binding,
FunctionEnv env) |
NodeValue |
ExprFunction1.eval(Binding binding,
FunctionEnv env) |
NodeValue |
ExprFunctionN.eval(Binding binding,
FunctionEnv env) |
NodeValue |
ExprFunction0.eval(Binding binding,
FunctionEnv env) |
NodeValue |
ExprFunction2.eval(Binding binding,
FunctionEnv env) |
NodeValue |
NodeValue.eval(Binding binding,
FunctionEnv env) |
NodeValue |
ExprFunctionOp.eval(Binding binding,
FunctionEnv env) |
NodeValue |
ExprFunction3.eval(Binding binding,
FunctionEnv env) |
Node |
NodeValue.evalNode(Binding binding,
ExecutionContext execCxt) |
NodeValue |
E_Function.evalSpecial(Binding binding,
FunctionEnv env) |
NodeValue |
E_BNode.evalSpecial(Binding binding,
FunctionEnv env) |
NodeValue |
E_NotOneOf.evalSpecial(Binding binding,
FunctionEnv env) |
NodeValue |
E_OneOf.evalSpecial(Binding binding,
FunctionEnv env) |
NodeValue |
E_Bound.evalSpecial(Binding binding,
FunctionEnv env) |
NodeValue |
E_Coalesce.evalSpecial(Binding binding,
FunctionEnv env) |
NodeValue |
E_LogicalAnd.evalSpecial(Binding binding,
FunctionEnv env) |
NodeValue |
E_Call.evalSpecial(Binding binding,
FunctionEnv env) |
NodeValue |
E_LogicalOr.evalSpecial(Binding binding,
FunctionEnv env) |
boolean |
ExprList.isSatisfied(Binding binding,
ExecutionContext execCxt) |
boolean |
Expr.isSatisfied(Binding binding,
FunctionEnv execCxt)
Test whether a Constraint is satisfied, given a set of bindings
Includes error propagtion and Effective Boolean Value rules.
|
boolean |
ExprNode.isSatisfied(Binding binding,
FunctionEnv funcEnv) |
Modifier and Type | Method and Description |
---|---|
void |
Accumulator.accumulate(Binding binding,
FunctionEnv functionEnv) |
Node |
AggregatorBase.getValue(Binding key) |
Modifier and Type | Method and Description |
---|---|
NodeValue |
FunctionBase.exec(Binding binding,
ExprList args,
String uri,
FunctionEnv env) |
NodeValue |
Function.exec(Binding binding,
ExprList args,
String uri,
FunctionEnv env)
Test a list of values - argument will not be null but
may have the wrong number of arguments.
|
Modifier and Type | Method and Description |
---|---|
NodeValue |
eval.exec(Binding binding,
ExprList args,
String uri,
FunctionEnv env)
Processes unevaluated arguments
|
NodeValue |
FN_Matches.exec(Binding binding,
ExprList args,
String uri,
FunctionEnv env) |
Modifier and Type | Method and Description |
---|---|
NodeValue |
UserDefinedFunction.exec(Binding binding,
ExprList args,
String uri,
FunctionEnv env)
Executes the function
|
Modifier and Type | Method and Description |
---|---|
static Quad |
TemplateLib.subst(Quad quad,
Binding b,
Map<Node,Node> bNodeMap)
Substitute into a quad, with rewriting of bNodes
|
static Triple |
TemplateLib.subst(Triple triple,
Binding b,
Map<Node,Node> bNodeMap)
Substitute into a triple, with rewriting of bNodes
|
Modifier and Type | Method and Description |
---|---|
static Iterator<Quad> |
TemplateLib.calcQuads(List<Quad> quads,
Iterator<Binding> bindings)
Substitute into quad patterns
|
static Iterator<Triple> |
TemplateLib.calcTriples(List<Triple> triples,
Iterator<Binding> bindings)
Substitute into triple patterns
|
static Iterator<Quad> |
TemplateLib.template(List<Quad> quads,
Node dftGraph,
Iterator<Binding> bindings)
Take a template, as a list of quad patterns, a default graph, and an iterator of bindings,
and produce an iterator of quads that results from applying the template to the bindings.
|
Modifier and Type | Method and Description |
---|---|
QueryIterator |
PathPropertyFunction.execEvaluated(Binding binding,
Node subject,
Node predicate,
Node object,
ExecutionContext execCxt) |
static QueryIterator |
PathLib.execTriplePath(Binding binding,
Node s,
Path path,
Node o,
ExecutionContext execCxt) |
static QueryIterator |
PathLib.execTriplePath(Binding binding,
TriplePath triplePath,
ExecutionContext execCxt) |
Modifier and Type | Method and Description |
---|---|
abstract QueryIterator |
PropertyFunctionBase.exec(Binding binding,
PropFuncArg argSubject,
Node predicate,
PropFuncArg argObject,
ExecutionContext execCxt) |
QueryIterator |
PropertyFunctionEval.exec(Binding binding,
PropFuncArg argSubject,
Node predicate,
PropFuncArg argObject,
ExecutionContext execCxt) |
QueryIterator |
PFuncAssignToSubject.execEvaluated(Binding binding,
Node subject,
Node predicate,
Node object,
ExecutionContext execCxt) |
abstract QueryIterator |
PFuncSimple.execEvaluated(Binding binding,
Node subject,
Node predicate,
Node object,
ExecutionContext execCxt) |
abstract QueryIterator |
PFuncSimpleAndList.execEvaluated(Binding binding,
Node subject,
Node predicate,
PropFuncArg object,
ExecutionContext execCxt) |
QueryIterator |
PFuncSimpleAndList.execEvaluated(Binding binding,
PropFuncArg argSubject,
Node predicate,
PropFuncArg argObject,
ExecutionContext execCxt) |
QueryIterator |
PFuncSimple.execEvaluated(Binding binding,
PropFuncArg argSubject,
Node predicate,
PropFuncArg argObject,
ExecutionContext execCxt) |
abstract QueryIterator |
PropertyFunctionEval.execEvaluated(Binding binding,
PropFuncArg argSubject,
Node predicate,
PropFuncArg argObject,
ExecutionContext execCxt) |
Modifier and Type | Method and Description |
---|---|
QueryIterator |
assign.execEvaluated(Binding binding,
Node subject,
Node predicate,
Node object,
ExecutionContext execCxt) |
QueryIterator |
container.execEvaluated(Binding binding,
Node containerNode,
Node predicate,
Node member,
ExecutionContext execCxt) |
QueryIterator |
str.execEvaluated(Binding binding,
Node subject,
Node predicate,
Node object,
ExecutionContext execCxt) |
QueryIterator |
blankNode.execEvaluated(Binding binding,
Node subject,
Node predicate,
Node object,
ExecutionContext execCxt) |
QueryIterator |
concat.execEvaluated(Binding binding,
Node subject,
Node predicate,
PropFuncArg object,
ExecutionContext execCxt) |
QueryIterator |
versionARQ.execEvaluated(Binding binding,
PropFuncArg subject,
Node predicate,
PropFuncArg object,
ExecutionContext execCxt) |
QueryIterator |
version.execEvaluated(Binding binding,
PropFuncArg subject,
Node predicate,
PropFuncArg object,
ExecutionContext execCxt) |
QueryIterator |
splitIRI.execEvaluated(Binding binding,
PropFuncArg argSubject,
Node predicate,
PropFuncArg argObject,
ExecutionContext execCxt) |
QueryIterator |
ListBase.execEvaluated(Binding binding,
PropFuncArg argSubject,
Node predicate,
PropFuncArg argObject,
ExecutionContext execCxt)
If the subject is a list (well, at least not an unbound variable), dispatch to execOneList
else dispatch to one of object a var, a list or a node.
|
QueryIterator |
listLength.execOneList(Binding binding,
Node listNode,
Node predicate,
Node length,
ExecutionContext execCxt) |
Modifier and Type | Method and Description |
---|---|
QueryIterator |
ProcedureEval.exec(Binding binding,
Node name,
ExprList args,
ExecutionContext execCxt) |
abstract QueryIterator |
ProcedureBase.exec(Binding binding,
Node name,
ExprList args,
ExecutionContext execCxt) |
abstract QueryIterator |
ProcedureEval.execEval(Binding binding,
ExprList args,
ExecutionContext execCxt) |
Modifier and Type | Method and Description |
---|---|
QueryIterator |
debug.execEval(Binding binding,
ExprList args,
ExecutionContext execCxt) |
Modifier and Type | Method and Description |
---|---|
Binding |
ResultSetMem.nextBinding() |
Binding |
SortedResultSet.nextBinding() |
Binding |
ResultSetPeeking.nextBinding() |
Binding |
ResultSetMem.peekBinding() |
Binding |
ResultSetPeeking.peekBinding() |
Binding |
ResultSetPeekable.peekBinding()
Peek at the next binding
|
Modifier and Type | Method and Description |
---|---|
static boolean |
ResultSetCompare.equal(Binding bind1,
Binding bind2,
NodeUtils.EqualityTest test)
Compare two bindings, use the node equality test provided
|
Modifier and Type | Method and Description |
---|---|
static boolean |
ResultSetCompare.equalsByTest(Collection<Binding> b1,
Collection<Binding> b2,
NodeUtils.EqualityTest match) |
static boolean |
ResultSetCompare.equalsByTest(Collection<Binding> b1,
Collection<Binding> b2,
NodeUtils.EqualityTest match) |
Modifier and Type | Method and Description |
---|---|
static void |
QuerySerializer.outputDataBlock(IndentedWriter out,
List<Var> variables,
List<Binding> values,
Prologue prologue) |
Modifier and Type | Method and Description |
---|---|
static Binding |
BuilderBinding.build(Item item) |
Modifier and Type | Method and Description |
---|---|
static void |
WriterTable.output(IndentedWriter out,
Binding binding,
SerializationContext sCxt) |
Modifier and Type | Method and Description |
---|---|
List<Binding> |
ElementData.getRows() |
Modifier and Type | Method and Description |
---|---|
void |
ElementData.add(Binding binding) |
void |
Template.subst(Collection<Triple> acc,
Map<Node,Node> bNodeMap,
Binding b) |
Modifier and Type | Method and Description |
---|---|
static NodeValue |
ExprUtils.eval(Expr expr,
Binding binding) |
static void |
ExprUtils.evalPrint(Expr expr,
Binding binding) |
static void |
ExprUtils.expr(String exprStr,
Binding binding) |
static void |
ExprUtils.exprPrefix(String string,
Binding binding) |
static QueryIterator |
IterLib.oneResult(Binding binding,
Var var,
Node value,
ExecutionContext execCxt) |
static QueryIterator |
IterLib.result(Binding binding,
ExecutionContext execCxt) |
Modifier and Type | Method and Description |
---|---|
static SerializationFactory<Binding> |
SerializationFactoryFinder.bindingSerializationFactory() |
Licenced under the Apache License, Version 2.0