@Test
  public void testEncoder_FilteredToOne() throws IOException {

    filters.add(
        new EncoderFilter() {

          @Override
          public boolean matches(ClientEntity<?> clientEntity) {
            return true;
          }

          @Override
          public boolean encode(
              String propertyName, Object object, JsonGenerator out, Encoder delegate)
              throws IOException {

            if (object instanceof E2) {
              E2 e2 = (E2) object;
              if (Cayenne.intPKForObject(e2) == 7) {
                return delegate.encode(propertyName, object, out);
              } else {
                return false;
              }
            } else {
              delegate.encode(propertyName, object, out);
              return true;
            }
          }

          @Override
          public boolean willEncode(String propertyName, Object object, Encoder delegate) {
            if (object instanceof E2) {
              E2 e2 = (E2) object;
              if (Cayenne.intPKForObject(e2) == 7) {
                return delegate.willEncode(propertyName, object);
              } else {
                return false;
              }
            } else {
              return delegate.willEncode(propertyName, object);
            }
          }
        });

    ClientEntity<E2> e2Descriptor = getClientEntity(E2.class);
    e2Descriptor.setIdIncluded(true);

    ClientEntity<E3> e3Descriptor = getClientEntity(E3.class);
    e3Descriptor.setIdIncluded(true);
    e3Descriptor.getRelationships().put(E3.E2.getName(), e2Descriptor);

    ObjectContext context = cayenneService.newContext();

    E2 e21 = new E2();
    e21.setObjectId(new ObjectId("E2", E2.ID_PK_COLUMN, 7));
    context.registerNewObject(e21);

    E3 e31 = new E3();
    e31.setObjectId(new ObjectId("E3", E3.ID_PK_COLUMN, 5));
    context.registerNewObject(e31);
    e31.setE2(e21);

    DataResponse<E3> builder =
        DataResponse.forType(E3.class).withClientEntity(e3Descriptor).withObject(e31);

    encoderService.makeEncoder(builder);

    assertEquals("[{\"id\":5,\"e2\":{\"id\":7},\"e2_id\":7}]", toJson(builder));

    E2 e22 = new E2();
    e22.setObjectId(new ObjectId("E2", E2.ID_PK_COLUMN, 8));
    context.registerNewObject(e22);

    E3 e32 = new E3();
    e32.setObjectId(new ObjectId("E3", E3.ID_PK_COLUMN, 6));
    context.registerNewObject(e32);
    e32.setE2(e22);

    builder.withObject(e32);

    assertEquals("[{\"id\":6}]", toJson(builder));
  }
  @Test
  public void testEncoder_FilteredRoots() throws IOException {

    filters.add(
        new EncoderFilter() {

          @Override
          public boolean matches(ClientEntity<?> clientEntity) {
            return true;
          }

          @Override
          public boolean encode(
              String propertyName, Object object, JsonGenerator out, Encoder delegate)
              throws IOException {

            E2 e2 = (E2) object;
            if (Cayenne.intPKForObject(e2) == 7) {
              delegate.encode(propertyName, object, out);
              return true;
            }

            return false;
          }

          @Override
          public boolean willEncode(String propertyName, Object object, Encoder delegate) {
            E2 e2 = (E2) object;
            if (Cayenne.intPKForObject(e2) == 7) {
              delegate.willEncode(propertyName, object);
              return true;
            }

            return false;
          }
        });

    ClientEntity<E2> descriptor = getClientEntity(E2.class);
    descriptor.setIdIncluded(true);

    ObjectContext context = cayenneService.newContext();
    E2 e21 = new E2();
    e21.setObjectId(new ObjectId("E2", E2.ID_PK_COLUMN, 7));
    e21.setName("XYZ");
    e21.setAddress("bla bla street");
    context.registerNewObject(e21);

    DataResponse<E2> builder =
        DataResponse.forType(E2.class).withClientEntity(descriptor).withObject(e21);

    encoderService.makeEncoder(builder);
    assertEquals("[{\"id\":7}]", toJson(builder));

    E2 e22 = new E2();
    e22.setObjectId(new ObjectId("E2", E2.ID_PK_COLUMN, 8));
    e22.setName("XYZ");
    e22.setAddress("bla bla street");
    context.registerNewObject(e22);

    builder.withObject(e22);
    encoderService.makeEncoder(builder);

    assertEquals("[]", toJson(builder));
  }