1 /*
   2  * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package test.javafx.binding;
  27 
  28 import static org.junit.Assert.assertEquals;
  29 
  30 import java.util.Arrays;
  31 import java.util.Collection;
  32 
  33 import test.javafx.beans.InvalidationListenerMock;
  34 import javafx.beans.binding.Bindings;
  35 import javafx.beans.binding.BooleanBinding;
  36 import javafx.beans.property.DoubleProperty;
  37 import javafx.beans.property.FloatProperty;
  38 import javafx.beans.property.IntegerProperty;
  39 import javafx.beans.property.LongProperty;
  40 import javafx.beans.property.ObjectProperty;
  41 import javafx.beans.property.SimpleDoubleProperty;
  42 import javafx.beans.property.SimpleFloatProperty;
  43 import javafx.beans.property.SimpleIntegerProperty;
  44 import javafx.beans.property.SimpleLongProperty;
  45 import javafx.beans.property.SimpleObjectProperty;
  46 import javafx.beans.property.SimpleStringProperty;
  47 import javafx.beans.property.StringProperty;
  48 import javafx.beans.value.*;
  49 
  50 import org.junit.Before;
  51 import org.junit.Test;
  52 import org.junit.runner.RunWith;
  53 import org.junit.runners.Parameterized;
  54 
  55 @RunWith(Parameterized.class)
  56 public class BindingsEqualsTest<T> {
  57 
  58     private static final float EPSILON_FLOAT = 1e-5f;
  59     private static final double EPSILON_DOUBLE = 1e-10;
  60 
  61     public static interface Functions<T> {
  62         BooleanBinding generateExpressionExpression(Object op1, Object op2);
  63         BooleanBinding generateExpressionPrimitive(Object op1, T op2);
  64         BooleanBinding generatePrimitiveExpression(T op1, Object op2);
  65         void setOp1(T value);
  66         void setOp2(T value);
  67         void check(T op1, T op2, BooleanBinding exp);
  68     }
  69 
  70     private final ObservableValue op1;
  71     private final ObservableValue op2;
  72     private final Functions<T> func;
  73     private final T[] v;
  74     private InvalidationListenerMock observer;
  75 
  76     public BindingsEqualsTest(ObservableValue op1, ObservableValue op2, Functions<T> func, T... v) {
  77         this.op1 = op1;
  78         this.op2 = op2;
  79         this.func = func;
  80         this.v = v;
  81     }
  82 
  83     private static String makeSafe(String value) {
  84         return value == null? "" : value;
  85     }
  86 
  87     @Before
  88     public void setUp() {
  89         func.setOp1(v[0]);
  90         func.setOp2(v[1]);
  91         observer = new InvalidationListenerMock();
  92     }
  93 
  94     @Test
  95     public void test_Expression_Expression() {
  96         final BooleanBinding binding = func.generateExpressionExpression(op1, op2);
  97         binding.addListener(observer);
  98 
  99         // check initial value
 100         func.check(v[0], v[1], binding);
 101         DependencyUtils.checkDependencies(binding.getDependencies(), op1, op2);
 102 
 103         // change first operand
 104         observer.reset();
 105         func.setOp1(v[1]);
 106         func.check(v[1], v[1], binding);
 107         observer.check(binding, 1);
 108 
 109         // change second operand
 110         func.setOp2(v[0]);
 111         func.check(v[1], v[0], binding);
 112         observer.check(binding, 1);
 113 
 114         // change both operands
 115         func.setOp1(v[0]);
 116         func.setOp2(v[1]);
 117         func.check(v[0], v[1], binding);
 118         observer.check(binding, 1);
 119     }
 120 
 121     @Test
 122     public void test_Self() {
 123         // using same FloatValue twice
 124         final BooleanBinding binding = func.generateExpressionExpression(op1, op1);
 125         binding.addListener(observer);
 126 
 127         // check initial value
 128         func.check(v[0], v[0], binding);
 129 
 130         // change value
 131         func.setOp1(v[1]);
 132         func.check(v[1], v[1], binding);
 133         observer.check(binding, 1);
 134     }
 135 
 136     @Test(expected=NullPointerException.class)
 137     public void test_null_Expression() {
 138         func.generateExpressionExpression(null, op1);
 139     }
 140 
 141     @Test(expected=NullPointerException.class)
 142     public void test_Expression_null() {
 143         func.generateExpressionExpression(op1, null);
 144     }
 145 
 146     @Test
 147     public void test_Expression_Primitive() {
 148         final BooleanBinding binding = func.generateExpressionPrimitive(op1, v[1]);
 149         binding.addListener(observer);
 150 
 151         // check initial value
 152         func.check(v[0], v[1], binding);
 153         DependencyUtils.checkDependencies(binding.getDependencies(), op1);
 154 
 155         // change first operand
 156         observer.reset();
 157         func.setOp1(v[1]);
 158         func.check(v[1], v[1], binding);
 159         observer.check(binding, 1);
 160 
 161         // change to highest value
 162         func.setOp1(v[2]);
 163         func.check(v[2], v[1], binding);
 164         observer.check(binding, 1);
 165     }
 166 
 167     @Test(expected=NullPointerException.class)
 168     public void test_null_Primitive() {
 169         func.generateExpressionPrimitive(null, v[0]);
 170     }
 171 
 172     @Test
 173     public void test_Primitive_Expression() {
 174         final BooleanBinding binding = func.generatePrimitiveExpression(v[1], op1);
 175         binding.addListener(observer);
 176 
 177         // check initial value
 178         func.check(v[1], v[0], binding);
 179         DependencyUtils.checkDependencies(binding.getDependencies(), op1);
 180 
 181         // change first operand
 182         observer.reset();
 183         func.setOp1(v[1]);
 184         func.check(v[1], v[1], binding);
 185         observer.check(binding, 1);
 186 
 187         // change to highest value
 188         func.setOp1(v[2]);
 189         func.check(v[1], v[2], binding);
 190         observer.check(binding, 1);
 191     }
 192 
 193     @Test(expected=NullPointerException.class)
 194     public void test_Primitive_null() {
 195         func.generatePrimitiveExpression(v[0], null);
 196     }
 197 
 198     @Parameterized.Parameters
 199     public static Collection<Object[]> parameters() {
 200         final FloatProperty float1 = new SimpleFloatProperty();
 201         final FloatProperty float2 = new SimpleFloatProperty();
 202         final Float[] floatData = new Float[] {-EPSILON_FLOAT, 0.0f, EPSILON_FLOAT};
 203 
 204         final DoubleProperty double1 = new SimpleDoubleProperty();
 205         final DoubleProperty double2 = new SimpleDoubleProperty();
 206         final Double[] doubleData = new Double[] {-EPSILON_DOUBLE, 0.0, EPSILON_DOUBLE};
 207 
 208         final IntegerProperty int1 = new SimpleIntegerProperty();
 209         final IntegerProperty int2 = new SimpleIntegerProperty();
 210         final Integer[] integerData = new Integer[] {-1, 0, 1};
 211 
 212         final LongProperty long1 = new SimpleLongProperty();
 213         final LongProperty long2 = new SimpleLongProperty();
 214         final Long[] longData = new Long[] {-1L, 0L, 1L};
 215 
 216         final StringProperty string1 = new SimpleStringProperty();
 217         final StringProperty string2 = new SimpleStringProperty();
 218         final String[] stringData = new String[] {null, "Hello", "Hello World"};
 219         final String[] ciStringData = new String[] {null, "hello", "HELLO"};
 220 
 221         final ObjectProperty<Object> object1 = new SimpleObjectProperty<Object>();
 222         final ObjectProperty<Object> object2 = new SimpleObjectProperty<Object>();
 223         final Object[] objectData = new Object[] {new Object(), new Object(), new Object()};
 224 
 225         return Arrays.asList(new Object[][] {
 226             {
 227                 float1, float2,
 228                 new Functions<Float>() {
 229                     @Override
 230                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 231                         return Bindings.equal((ObservableFloatValue)op1, (ObservableFloatValue)op2, EPSILON_FLOAT);
 232                     }
 233                     @Override
 234                     public BooleanBinding generateExpressionPrimitive(Object op1, Float op2) {
 235                         return Bindings.equal((ObservableFloatValue)op1, op2.floatValue(), EPSILON_FLOAT);
 236                     }
 237                     @Override
 238                     public BooleanBinding generatePrimitiveExpression(Float op1, Object op2) {
 239                         return Bindings.equal(op1.floatValue(), (ObservableFloatValue)op2, EPSILON_FLOAT);
 240                     }
 241                     @Override
 242                     public void setOp1(Float value) {float1.set(value);}
 243                     @Override
 244                     public void setOp2(Float value) {float2.set(value);}
 245                     @Override
 246                     public void check(Float op1, Float op2, BooleanBinding exp) {
 247                         assertEquals(Math.abs(op1 - op2) <= EPSILON_FLOAT, exp.get());
 248                     }
 249                 },
 250                 floatData
 251             },
 252             {
 253                 float1, float2,
 254                 new Functions<Float>() {
 255                     @Override
 256                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 257                         return Bindings.notEqual((ObservableFloatValue)op1, (ObservableFloatValue)op2, EPSILON_FLOAT);
 258                     }
 259                     @Override
 260                     public BooleanBinding generateExpressionPrimitive(Object op1, Float op2) {
 261                         return Bindings.notEqual((ObservableFloatValue)op1, op2.floatValue(), EPSILON_FLOAT);
 262                     }
 263                     @Override
 264                     public BooleanBinding generatePrimitiveExpression(Float op1, Object op2) {
 265                         return Bindings.notEqual(op1.floatValue(), (ObservableFloatValue)op2, EPSILON_FLOAT);
 266                     }
 267                     @Override
 268                     public void setOp1(Float value) {float1.set(value);}
 269                     @Override
 270                     public void setOp2(Float value) {float2.set(value);}
 271                     @Override
 272                     public void check(Float op1, Float op2, BooleanBinding exp) {
 273                         assertEquals(Math.abs(op1 - op2) > EPSILON_FLOAT, exp.get());
 274                     }
 275                 },
 276                 floatData
 277             },
 278             {
 279                 float1, float2,
 280                 new Functions<Float>() {
 281                     @Override
 282                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 283                         return Bindings.greaterThan((ObservableFloatValue)op1, (ObservableFloatValue)op2);
 284                     }
 285                     @Override
 286                     public BooleanBinding generateExpressionPrimitive(Object op1, Float op2) {
 287                         return Bindings.greaterThan((ObservableFloatValue)op1, op2.floatValue());
 288                     }
 289                     @Override
 290                     public BooleanBinding generatePrimitiveExpression(Float op1, Object op2) {
 291                         return Bindings.greaterThan(op1.floatValue(), (ObservableFloatValue)op2);
 292                     }
 293                     @Override
 294                     public void setOp1(Float value) {float1.set(value);}
 295                     @Override
 296                     public void setOp2(Float value) {float2.set(value);}
 297                     @Override
 298                     public void check(Float op1, Float op2, BooleanBinding exp) {
 299                         assertEquals(op1 > op2, exp.get());
 300                     }
 301                 },
 302                 floatData
 303             },
 304             {
 305                 float1, float2,
 306                 new Functions<Float>() {
 307                     @Override
 308                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 309                         return Bindings.lessThan((ObservableFloatValue)op1, (ObservableFloatValue)op2);
 310                     }
 311                     @Override
 312                     public BooleanBinding generateExpressionPrimitive(Object op1, Float op2) {
 313                         return Bindings.lessThan((ObservableFloatValue)op1, op2.floatValue());
 314                     }
 315                     @Override
 316                     public BooleanBinding generatePrimitiveExpression(Float op1, Object op2) {
 317                         return Bindings.lessThan(op1.floatValue(), (ObservableFloatValue)op2);
 318                     }
 319                     @Override
 320                     public void setOp1(Float value) {float1.set(value);}
 321                     @Override
 322                     public void setOp2(Float value) {float2.set(value);}
 323                     @Override
 324                     public void check(Float op1, Float op2, BooleanBinding exp) {
 325                         assertEquals(op1 < op2, exp.get());
 326                     }
 327                 },
 328                 floatData
 329             },
 330             {
 331                 float1, float2,
 332                 new Functions<Float>() {
 333                     @Override
 334                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 335                         return Bindings.greaterThanOrEqual((ObservableFloatValue)op1, (ObservableFloatValue)op2);
 336                     }
 337                     @Override
 338                     public BooleanBinding generateExpressionPrimitive(Object op1, Float op2) {
 339                         return Bindings.greaterThanOrEqual((ObservableFloatValue)op1, op2.floatValue());
 340                     }
 341                     @Override
 342                     public BooleanBinding generatePrimitiveExpression(Float op1, Object op2) {
 343                         return Bindings.greaterThanOrEqual(op1.floatValue(), (ObservableFloatValue)op2);
 344                     }
 345                     @Override
 346                     public void setOp1(Float value) {float1.set(value);}
 347                     @Override
 348                     public void setOp2(Float value) {float2.set(value);}
 349                     @Override
 350                     public void check(Float op1, Float op2, BooleanBinding exp) {
 351                         assertEquals(op1 >= op2, exp.get());
 352                     }
 353                 },
 354                 floatData
 355             },
 356             {
 357                 float1, float2,
 358                 new Functions<Float>() {
 359                     @Override
 360                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 361                         return Bindings.lessThanOrEqual((ObservableFloatValue)op1, (ObservableFloatValue)op2);
 362                     }
 363                     @Override
 364                     public BooleanBinding generateExpressionPrimitive(Object op1, Float op2) {
 365                         return Bindings.lessThanOrEqual((ObservableFloatValue)op1, op2.floatValue());
 366                     }
 367                     @Override
 368                     public BooleanBinding generatePrimitiveExpression(Float op1, Object op2) {
 369                         return Bindings.lessThanOrEqual(op1.floatValue(), (ObservableFloatValue)op2);
 370                     }
 371                     @Override
 372                     public void setOp1(Float value) {float1.set(value);}
 373                     @Override
 374                     public void setOp2(Float value) {float2.set(value);}
 375                     @Override
 376                     public void check(Float op1, Float op2, BooleanBinding exp) {
 377                         assertEquals(op1 <= op2, exp.get());
 378                     }
 379                 },
 380                 floatData
 381             },
 382 
 383 
 384 
 385             // double
 386             {
 387                 double1, double2,
 388                 new Functions<Double>() {
 389                     @Override
 390                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 391                         return Bindings.equal((ObservableDoubleValue)op1, (ObservableDoubleValue)op2, EPSILON_DOUBLE);
 392                     }
 393                     @Override
 394                     public BooleanBinding generateExpressionPrimitive(Object op1, Double op2) {
 395                         return Bindings.equal((ObservableDoubleValue)op1, op2.doubleValue(), EPSILON_DOUBLE);
 396                     }
 397                     @Override
 398                     public BooleanBinding generatePrimitiveExpression(Double op1, Object op2) {
 399                         return Bindings.equal(op1.doubleValue(), (ObservableDoubleValue)op2, EPSILON_DOUBLE);
 400                     }
 401                     @Override
 402                     public void setOp1(Double value) {double1.set(value);}
 403                     @Override
 404                     public void setOp2(Double value) {double2.set(value);}
 405                     @Override
 406                     public void check(Double op1, Double op2, BooleanBinding exp) {
 407                         assertEquals(Math.abs(op1 - op2) <= EPSILON_DOUBLE, exp.get());
 408                     }
 409                 },
 410                 doubleData
 411             },
 412             {
 413                 double1, double2,
 414                 new Functions<Double>() {
 415                     @Override
 416                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 417                         return Bindings.notEqual((ObservableDoubleValue)op1, (ObservableDoubleValue)op2, EPSILON_DOUBLE);
 418                     }
 419                     @Override
 420                     public BooleanBinding generateExpressionPrimitive(Object op1, Double op2) {
 421                         return Bindings.notEqual((ObservableDoubleValue)op1, op2.doubleValue(), EPSILON_DOUBLE);
 422                     }
 423                     @Override
 424                     public BooleanBinding generatePrimitiveExpression(Double op1, Object op2) {
 425                         return Bindings.notEqual(op1.doubleValue(), (ObservableDoubleValue)op2, EPSILON_DOUBLE);
 426                     }
 427                     @Override
 428                     public void setOp1(Double value) {double1.set(value);}
 429                     @Override
 430                     public void setOp2(Double value) {double2.set(value);}
 431                     @Override
 432                     public void check(Double op1, Double op2, BooleanBinding exp) {
 433                         assertEquals(Math.abs(op1 - op2) > EPSILON_DOUBLE, exp.get());
 434                     }
 435                 },
 436                 doubleData
 437             },
 438             {
 439                 double1, double2,
 440                 new Functions<Double>() {
 441                     @Override
 442                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 443                         return Bindings.greaterThan((ObservableDoubleValue)op1, (ObservableDoubleValue)op2);
 444                     }
 445                     @Override
 446                     public BooleanBinding generateExpressionPrimitive(Object op1, Double op2) {
 447                         return Bindings.greaterThan((ObservableDoubleValue)op1, op2.doubleValue());
 448                     }
 449                     @Override
 450                     public BooleanBinding generatePrimitiveExpression(Double op1, Object op2) {
 451                         return Bindings.greaterThan(op1.doubleValue(), (ObservableDoubleValue)op2);
 452                     }
 453                     @Override
 454                     public void setOp1(Double value) {double1.set(value);}
 455                     @Override
 456                     public void setOp2(Double value) {double2.set(value);}
 457                     @Override
 458                     public void check(Double op1, Double op2, BooleanBinding exp) {
 459                         assertEquals(op1 > op2, exp.get());
 460                     }
 461                 },
 462                 doubleData
 463             },
 464             {
 465                 double1, double2,
 466                 new Functions<Double>() {
 467                     @Override
 468                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 469                         return Bindings.lessThan((ObservableDoubleValue)op1, (ObservableDoubleValue)op2);
 470                     }
 471                     @Override
 472                     public BooleanBinding generateExpressionPrimitive(Object op1, Double op2) {
 473                         return Bindings.lessThan((ObservableDoubleValue)op1, op2.doubleValue());
 474                     }
 475                     @Override
 476                     public BooleanBinding generatePrimitiveExpression(Double op1, Object op2) {
 477                         return Bindings.lessThan(op1.doubleValue(), (ObservableDoubleValue)op2);
 478                     }
 479                     @Override
 480                     public void setOp1(Double value) {double1.set(value);}
 481                     @Override
 482                     public void setOp2(Double value) {double2.set(value);}
 483                     @Override
 484                     public void check(Double op1, Double op2, BooleanBinding exp) {
 485                         assertEquals(op1 < op2, exp.get());
 486                     }
 487                 },
 488                 doubleData
 489             },
 490             {
 491                 double1, double2,
 492                 new Functions<Double>() {
 493                     @Override
 494                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 495                         return Bindings.greaterThanOrEqual((ObservableDoubleValue)op1, (ObservableDoubleValue)op2);
 496                     }
 497                     @Override
 498                     public BooleanBinding generateExpressionPrimitive(Object op1, Double op2) {
 499                         return Bindings.greaterThanOrEqual((ObservableDoubleValue)op1, op2.doubleValue());
 500                     }
 501                     @Override
 502                     public BooleanBinding generatePrimitiveExpression(Double op1, Object op2) {
 503                         return Bindings.greaterThanOrEqual(op1.doubleValue(), (ObservableDoubleValue)op2);
 504                     }
 505                     @Override
 506                     public void setOp1(Double value) {double1.set(value);}
 507                     @Override
 508                     public void setOp2(Double value) {double2.set(value);}
 509                     @Override
 510                     public void check(Double op1, Double op2, BooleanBinding exp) {
 511                         assertEquals(op1 >= op2, exp.get());
 512                     }
 513                 },
 514                 doubleData
 515             },
 516             {
 517                 double1, double2,
 518                 new Functions<Double>() {
 519                     @Override
 520                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 521                         return Bindings.lessThanOrEqual((ObservableDoubleValue)op1, (ObservableDoubleValue)op2);
 522                     }
 523                     @Override
 524                     public BooleanBinding generateExpressionPrimitive(Object op1, Double op2) {
 525                         return Bindings.lessThanOrEqual((ObservableDoubleValue)op1, op2.doubleValue());
 526                     }
 527                     @Override
 528                     public BooleanBinding generatePrimitiveExpression(Double op1, Object op2) {
 529                         return Bindings.lessThanOrEqual(op1.doubleValue(), (ObservableDoubleValue)op2);
 530                     }
 531                     @Override
 532                     public void setOp1(Double value) {double1.set(value);}
 533                     @Override
 534                     public void setOp2(Double value) {double2.set(value);}
 535                     @Override
 536                     public void check(Double op1, Double op2, BooleanBinding exp) {
 537                         assertEquals(op1 <= op2, exp.get());
 538                     }
 539                 },
 540                 doubleData
 541             },
 542 
 543 
 544 
 545             // integer
 546             {
 547                 int1, int2,
 548                 new Functions<Integer>() {
 549                     @Override
 550                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 551                         return Bindings.equal((ObservableIntegerValue)op1, (ObservableIntegerValue)op2);
 552                     }
 553                     @Override
 554                     public BooleanBinding generateExpressionPrimitive(Object op1, Integer op2) {
 555                         return Bindings.equal((ObservableIntegerValue)op1, op2.intValue());
 556                     }
 557                     @Override
 558                     public BooleanBinding generatePrimitiveExpression(Integer op1, Object op2) {
 559                         return Bindings.equal(op1.intValue(), (ObservableIntegerValue)op2);
 560                     }
 561                     @Override
 562                     public void setOp1(Integer value) {int1.set(value);}
 563                     @Override
 564                     public void setOp2(Integer value) {int2.set(value);}
 565                     @Override
 566                     public void check(Integer op1, Integer op2, BooleanBinding exp) {
 567                         assertEquals(op1.equals(op2), exp.get());
 568                     }
 569                 },
 570                 integerData
 571             },
 572             {
 573                 int1, int2,
 574                 new Functions<Integer>() {
 575                     @Override
 576                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 577                         return Bindings.equal((ObservableIntegerValue)op1, (ObservableIntegerValue)op2, 1);
 578                     }
 579                     @Override
 580                     public BooleanBinding generateExpressionPrimitive(Object op1, Integer op2) {
 581                         return Bindings.equal((ObservableIntegerValue)op1, op2.intValue(), 1);
 582                     }
 583                     @Override
 584                     public BooleanBinding generatePrimitiveExpression(Integer op1, Object op2) {
 585                         return Bindings.equal(op1.intValue(), (ObservableIntegerValue)op2, 1);
 586                     }
 587                     @Override
 588                     public void setOp1(Integer value) {int1.set(value);}
 589                     @Override
 590                     public void setOp2(Integer value) {int2.set(value);}
 591                     @Override
 592                     public void check(Integer op1, Integer op2, BooleanBinding exp) {
 593                         assertEquals(Math.abs(op1 - op2) <= 1, exp.get());
 594                     }
 595                 },
 596                 integerData
 597             },
 598             {
 599                 int1, int2,
 600                 new Functions<Integer>() {
 601                     @Override
 602                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 603                         return Bindings.notEqual((ObservableIntegerValue)op1, (ObservableIntegerValue)op2);
 604                     }
 605                     @Override
 606                     public BooleanBinding generateExpressionPrimitive(Object op1, Integer op2) {
 607                         return Bindings.notEqual((ObservableIntegerValue)op1, op2.intValue());
 608                     }
 609                     @Override
 610                     public BooleanBinding generatePrimitiveExpression(Integer op1, Object op2) {
 611                         return Bindings.notEqual(op1.intValue(), (ObservableIntegerValue)op2);
 612                     }
 613                     @Override
 614                     public void setOp1(Integer value) {int1.set(value);}
 615                     @Override
 616                     public void setOp2(Integer value) {int2.set(value);}
 617                     @Override
 618                     public void check(Integer op1, Integer op2, BooleanBinding exp) {
 619                         assertEquals(!op1.equals(op2), exp.get());
 620                     }
 621                 },
 622                 integerData
 623             },
 624             {
 625                 int1, int2,
 626                 new Functions<Integer>() {
 627                     @Override
 628                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 629                         return Bindings.notEqual((ObservableIntegerValue)op1, (ObservableIntegerValue)op2, 1);
 630                     }
 631                     @Override
 632                     public BooleanBinding generateExpressionPrimitive(Object op1, Integer op2) {
 633                         return Bindings.notEqual((ObservableIntegerValue)op1, op2.intValue(), 1);
 634                     }
 635                     @Override
 636                     public BooleanBinding generatePrimitiveExpression(Integer op1, Object op2) {
 637                         return Bindings.notEqual(op1.intValue(), (ObservableIntegerValue)op2, 1);
 638                     }
 639                     @Override
 640                     public void setOp1(Integer value) {int1.set(value);}
 641                     @Override
 642                     public void setOp2(Integer value) {int2.set(value);}
 643                     @Override
 644                     public void check(Integer op1, Integer op2, BooleanBinding exp) {
 645                         assertEquals(Math.abs(op1 - op2) > 1, exp.get());
 646                     }
 647                 },
 648                 integerData
 649             },
 650             {
 651                 int1, int2,
 652                 new Functions<Integer>() {
 653                     @Override
 654                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 655                         return Bindings.greaterThan((ObservableIntegerValue)op1, (ObservableIntegerValue)op2);
 656                     }
 657                     @Override
 658                     public BooleanBinding generateExpressionPrimitive(Object op1, Integer op2) {
 659                         return Bindings.greaterThan((ObservableIntegerValue)op1, op2.intValue());
 660                     }
 661                     @Override
 662                     public BooleanBinding generatePrimitiveExpression(Integer op1, Object op2) {
 663                         return Bindings.greaterThan(op1.intValue(), (ObservableIntegerValue)op2);
 664                     }
 665                     @Override
 666                     public void setOp1(Integer value) {int1.set(value);}
 667                     @Override
 668                     public void setOp2(Integer value) {int2.set(value);}
 669                     @Override
 670                     public void check(Integer op1, Integer op2, BooleanBinding exp) {
 671                         assertEquals(op1 > op2, exp.get());
 672                     }
 673                 },
 674                 integerData
 675             },
 676             {
 677                 int1, int2,
 678                 new Functions<Integer>() {
 679                     @Override
 680                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 681                         return Bindings.lessThan((ObservableIntegerValue)op1, (ObservableIntegerValue)op2);
 682                     }
 683                     @Override
 684                     public BooleanBinding generateExpressionPrimitive(Object op1, Integer op2) {
 685                         return Bindings.lessThan((ObservableIntegerValue)op1, op2.intValue());
 686                     }
 687                     @Override
 688                     public BooleanBinding generatePrimitiveExpression(Integer op1, Object op2) {
 689                         return Bindings.lessThan(op1.intValue(), (ObservableIntegerValue)op2);
 690                     }
 691                     @Override
 692                     public void setOp1(Integer value) {int1.set(value);}
 693                     @Override
 694                     public void setOp2(Integer value) {int2.set(value);}
 695                     @Override
 696                     public void check(Integer op1, Integer op2, BooleanBinding exp) {
 697                         assertEquals(op1 < op2, exp.get());
 698                     }
 699                 },
 700                 integerData
 701             },
 702             {
 703                 int1, int2,
 704                 new Functions<Integer>() {
 705                     @Override
 706                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 707                         return Bindings.greaterThanOrEqual((ObservableIntegerValue)op1, (ObservableIntegerValue)op2);
 708                     }
 709                     @Override
 710                     public BooleanBinding generateExpressionPrimitive(Object op1, Integer op2) {
 711                         return Bindings.greaterThanOrEqual((ObservableIntegerValue)op1, op2.intValue());
 712                     }
 713                     @Override
 714                     public BooleanBinding generatePrimitiveExpression(Integer op1, Object op2) {
 715                         return Bindings.greaterThanOrEqual(op1.intValue(), (ObservableIntegerValue)op2);
 716                     }
 717                     @Override
 718                     public void setOp1(Integer value) {int1.set(value);}
 719                     @Override
 720                     public void setOp2(Integer value) {int2.set(value);}
 721                     @Override
 722                     public void check(Integer op1, Integer op2, BooleanBinding exp) {
 723                         assertEquals(op1 >= op2, exp.get());
 724                     }
 725                 },
 726                 integerData
 727             },
 728             {
 729                 int1, int2,
 730                 new Functions<Integer>() {
 731                     @Override
 732                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 733                         return Bindings.lessThanOrEqual((ObservableIntegerValue)op1, (ObservableIntegerValue)op2);
 734                     }
 735                     @Override
 736                     public BooleanBinding generateExpressionPrimitive(Object op1, Integer op2) {
 737                         return Bindings.lessThanOrEqual((ObservableIntegerValue)op1, op2.intValue());
 738                     }
 739                     @Override
 740                     public BooleanBinding generatePrimitiveExpression(Integer op1, Object op2) {
 741                         return Bindings.lessThanOrEqual(op1.intValue(), (ObservableIntegerValue)op2);
 742                     }
 743                     @Override
 744                     public void setOp1(Integer value) {int1.set(value);}
 745                     @Override
 746                     public void setOp2(Integer value) {int2.set(value);}
 747                     @Override
 748                     public void check(Integer op1, Integer op2, BooleanBinding exp) {
 749                         assertEquals(op1 <= op2, exp.get());
 750                     }
 751                 },
 752                 integerData
 753             },
 754 
 755 
 756 
 757             // long
 758             {
 759                 long1, long2,
 760                 new Functions<Long>() {
 761                     @Override
 762                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 763                         return Bindings.equal((ObservableLongValue)op1, (ObservableLongValue)op2);
 764                     }
 765                     @Override
 766                     public BooleanBinding generateExpressionPrimitive(Object op1, Long op2) {
 767                         return Bindings.equal((ObservableLongValue)op1, op2.longValue());
 768                     }
 769                     @Override
 770                     public BooleanBinding generatePrimitiveExpression(Long op1, Object op2) {
 771                         return Bindings.equal(op1.longValue(), (ObservableLongValue)op2);
 772                     }
 773                     @Override
 774                     public void setOp1(Long value) {long1.set(value);}
 775                     @Override
 776                     public void setOp2(Long value) {long2.set(value);}
 777                     @Override
 778                     public void check(Long op1, Long op2, BooleanBinding exp) {
 779                         assertEquals(op1.equals(op2), exp.get());
 780                     }
 781                 },
 782                 longData
 783             },
 784             {
 785                 long1, long2,
 786                 new Functions<Long>() {
 787                     @Override
 788                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 789                         return Bindings.equal((ObservableLongValue)op1, (ObservableLongValue)op2, 1);
 790                     }
 791                     @Override
 792                     public BooleanBinding generateExpressionPrimitive(Object op1, Long op2) {
 793                         return Bindings.equal((ObservableLongValue)op1, op2.longValue(), 1);
 794                     }
 795                     @Override
 796                     public BooleanBinding generatePrimitiveExpression(Long op1, Object op2) {
 797                         return Bindings.equal(op1.longValue(), (ObservableLongValue)op2, 1);
 798                     }
 799                     @Override
 800                     public void setOp1(Long value) {long1.set(value);}
 801                     @Override
 802                     public void setOp2(Long value) {long2.set(value);}
 803                     @Override
 804                     public void check(Long op1, Long op2, BooleanBinding exp) {
 805                         assertEquals(Math.abs(op1 - op2) <= 1, exp.get());
 806                     }
 807                 },
 808                 longData
 809             },
 810             {
 811                 long1, long2,
 812                 new Functions<Long>() {
 813                     @Override
 814                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 815                         return Bindings.notEqual((ObservableLongValue)op1, (ObservableLongValue)op2);
 816                     }
 817                     @Override
 818                     public BooleanBinding generateExpressionPrimitive(Object op1, Long op2) {
 819                         return Bindings.notEqual((ObservableLongValue)op1, op2.longValue());
 820                     }
 821                     @Override
 822                     public BooleanBinding generatePrimitiveExpression(Long op1, Object op2) {
 823                         return Bindings.notEqual(op1.longValue(), (ObservableLongValue)op2);
 824                     }
 825                     @Override
 826                     public void setOp1(Long value) {long1.set(value);}
 827                     @Override
 828                     public void setOp2(Long value) {long2.set(value);}
 829                     @Override
 830                     public void check(Long op1, Long op2, BooleanBinding exp) {
 831                         assertEquals(!op1.equals(op2), exp.get());
 832                     }
 833                 },
 834                 longData
 835             },
 836             {
 837                 long1, long2,
 838                 new Functions<Long>() {
 839                     @Override
 840                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 841                         return Bindings.notEqual((ObservableLongValue)op1, (ObservableLongValue)op2, 1);
 842                     }
 843                     @Override
 844                     public BooleanBinding generateExpressionPrimitive(Object op1, Long op2) {
 845                         return Bindings.notEqual((ObservableLongValue)op1, op2.longValue(), 1);
 846                     }
 847                     @Override
 848                     public BooleanBinding generatePrimitiveExpression(Long op1, Object op2) {
 849                         return Bindings.notEqual(op1.longValue(), (ObservableLongValue)op2, 1);
 850                     }
 851                     @Override
 852                     public void setOp1(Long value) {long1.set(value);}
 853                     @Override
 854                     public void setOp2(Long value) {long2.set(value);}
 855                     @Override
 856                     public void check(Long op1, Long op2, BooleanBinding exp) {
 857                         assertEquals(Math.abs(op1 - op2) > 1, exp.get());
 858                     }
 859                 },
 860                 longData
 861             },
 862             {
 863                 long1, long2,
 864                 new Functions<Long>() {
 865                     @Override
 866                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 867                         return Bindings.greaterThan((ObservableLongValue)op1, (ObservableLongValue)op2);
 868                     }
 869                     @Override
 870                     public BooleanBinding generateExpressionPrimitive(Object op1, Long op2) {
 871                         return Bindings.greaterThan((ObservableLongValue)op1, op2.longValue());
 872                     }
 873                     @Override
 874                     public BooleanBinding generatePrimitiveExpression(Long op1, Object op2) {
 875                         return Bindings.greaterThan(op1.longValue(), (ObservableLongValue)op2);
 876                     }
 877                     @Override
 878                     public void setOp1(Long value) {long1.set(value);}
 879                     @Override
 880                     public void setOp2(Long value) {long2.set(value);}
 881                     @Override
 882                     public void check(Long op1, Long op2, BooleanBinding exp) {
 883                         assertEquals(op1 > op2, exp.get());
 884                     }
 885                 },
 886                 longData
 887             },
 888             {
 889                 long1, long2,
 890                 new Functions<Long>() {
 891                     @Override
 892                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 893                         return Bindings.lessThan((ObservableLongValue)op1, (ObservableLongValue)op2);
 894                     }
 895                     @Override
 896                     public BooleanBinding generateExpressionPrimitive(Object op1, Long op2) {
 897                         return Bindings.lessThan((ObservableLongValue)op1, op2.longValue());
 898                     }
 899                     @Override
 900                     public BooleanBinding generatePrimitiveExpression(Long op1, Object op2) {
 901                         return Bindings.lessThan(op1.longValue(), (ObservableLongValue)op2);
 902                     }
 903                     @Override
 904                     public void setOp1(Long value) {long1.set(value);}
 905                     @Override
 906                     public void setOp2(Long value) {long2.set(value);}
 907                     @Override
 908                     public void check(Long op1, Long op2, BooleanBinding exp) {
 909                         assertEquals(op1 < op2, exp.get());
 910                     }
 911                 },
 912                 longData
 913             },
 914             {
 915                 long1, long2,
 916                 new Functions<Long>() {
 917                     @Override
 918                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 919                         return Bindings.greaterThanOrEqual((ObservableLongValue)op1, (ObservableLongValue)op2);
 920                     }
 921                     @Override
 922                     public BooleanBinding generateExpressionPrimitive(Object op1, Long op2) {
 923                         return Bindings.greaterThanOrEqual((ObservableLongValue)op1, op2.longValue());
 924                     }
 925                     @Override
 926                     public BooleanBinding generatePrimitiveExpression(Long op1, Object op2) {
 927                         return Bindings.greaterThanOrEqual(op1.longValue(), (ObservableLongValue)op2);
 928                     }
 929                     @Override
 930                     public void setOp1(Long value) {long1.set(value);}
 931                     @Override
 932                     public void setOp2(Long value) {long2.set(value);}
 933                     @Override
 934                     public void check(Long op1, Long op2, BooleanBinding exp) {
 935                         assertEquals(op1 >= op2, exp.get());
 936                     }
 937                 },
 938                 longData
 939             },
 940             {
 941                 long1, long2,
 942                 new Functions<Long>() {
 943                     @Override
 944                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 945                         return Bindings.lessThanOrEqual((ObservableLongValue)op1, (ObservableLongValue)op2);
 946                     }
 947                     @Override
 948                     public BooleanBinding generateExpressionPrimitive(Object op1, Long op2) {
 949                         return Bindings.lessThanOrEqual((ObservableLongValue)op1, op2.longValue());
 950                     }
 951                     @Override
 952                     public BooleanBinding generatePrimitiveExpression(Long op1, Object op2) {
 953                         return Bindings.lessThanOrEqual(op1.longValue(), (ObservableLongValue)op2);
 954                     }
 955                     @Override
 956                     public void setOp1(Long value) {long1.set(value);}
 957                     @Override
 958                     public void setOp2(Long value) {long2.set(value);}
 959                     @Override
 960                     public void check(Long op1, Long op2, BooleanBinding exp) {
 961                         assertEquals(op1 <= op2, exp.get());
 962                     }
 963                 },
 964                 longData
 965             },
 966 
 967 
 968 
 969             // String
 970             {
 971                 string1, string2,
 972                 new Functions<String>() {
 973                     @Override
 974                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
 975                         return Bindings.equal((ObservableStringValue)op1, (ObservableStringValue)op2);
 976                     }
 977                     @Override
 978                     public BooleanBinding generateExpressionPrimitive(Object op1, String op2) {
 979                         return Bindings.equal((ObservableStringValue)op1, op2);
 980                     }
 981                     @Override
 982                     public BooleanBinding generatePrimitiveExpression(String op1, Object op2) {
 983                         return Bindings.equal(op1, (ObservableStringValue)op2);
 984                     }
 985                     @Override
 986                     public void setOp1(String value) {string1.set(value);}
 987                     @Override
 988                     public void setOp2(String value) {string2.set(value);}
 989                     @Override
 990                     public void check(String op1, String op2, BooleanBinding exp) {
 991                         assertEquals(makeSafe(op1).equals(makeSafe(op2)), exp.get());
 992                     }
 993                 },
 994                 stringData
 995             },
 996             {
 997                 string1, string2,
 998                 new Functions<String>() {
 999                     @Override
1000                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
1001                         return Bindings.equal((ObservableStringValue)op1, (ObservableStringValue)op2);
1002                     }
1003                     @Override
1004                     public BooleanBinding generateExpressionPrimitive(Object op1, String op2) {
1005                         return Bindings.equal((ObservableStringValue)op1, op2);
1006                     }
1007                     @Override
1008                     public BooleanBinding generatePrimitiveExpression(String op1, Object op2) {
1009                         return Bindings.equal(op1, (ObservableStringValue)op2);
1010                     }
1011                     @Override
1012                     public void setOp1(String value) {string1.set(value);}
1013                     @Override
1014                     public void setOp2(String value) {string2.set(value);}
1015                     @Override
1016                     public void check(String op1, String op2, BooleanBinding exp) {
1017                         assertEquals(makeSafe(op1).equals(makeSafe(op2)), exp.get());
1018                     }
1019                 },
1020                 ciStringData
1021             },
1022             {
1023                 string1, string2,
1024                 new Functions<String>() {
1025                     @Override
1026                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
1027                         return Bindings.equalIgnoreCase((ObservableStringValue)op1, (ObservableStringValue)op2);
1028                     }
1029                     @Override
1030                     public BooleanBinding generateExpressionPrimitive(Object op1, String op2) {
1031                         return Bindings.equalIgnoreCase((ObservableStringValue)op1, op2);
1032                     }
1033                     @Override
1034                     public BooleanBinding generatePrimitiveExpression(String op1, Object op2) {
1035                         return Bindings.equalIgnoreCase(op1, (ObservableStringValue)op2);
1036                     }
1037                     @Override
1038                     public void setOp1(String value) {string1.set(value);}
1039                     @Override
1040                     public void setOp2(String value) {string2.set(value);}
1041                     @Override
1042                     public void check(String op1, String op2, BooleanBinding exp) {
1043                         assertEquals(makeSafe(op1).equalsIgnoreCase(makeSafe(op2)), exp.get());
1044                     }
1045                 },
1046                 stringData
1047             },
1048             {
1049                 string1, string2,
1050                 new Functions<String>() {
1051                     @Override
1052                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
1053                         return Bindings.equalIgnoreCase((ObservableStringValue)op1, (ObservableStringValue)op2);
1054                     }
1055                     @Override
1056                     public BooleanBinding generateExpressionPrimitive(Object op1, String op2) {
1057                         return Bindings.equalIgnoreCase((ObservableStringValue)op1, op2);
1058                     }
1059                     @Override
1060                     public BooleanBinding generatePrimitiveExpression(String op1, Object op2) {
1061                         return Bindings.equalIgnoreCase(op1, (ObservableStringValue)op2);
1062                     }
1063                     @Override
1064                     public void setOp1(String value) {string1.set(value);}
1065                     @Override
1066                     public void setOp2(String value) {string2.set(value);}
1067                     @Override
1068                     public void check(String op1, String op2, BooleanBinding exp) {
1069                         assertEquals(makeSafe(op1).equalsIgnoreCase(makeSafe(op2)), exp.get());
1070                     }
1071                 },
1072                 ciStringData
1073             },
1074             {
1075                 string1, string2,
1076                 new Functions<String>() {
1077                     @Override
1078                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
1079                         return Bindings.notEqual((ObservableStringValue)op1, (ObservableStringValue)op2);
1080                     }
1081                     @Override
1082                     public BooleanBinding generateExpressionPrimitive(Object op1, String op2) {
1083                         return Bindings.notEqual((ObservableStringValue)op1, op2);
1084                     }
1085                     @Override
1086                     public BooleanBinding generatePrimitiveExpression(String op1, Object op2) {
1087                         return Bindings.notEqual(op1, (ObservableStringValue)op2);
1088                     }
1089                     @Override
1090                     public void setOp1(String value) {string1.set(value);}
1091                     @Override
1092                     public void setOp2(String value) {string2.set(value);}
1093                     @Override
1094                     public void check(String op1, String op2, BooleanBinding exp) {
1095                         assertEquals(!makeSafe(op1).equals(makeSafe(op2)), exp.get());
1096                     }
1097                 },
1098                 stringData
1099             },
1100             {
1101                 string1, string2,
1102                 new Functions<String>() {
1103                     @Override
1104                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
1105                         return Bindings.notEqual((ObservableStringValue)op1, (ObservableStringValue)op2);
1106                     }
1107                     @Override
1108                     public BooleanBinding generateExpressionPrimitive(Object op1, String op2) {
1109                         return Bindings.notEqual((ObservableStringValue)op1, op2);
1110                     }
1111                     @Override
1112                     public BooleanBinding generatePrimitiveExpression(String op1, Object op2) {
1113                         return Bindings.notEqual(op1, (ObservableStringValue)op2);
1114                     }
1115                     @Override
1116                     public void setOp1(String value) {string1.set(value);}
1117                     @Override
1118                     public void setOp2(String value) {string2.set(value);}
1119                     @Override
1120                     public void check(String op1, String op2, BooleanBinding exp) {
1121                         assertEquals(!makeSafe(op1).equals(makeSafe(op2)), exp.get());
1122                     }
1123                 },
1124                 ciStringData
1125             },
1126             {
1127                 string1, string2,
1128                 new Functions<String>() {
1129                     @Override
1130                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
1131                         return Bindings.notEqualIgnoreCase((ObservableStringValue)op1, (ObservableStringValue)op2);
1132                     }
1133                     @Override
1134                     public BooleanBinding generateExpressionPrimitive(Object op1, String op2) {
1135                         return Bindings.notEqualIgnoreCase((ObservableStringValue)op1, op2);
1136                     }
1137                     @Override
1138                     public BooleanBinding generatePrimitiveExpression(String op1, Object op2) {
1139                         return Bindings.notEqualIgnoreCase(op1, (ObservableStringValue)op2);
1140                     }
1141                     @Override
1142                     public void setOp1(String value) {string1.set(value);}
1143                     @Override
1144                     public void setOp2(String value) {string2.set(value);}
1145                     @Override
1146                     public void check(String op1, String op2, BooleanBinding exp) {
1147                         assertEquals(!makeSafe(op1).equalsIgnoreCase(makeSafe(op2)), exp.get());
1148                     }
1149                 },
1150                 stringData
1151             },
1152             {
1153                 string1, string2,
1154                 new Functions<String>() {
1155                     @Override
1156                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
1157                         return Bindings.notEqualIgnoreCase((ObservableStringValue)op1, (ObservableStringValue)op2);
1158                     }
1159                     @Override
1160                     public BooleanBinding generateExpressionPrimitive(Object op1, String op2) {
1161                         return Bindings.notEqualIgnoreCase((ObservableStringValue)op1, op2);
1162                     }
1163                     @Override
1164                     public BooleanBinding generatePrimitiveExpression(String op1, Object op2) {
1165                         return Bindings.notEqualIgnoreCase(op1, (ObservableStringValue)op2);
1166                     }
1167                     @Override
1168                     public void setOp1(String value) {string1.set(value);}
1169                     @Override
1170                     public void setOp2(String value) {string2.set(value);}
1171                     @Override
1172                     public void check(String op1, String op2, BooleanBinding exp) {
1173                         assertEquals(!makeSafe(op1).equalsIgnoreCase(makeSafe(op2)), exp.get());
1174                     }
1175                 },
1176                 ciStringData
1177             },
1178             {
1179                 string1, string2,
1180                 new Functions<String>() {
1181                     @Override
1182                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
1183                         return Bindings.greaterThan((ObservableStringValue)op1, (ObservableStringValue)op2);
1184                     }
1185                     @Override
1186                     public BooleanBinding generateExpressionPrimitive(Object op1, String op2) {
1187                         return Bindings.greaterThan((ObservableStringValue)op1, op2);
1188                     }
1189                     @Override
1190                     public BooleanBinding generatePrimitiveExpression(String op1, Object op2) {
1191                         return Bindings.greaterThan(op1, (ObservableStringValue)op2);
1192                     }
1193                     @Override
1194                     public void setOp1(String value) {string1.set(value);}
1195                     @Override
1196                     public void setOp2(String value) {string2.set(value);}
1197                     @Override
1198                     public void check(String op1, String op2, BooleanBinding exp) {
1199                         assertEquals(makeSafe(op1).compareTo(makeSafe(op2)) > 0, exp.get());
1200                     }
1201                 },
1202                 stringData
1203             },
1204             {
1205                 string1, string2,
1206                 new Functions<String>() {
1207                     @Override
1208                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
1209                         return Bindings.lessThan((ObservableStringValue)op1, (ObservableStringValue)op2);
1210                     }
1211                     @Override
1212                     public BooleanBinding generateExpressionPrimitive(Object op1, String op2) {
1213                         return Bindings.lessThan((ObservableStringValue)op1, op2);
1214                     }
1215                     @Override
1216                     public BooleanBinding generatePrimitiveExpression(String op1, Object op2) {
1217                         return Bindings.lessThan(op1, (ObservableStringValue)op2);
1218                     }
1219                     @Override
1220                     public void setOp1(String value) {string1.set(value);}
1221                     @Override
1222                     public void setOp2(String value) {string2.set(value);}
1223                     @Override
1224                     public void check(String op1, String op2, BooleanBinding exp) {
1225                         assertEquals(makeSafe(op1).compareTo(makeSafe(op2)) < 0, exp.get());
1226                     }
1227                 },
1228                 stringData
1229             },
1230             {
1231                 string1, string2,
1232                 new Functions<String>() {
1233                     @Override
1234                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
1235                         return Bindings.greaterThanOrEqual((ObservableStringValue)op1, (ObservableStringValue)op2);
1236                     }
1237                     @Override
1238                     public BooleanBinding generateExpressionPrimitive(Object op1, String op2) {
1239                         return Bindings.greaterThanOrEqual((ObservableStringValue)op1, op2);
1240                     }
1241                     @Override
1242                     public BooleanBinding generatePrimitiveExpression(String op1, Object op2) {
1243                         return Bindings.greaterThanOrEqual(op1, (ObservableStringValue)op2);
1244                     }
1245                     @Override
1246                     public void setOp1(String value) {string1.set(value);}
1247                     @Override
1248                     public void setOp2(String value) {string2.set(value);}
1249                     @Override
1250                     public void check(String op1, String op2, BooleanBinding exp) {
1251                         assertEquals(makeSafe(op1).compareTo(makeSafe(op2)) >= 0, exp.get());
1252                     }
1253                 },
1254                 stringData
1255             },
1256             {
1257                 string1, string2,
1258                 new Functions<String>() {
1259                     @Override
1260                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
1261                         return Bindings.lessThanOrEqual((ObservableStringValue)op1, (ObservableStringValue)op2);
1262                     }
1263                     @Override
1264                     public BooleanBinding generateExpressionPrimitive(Object op1, String op2) {
1265                         return Bindings.lessThanOrEqual((ObservableStringValue)op1, op2);
1266                     }
1267                     @Override
1268                     public BooleanBinding generatePrimitiveExpression(String op1, Object op2) {
1269                         return Bindings.lessThanOrEqual(op1, (ObservableStringValue)op2);
1270                     }
1271                     @Override
1272                     public void setOp1(String value) {string1.set(value);}
1273                     @Override
1274                     public void setOp2(String value) {string2.set(value);}
1275                     @Override
1276                     public void check(String op1, String op2, BooleanBinding exp) {
1277                         assertEquals(makeSafe(op1).compareTo(makeSafe(op2)) <= 0, exp.get());
1278                     }
1279                 },
1280                 stringData
1281             },
1282 
1283 
1284 
1285             // Object
1286             {
1287                 object1, object2,
1288                 new Functions<Object>() {
1289                     @SuppressWarnings("unchecked")
1290                                         @Override
1291                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
1292                         return Bindings.equal((ObservableObjectValue<Object>)op1, (ObservableObjectValue<Object>)op2);
1293                     }
1294                     @SuppressWarnings("unchecked")
1295                                         @Override
1296                     public BooleanBinding generateExpressionPrimitive(Object op1, Object op2) {
1297                         return Bindings.equal((ObservableObjectValue<Object>)op1, op2);
1298                     }
1299                     @SuppressWarnings("unchecked")
1300                                         @Override
1301                     public BooleanBinding generatePrimitiveExpression(Object op1, Object op2) {
1302                         return Bindings.equal(op1, (ObservableObjectValue<Object>)op2);
1303                     }
1304                     @Override
1305                     public void setOp1(Object value) {object1.set(value);}
1306                     @Override
1307                     public void setOp2(Object value) {object2.set(value);}
1308                     @Override
1309                     public void check(Object op1, Object op2, BooleanBinding exp) {
1310                         assertEquals(op1.equals(op2), exp.get());
1311                     }
1312                 },
1313                 objectData
1314             },
1315             {
1316                 object1, object2,
1317                 new Functions<Object>() {
1318                     @SuppressWarnings("unchecked")
1319                                         @Override
1320                     public BooleanBinding generateExpressionExpression(Object op1, Object op2) {
1321                         return Bindings.notEqual((ObservableObjectValue<Object>)op1, (ObservableObjectValue<Object>)op2);
1322                     }
1323                     @SuppressWarnings("unchecked")
1324                                         @Override
1325                     public BooleanBinding generateExpressionPrimitive(Object op1, Object op2) {
1326                         return Bindings.notEqual((ObservableObjectValue<Object>)op1, op2);
1327                     }
1328                     @SuppressWarnings("unchecked")
1329                                         @Override
1330                     public BooleanBinding generatePrimitiveExpression(Object op1, Object op2) {
1331                         return Bindings.notEqual(op1, (ObservableObjectValue<Object>)op2);
1332                     }
1333                     @Override
1334                     public void setOp1(Object value) {object1.set(value);}
1335                     @Override
1336                     public void setOp2(Object value) {object2.set(value);}
1337                     @Override
1338                     public void check(Object op1, Object op2, BooleanBinding exp) {
1339                         assertEquals(!op1.equals(op2), exp.get());
1340                     }
1341                 },
1342                 objectData
1343             },
1344         });
1345     };
1346 
1347 }