ExprModel { public <T extends Expr> T register(T expr) { Preconditions.check(!mSealed, "Cannot add expressions to a model after it is sealed"); Location location = null; if (mCurrentParserContext != null) { location = new Location(mCurrentParserContext); location.setParentLocation(mCurrentLocationInFile); } T existing = (T) mExprMap.get(expr.getUniqueKey()); if (existing != null) { Preconditions.check(expr.getParents().isEmpty(), "If an expression already exists, it should've never been added to a parent," + "if thats the case, somewhere we are creating an expression w/o" + "calling expression model"); expr.onSwappedWith(existing); if (location != null) { existing.addLocation(location); } return existing; } mExprMap.put(expr.getUniqueKey(), expr); expr.setModel(this); if (location != null) { expr.addLocation(location); } return expr; }  T register(T expr); ExprModelExt getExt(); int obtainCallbackId(); void setCurrentParserContext(ParserRuleContext currentParserContext); ParserRuleContext getCurrentParserContext(); Location getCurrentLocationInFile(); Map<String, Expr> getExprMap(); int size(); ComparisonExpr comparison(String op, Expr left, Expr right); InstanceOfExpr instanceOfOp(Expr expr, String type); FieldAccessExpr field(Expr parent, String name); FieldAccessExpr observableField(Expr parent, String name); MethodReferenceExpr methodReference(Expr parent, String name); SymbolExpr symbol(String text, Class type); TernaryExpr ternary(Expr pred, Expr ifTrue, Expr ifFalse); IdentifierExpr identifier(String name); StaticIdentifierExpr staticIdentifier(String name); BuiltInVariableExpr builtInVariable(String name, String type, String accessCode); ViewFieldExpr viewFieldExpr(BindingTarget bindingTarget); StaticIdentifierExpr staticIdentifierFor(final ModelClass modelClass); MethodCallExpr methodCall(Expr target, String name, List<Expr> args); MathExpr math(Expr left, String op, Expr right); TernaryExpr logical(Expr left, String op, Expr right); BitShiftExpr bitshift(Expr left, String op, Expr right); UnaryExpr unary(String op, Expr expr); Expr resourceExpr(BindingTarget target, String packageName, String resourceType,
            String resourceName, List<Expr> args); Expr bracketExpr(Expr variableExpr, Expr argExpr); Expr castExpr(String type, Expr expr); TwoWayListenerExpr twoWayListenerExpr(InverseBinding inverseBinding); List<Expr> getBindingExpressions(); StaticIdentifierExpr addImport(String alias, String type, Location location); Map<String, String> getImports(); Expr bindingExpr(Expr bindingExpr); void removeExpr(Expr expr); List<Expr> getObservables(); void seal(); int getFlagBucketCount(); int getTotalFlagCount(); int getInvalidateableFieldLimit(); String[] getFlagMapping(); String getFlag(int id); List<Expr> getPendingExpressions(); boolean markBitsRead(); static ArrayList<Expr> filterShouldRead(Iterable<Expr> exprs); Expr findFlagExpression(int flag); BitSet getInvalidateAnyBitSet(); int getInvalidateAnyFlagIndex(); Expr argListExpr(Iterable<Expr> expressions); void setCurrentLocationInFile(Location location); Expr listenerExpr(Expr expression, String name, ModelClass listenerType,
            ModelMethod listenerMethod); FieldAssignmentExpr assignment(Expr target, String name, Expr value); Map<String, CallbackWrapper> getCallbackWrappers(); CallbackWrapper callbackWrapper(ModelClass klass, ModelMethod method); LambdaExpr lambdaExpr(Expr expr, CallbackExprModel callbackExprModel); IdentifierExpr findIdentifier(String name);  }
@Test public void testAddWithChildren() { DummyExpr a = new DummyExpr("a"); DummyExpr b = new DummyExpr("b"); DummyExpr c = new DummyExpr("c", a, b); mExprModel.register(c); DummyExpr a2 = new DummyExpr("a"); DummyExpr b2 = new DummyExpr("b"); DummyExpr c2 = new DummyExpr("c", a, b); assertEquals(c, mExprModel.register(c2)); }