text:
package org.apache.beam.sdk.schemas.transforms;

import static org.junit.Assert.assertEquals;

import com.google.auto.value.AutoValue;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.apache.beam.sdk.schemas.AutoValueSchema;
import org.apache.beam.sdk.schemas.Schema;
import org.apache.beam.sdk.schemas.annotations.DefaultSchema;
import org.apache.beam.sdk.testing.NeedsRunner;
import org.apache.beam.sdk.testing.PAssert;
import org.apache.beam.sdk.testing.TestPipeline;
import org.apache.beam.sdk.testing.UsesSchema;
import org.apache.beam.sdk.transforms.Create;
import org.apache.beam.sdk.values.PCollection;
import org.apache.beam.sdk.values.Row;
import org.apache.beam.vendor.guava.v26_0_jre.com.google.common.collect.ImmutableList;
import org.apache.beam.vendor.guava.v26_0_jre.com.google.common.collect.ImmutableMap;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Test for {@link Select}. */
@RunWith(JUnit4.class)
@Category(UsesSchema.class)
public class SelectTest {
  @Rule public final transient TestPipeline pipeline = TestPipeline.create();
  @Rule public transient ExpectedException thrown = ExpectedException.none();

  /** flat schema to select from. */
  @DefaultSchema(AutoValueSchema.class)
  @AutoValue
  abstract static class Schema1 {
    abstract String getField1();

    abstract Integer getField2();

    abstract Double getField3();

    static Schema1 create() {
      return new AutoValue_SelectTest_Schema1("field1", 42, 3.14);
    }
  };

  /** A class matching the schema resulting from selection field1, field3. */
  @DefaultSchema(AutoValueSchema.class)
  @AutoValue
  abstract static class Schema1Selected {
    abstract String getField1();

    abstract Double getField3();

    static Schema1Selected create() {
      return new AutoValue_SelectTest_Schema1Selected("field1", 3.14);
    }
  }

  /**
   * A class matching the schema resulting from selection field1, field3 with the fields renamed.
   */
  @DefaultSchema(AutoValueSchema.class)
  @AutoValue
  abstract static class Schema1SelectedRenamed {
    abstract String getFieldOne();

    abstract Double getFieldThree();

    static Schema1SelectedRenamed create() {
      return new AutoValue_SelectTest_Schema1SelectedRenamed("field1", 3.14);
    }
  }

  /** A nested schema class. */
  @DefaultSchema(AutoValueSchema.class)
  @AutoValue
  abstract static class Schema2 {
    abstract String getField1();

    abstract Schema1 getField2();

    static Schema2 create() {
      return new AutoValue_SelectTest_Schema2("field1", Schema1.create());
    }
  }

  @Test
  @Category(NeedsRunner.class)
  public void testSelectMissingFieldName() {
    thrown.expect(IllegalArgumentException.class);
    pipeline.apply(Create.of(Schema1.create())).apply(Select.fieldNames("missing"));
    pipeline.run();
  }

  @Test
  @Category(NeedsRunner.class)
  public void testSelectMissingFieldIndex() {
    thrown.expect(IllegalArgumentException.class);
    pipeline.apply(Create.of(Schema1.create())).apply(Select.fieldIds(42));
    pipeline.run();
  }

  @Test
  @Category(NeedsRunner.class)
  public void testSelectAll() {
    PCollection<Schema1> rows =
        pipeline
            .apply(Create.of(Schema1.create()))
            .apply(Select.fieldNames("*"))
            .apply(Convert.to(Schema1.class));
    PAssert.that(rows).containsInAnyOrder(Schema1.create());
    pipeline.run();
  }

  @Test
  @Category(NeedsRunner.class)
  public void testSimpleSelect() {
    PCollection<Schema1Selected> rows =
        pipeline
            .apply(Create.of(Schema1.create()))
            .apply(Select.fieldNames("field1", "field3"))
            .apply(Convert.to(Schema1Selected.class));
    PAssert.that(rows).containsInAnyOrder(Schema1Selected.create());
    pipeline.run();
  }

  @Test
  @Category(NeedsRunner.class)
  public void testSimpleSelectRename() {
    PCollection<Schema1SelectedRenamed> rows =
        pipeline
            .apply(Create.of(Schema1.create()))
            .apply(
                Select.<Schema1>create()
                    .withFieldNameAs("field1", "fieldOne")
                    .withFieldNameAs("field3", "fieldThree"))
            .apply(Convert.to(Schema1SelectedRenamed.class));
    PAssert.that(rows).containsInAnyOrder(Schema1SelectedRenamed.create());
    pipeline.run();
  }

  @Test
  @Category(NeedsRunner.class)
  public void testSelectWithOutputSchema() {
    Schema outputSchema =
        Schema.builder()
            .addStringField("stringField")
            .addStringField("nestedStringField")
            .addDoubleField("nestedDoubleField")
            .build();

    Schema2 input = Schema2.create();
    PCollection<Row> rows =
        pipeline
            .apply(Create.of(input))
            .apply(
                Select.<Schema2>fieldNames("field1", "field2.field1", "field2.field3")
                    .withOutputSchema(outputSchema));
    Row expectedOutput =
        Row.withSchema(outputSchema)
            .addValues(
                input.getField1(), input.getField2().getField1(), input.getField2().getField3())
            .build();
    PAssert.that(rows).containsInAnyOrder(expectedOutput);
    pipeline.run();
  }

  @Test
  @Category(NeedsRunner.class)
  public void testSelectWithOutputSchemaIncorrectSchema() {
    Schema outputSchema =
        Schema.builder()
            .addStringField("stringField")
            .addStringField("nestedStringField")
            .addStringField("nestedDoubleField")
            .build();

    thrown.expect(IllegalArgumentException.class);
    pipeline
        .apply(Create.of(Schema2.create()))
        .apply(
            Select.<Schema2>fieldNames("field1", "field2.field1", "field2.field3")
                .withOutputSchema(outputSchema));
    pipeline.run();
  }

  @Test
  @Category(NeedsRunner.class)
  public void testSelectNestedAll() {
    PCollection<Schema1> rows =
        pipeline
            .apply(Create.of(Schema2.create()))
            .apply(Select.fieldNames("field2"))
            .apply(Convert.to(Schema1.class));
    PAssert.that(rows).containsInAnyOrder(Schema1.create());
    pipeline.run();
  }

  @Test
  @Category(NeedsRunner.class)
  public void testSelectNestedAllWildcard() {
    PCollection<Schema1> rows =
        pipeline
            .apply(Create.of(Schema2.create()))
            .apply(Select.fieldNames("field2.*"))
            .apply(Convert.to(Schema1.class));
    PAssert.that(rows).containsInAnyOrder(Schema1.create());
    pipeline.run();
  }

  @Test
  @Category(NeedsRunner.class)
  public void testSelectNestedPartial() {
    PCollection<Schema1Selected> rows =
        pipeline
            .apply(Create.of(Schema2.create()))
            .apply(Select.fieldNames("field2.field1", "field2.field3"))
            .apply(Convert.to(Schema1Selected.class));
    PAssert.that(rows).containsInAnyOrder(Schema1Selected.create());
    pipeline.run();
  }

  @DefaultSchema(AutoValueSchema.class)
  @AutoValue
  abstract static class PrimitiveArray {
    abstract List<Double> getField1();

    static PrimitiveArray create() {
      return new AutoValue_SelectTest_PrimitiveArray(ImmutableList.of(1.0, 2.1, 3.2));
    }
  }

  @Test
  @Category(NeedsRunner.class)
  public void testSelectPrimitiveArray() {
    PCollection<PrimitiveArray> selected =
        pipeline
            .apply(Create.of(PrimitiveArray.create()))
            .apply(Select.fieldNames("field1"))
            .apply(Convert.to(PrimitiveArray.class));
    PAssert.that(selected).containsInAnyOrder(PrimitiveArray.create());
    pipeline.run();
  }

  @DefaultSchema(AutoValueSchema.class)
  @AutoValue
  abstract static class RowSingleArray {
    abstract List<Schema1> getField1();

    static RowSingleArray create() {
      return new AutoValue_SelectTest_RowSingleArray(
          ImmutableList.of(Schema1.create(), Schema1.create(), Schema1.create()));
    }
  }

  @DefaultSchema(AutoValueSchema.class)
  @AutoValue
  abstract static class PartialRowSingleArray {
    abstract List<String> getField1();

    abstract List<Double> getField3();

    static PartialRowSingleArray create() {
      return new AutoValue_SelectTest_PartialRowSingleArray(
          ImmutableList.of("field1", "field1", "field1"), ImmutableList.of(3.14, 3.14, 3.14));
    }
  }

  @Test
  @Category(NeedsRunner.class)
  public void testSelectRowArray() {
    PCollection<PartialRowSingleArray> selected =
        pipeline
            .apply(Create.of(RowSingleArray.create()))
            .apply(Select.fieldNames("field1.field1", "field1.field3"))
            .apply(Convert.to(PartialRowSingleArray.class));
    PAssert.that(selected).containsInAnyOrder(PartialRowSingleArray.create());
    pipeline.run();
  }

  @DefaultSchema(AutoValueSchema.class)
  @AutoValue
  abstract static class RowSingleMap {
    abstract Map<String, Schema1> getField1();

    static RowSingleMap create() {
      return new AutoValue_SelectTest_RowSingleMap(
          ImmutableMap.of(
              "key1", Schema1.create(),
              "key2", Schema1.create(),
              "key3", Schema1.create()));
    }
  }

  @DefaultSchema(AutoValueSchema.class)
  @AutoValue
  abstract static class PartialRowSingleMap {
    abstract Map<String, String> getField1();

    abstract Map<String, Double> getField3();

    static PartialRowSingleMap create() {
      return new AutoValue_SelectTest_PartialRowSingleMap(
          ImmutableMap.of(
              "key1", "field1",
              "key2", "field1",
              "key3", "field1"),
          ImmutableMap.of(
              "key1", 3.14,
              "key2", 3.14,
              "key3", 3.14));
    }
  }

  @Test
  @Category(NeedsRunner.class)
  public void testSelectRowMap() {
    PCollection<PartialRowSingleMap> selected =
        pipeline
            .apply(Create.of(RowSingleMap.create()))
            .apply(Select.fieldNames("field1.field1", "field1.field3"))
            .apply(Convert.to(PartialRowSingleMap.class));
    PAssert.that(selected).containsInAnyOrder(PartialRowSingleMap.create());
    pipeline.run();
  }

  @DefaultSchema(AutoValueSchema.class)
  @AutoValue
  abstract static class RowMultipleArray {
    private static final List<Schema1> ROW_LIST =
        ImmutableList.of(Schema1.create(), Schema1.create(), Schema1.create());
    private static final List<List<Schema1>> ROW_LIST_LIST =
        ImmutableList.of(ROW_LIST, ROW_LIST, ROW_LIST);

    abstract List<List<List<Schema1>>> getField1();

    static RowMultipleArray create() {
      return new AutoValue_SelectTest_RowMultipleArray(
          ImmutableList.of(ROW_LIST_LIST, ROW_LIST_LIST, ROW_LIST_LIST));
    }
  }

  @DefaultSchema(AutoValueSchema.class)
  @AutoValue
  abstract static class PartialRowMultipleArray {
    private static final List<Schema1Selected> ROW_LIST =
        ImmutableList.of(
            Schema1Selected.create(), Schema1Selected.create(), Schema1Selected.create());
    private static final List<List<Schema1Selected>> ROW_LIST_LIST =
        ImmutableList.of(ROW_LIST, ROW_LIST, ROW_LIST);
    private static final List<String> STRING_LIST = ImmutableList.of("field1", "field1", "field1");
    private static final List<List<String>> STRING_LISTLIST =
        ImmutableList.of(STRING_LIST, STRING_LIST, STRING_LIST);
    private static final List<Double> DOUBLE_LIST = ImmutableList.of(3.14, 3.14, 3.14);
    private static final List<List<Double>> DOUBLE_LISTLIST =
        ImmutableList.of(DOUBLE_LIST, DOUBLE_LIST, DOUBLE_LIST);

    abstract List<List<List<String>>> getField1();

    abstract List<List<List<Double>>> getField3();

    static PartialRowMultipleArray create() {
      return new AutoValue_SelectTest_PartialRowMultipleArray(
          ImmutableList.of(STRING_LISTLIST, STRING_LISTLIST, STRING_LISTLIST),
          ImmutableList.of(DOUBLE_LISTLIST, DOUBLE_LISTLIST, DOUBLE_LISTLIST));
    }
  }

  @Test
  @Category(NeedsRunner.class)
  public void testSelectedNestedArrays() {
    PCollection<RowMultipleArray> input = pipeline.apply(Create.of(RowMultipleArray.create()));

    PCollection<PartialRowMultipleArray> selected =
        input
            .apply("select1", Select.fieldNames("field1.field1", "field1.field3"))
            .apply("convert1", Convert.to(PartialRowMultipleArray.class));
    PAssert.that(selected).containsInAnyOrder(PartialRowMultipleArray.create());

    PCollection<PartialRowMultipleArray> selected2 =
        input
            .apply("select2", Select.fieldNames("field1[][][].field1", "field1[][][].field3"))
            .apply("convert2", Convert.to(PartialRowMultipleArray.class));

    PAssert.that(selected).containsInAnyOrder(PartialRowMultipleArray.create());
    PAssert.that(selected2).containsInAnyOrder(PartialRowMultipleArray.create());
    pipeline.run();
  }

  @DefaultSchema(AutoValueSchema.class)
  @AutoValue
  abstract static class RowMultipleMaps {
    static final Map<String, Schema1> ROW_MAP =
        ImmutableMap.of(
            "key1", Schema1.create(),
            "key2", Schema1.create(),
            "key3", Schema1.create());
    static final Map<String, Map<String, Schema1>> ROW_MAP_MAP =
        ImmutableMap.of(
            "key1", ROW_MAP,
            "key2", ROW_MAP,
            "key3", ROW_MAP);

    abstract Map<String, Map<String, Map<String, Schema1>>> getField1();

    static RowMultipleMaps create() {
      return new AutoValue_SelectTest_RowMultipleMaps(
          ImmutableMap.of(
              "key1", ROW_MAP_MAP,
              "key2", ROW_MAP_MAP,
              "key3", ROW_MAP_MAP));
    }
  }

  @DefaultSchema(AutoValueSchema.class)
  @AutoValue
  abstract static class PartialRowMultipleMaps {
    static final Map<String, String> STRING_MAP =
        ImmutableMap.of(
            "key1", "field1",
            "key2", "field1",
            "key3", "field1");
    static final Map<String, Map<String, String>> STRING_MAPMAP =
        ImmutableMap.of(
            "key1", STRING_MAP,
            "key2", STRING_MAP,
            "key3", STRING_MAP);
    static final Map<String, Double> DOUBLE_MAP =
        ImmutableMap.of(
            "key1", 3.14,
            "key2", 3.14,
            "key3", 3.14);
    static final Map<String, Map<String, Double>> DOUBLE_MAPMAP =
        ImmutableMap.of(
            "key1", DOUBLE_MAP,
            "key2", DOUBLE_MAP,
            "key3", DOUBLE_MAP);

    abstract Map<String, Map<String, Map<String, String>>> getField1();

    abstract Map<String, Map<String, Map<String, Double>>> getField3();

    static PartialRowMultipleMaps create() {
      return new AutoValue_SelectTest_PartialRowMultipleMaps(
          ImmutableMap.of(
              "key1", STRING_MAPMAP,
              "key2", STRING_MAPMAP,
              "key3", STRING_MAPMAP),
          ImmutableMap.of(
              "key1", DOUBLE_MAPMAP,
              "key2", DOUBLE_MAPMAP,
              "key3", DOUBLE_MAPMAP));
    }
  }

  @Test
  @Category(NeedsRunner.class)
  public void testSelectRowNestedMaps() {
    PCollection<RowMultipleMaps> input = pipeline.apply(Create.of(RowMultipleMaps.create()));

    PCollection<PartialRowMultipleMaps> selected =
        input
            .apply("select1", Select.fieldNames("field1.field1", "field1.field3"))
            .apply("convert1", Convert.to(PartialRowMultipleMaps.class));

    PCollection<PartialRowMultipleMaps> selected2 =
        input
            .apply("select2", Select.fieldNames("field1{}{}{}.field1", "field1{}{}{}.field3"))
            .apply("convert2", Convert.to(PartialRowMultipleMaps.class));

    PAssert.that(selected).containsInAnyOrder(PartialRowMultipleMaps.create());
    PAssert.that(selected2).containsInAnyOrder(PartialRowMultipleMaps.create());
    pipeline.run();
  }

  @DefaultSchema(AutoValueSchema.class)
  @AutoValue
  abstract static class RowNestedArraysAndMaps {
    static final List<Schema1> ROW_LIST =
        ImmutableList.of(Schema1.create(), Schema1.create(), Schema1.create());
    static final Map<String, List<Schema1>> ROW_MAP_LIST =
        ImmutableMap.of(
            "key1", ROW_LIST,
            "key2", ROW_LIST,
            "key3", ROW_LIST);

    abstract List<Map<String, List<Schema1>>> getField1();

    static RowNestedArraysAndMaps create() {
      return new AutoValue_SelectTest_RowNestedArraysAndMaps(
          ImmutableList.of(ROW_MAP_LIST, ROW_MAP_LIST, ROW_MAP_LIST));
    }
  }

  @DefaultSchema(AutoValueSchema.class)
  @AutoValue
  abstract static class PartialRowNestedArraysAndMaps {
    static final Map<String, List<String>> STRING_MAP =
        ImmutableMap.of(
            "key1", ImmutableList.of("field1", "field1", "field1"),
            "key2", ImmutableList.of("field1", "field1", "field1"),
            "key3", ImmutableList.of("field1", "field1", "field1"));
    static final Map<String, List<Double>> DOUBLE_MAP =
        ImmutableMap.of(
            "key1", ImmutableList.of(3.14, 3.14, 3.14),
            "key2", ImmutableList.of(3.14, 3.14, 3.14),
            "key3", ImmutableList.of(3.14, 3.14, 3.14));

    abstract List<Map<String, List<String>>> getField1();

    abstract List<Map<String, List<Double>>> getField3();

    static PartialRowNestedArraysAndMaps create() {
      return new AutoValue_SelectTest_PartialRowNestedArraysAndMaps(
          ImmutableList.of(STRING_MAP, STRING_MAP, STRING_MAP),
          ImmutableList.of(DOUBLE_MAP, DOUBLE_MAP, DOUBLE_MAP));
    }
  }

  @Test
  @Category(NeedsRunner.class)
  public void testSelectRowNestedListsAndMaps() {
    PCollection<RowNestedArraysAndMaps> input =
        pipeline.apply(Create.of(RowNestedArraysAndMaps.create()));

    PCollection<PartialRowNestedArraysAndMaps> selected =
        input
            .apply("select1", Select.fieldNames("field1.field1", "field1.field3"))
            .apply("convert1", Convert.to(PartialRowNestedArraysAndMaps.class));

    PCollection<PartialRowNestedArraysAndMaps> selected2 =
        input
            .apply("select2", Select.fieldNames("field1[]{}[].field1", "field1[]{}[].field3"))
            .apply("convert2", Convert.to(PartialRowNestedArraysAndMaps.class));

    PAssert.that(selected).containsInAnyOrder(PartialRowNestedArraysAndMaps.create());
    PAssert.that(selected2).containsInAnyOrder(PartialRowNestedArraysAndMaps.create());
    pipeline.run();
  }

  static final Schema SIMPLE_SCHEMA =
      Schema.builder().addInt32Field("field1").addStringField("field2").build();
  static final Schema NESTED_SCHEMA =
      Schema.builder()
          .addRowField("nested1", SIMPLE_SCHEMA)
          .addRowField("nested2", SIMPLE_SCHEMA)
          .build();
  static final Schema UNNESTED_SCHEMA =
      Schema.builder()
          .addInt32Field("nested1_field1")
          .addStringField("nested1_field2")
          .addInt32Field("nested2_field1")
          .addStringField("nested2_field2")
          .build();
  static final Schema NESTED_SCHEMA2 =
      Schema.builder().addRowField("nested", SIMPLE_SCHEMA).build();
  static final Schema DOUBLE_NESTED_SCHEMA =
      Schema.builder().addRowField("nested", NESTED_SCHEMA).build();

  @Test
  @Category(NeedsRunner.class)
  public void testFlatSchema() {
    List<Row> rows =
        IntStream.rangeClosed(0, 2)
            .mapToObj(i -> Row.withSchema(SIMPLE_SCHEMA).addValues(i, Integer.toString(i)).build())
            .collect(Collectors.toList());
    PCollection<Row> unnested =
        pipeline
            .apply(Create.of(rows).withRowSchema(SIMPLE_SCHEMA))
            .apply(Select.flattenedSchema());
    PAssert.that(unnested).containsInAnyOrder(rows);
    pipeline.run();
  }

  @Test
  @Category(NeedsRunner.class)
  public void testSimpleFlattening() {
    List<Row> bottomRow =
        IntStream.rangeClosed(0, 2)
            .mapToObj(i -> Row.withSchema(SIMPLE_SCHEMA).addValues(i, Integer.toString(i)).build())
            .collect(Collectors.toList());
    List<Row> rows =
        bottomRow.stream()
            .map(r -> Row.withSchema(NESTED_SCHEMA).addValues(r, r).build())
            .collect(Collectors.toList());
    PCollection<Row> unnested =
        pipeline
            .apply(Create.of(rows).withRowSchema(NESTED_SCHEMA))
            .apply(Select.flattenedSchema());
    assertEquals(UNNESTED_SCHEMA, unnested.getSchema());
    List<Row> expected =
        bottomRow.stream()
            .map(
                r ->
                    Row.withSchema(UNNESTED_SCHEMA)
                        .addValues(r.getValue(0), r.getValue(1), r.getValue(0), r.getValue(1))
                        .build())
            .collect(Collectors.toList());
    ;
    PAssert.that(unnested).containsInAnyOrder(expected);
    pipeline.run();
  }

  static final Schema ONE_LEVEL_UNNESTED_SCHEMA =
      Schema.builder()
          .addRowField("nested_nested1", SIMPLE_SCHEMA)
          .addRowField("nested_nested2", SIMPLE_SCHEMA)
          .build();

  static final Schema UNNESTED2_SCHEMA_ALTERNATE =
      Schema.builder().addInt32Field("field1").addStringField("field2").build();

  @Test
  @Category(NeedsRunner.class)
  public void testAlternateNamePolicyFlatten() {
    List<Row> bottomRow =
        IntStream.rangeClosed(0, 2)
            .mapToObj(i -> Row.withSchema(SIMPLE_SCHEMA).addValues(i, Integer.toString(i)).build())
            .collect(Collectors.toList());
    List<Row> rows =
        bottomRow.stream()
            .map(r -> Row.withSchema(NESTED_SCHEMA2).addValues(r).build())
            .collect(Collectors.toList());
    PCollection<Row> unnested =
        pipeline
            .apply(Create.of(rows).withRowSchema(NESTED_SCHEMA2))
            .apply(Select.<Row>flattenedSchema().keepMostNestedFieldName());
    assertEquals(UNNESTED2_SCHEMA_ALTERNATE, unnested.getSchema());
    List<Row> expected =
        bottomRow.stream()
            .map(
                r ->
                    Row.withSchema(UNNESTED2_SCHEMA_ALTERNATE)
                        .addValues(r.getValue(0), r.getValue(1))
                        .build())
            .collect(Collectors.toList());
    ;
    PAssert.that(unnested).containsInAnyOrder(expected);
    pipeline.run();
  }

  @Test
  @Category(NeedsRunner.class)
  public void testClashingNamePolicyFlatten() {
    List<Row> bottomRow =
        IntStream.rangeClosed(0, 2)
            .mapToObj(i -> Row.withSchema(SIMPLE_SCHEMA).addValues(i, Integer.toString(i)).build())
            .collect(Collectors.toList());
    thrown.expect(IllegalArgumentException.class);
    List<Row> rows =
        bottomRow.stream()
            .map(r -> Row.withSchema(NESTED_SCHEMA).addValues(r, r).build())
            .collect(Collectors.toList());
    PCollection<Row> unnested =
        pipeline
            .apply(Create.of(rows).withRowSchema(NESTED_SCHEMA))
            .apply(Select.<Row>flattenedSchema().keepMostNestedFieldName());
    pipeline.run();
  }

  static final Schema CLASHING_NAME_UNNESTED_SCHEMA =
      Schema.builder()
          .addInt32Field("field1")
          .addStringField("field2")
          .addInt32Field("n2field1")
          .addStringField("n2field2")
          .build();

  @Test
  @Category(NeedsRunner.class)
  public void testClashingNameWithRenameFlatten() {
    List<Row> bottomRow =
        IntStream.rangeClosed(0, 2)
            .mapToObj(i -> Row.withSchema(SIMPLE_SCHEMA).addValues(i, Integer.toString(i)).build())
            .collect(Collectors.toList());
    List<Row> rows =
        bottomRow.stream()
            .map(r -> Row.withSchema(NESTED_SCHEMA).addValues(r, r).build())
            .collect(Collectors.toList());
    PCollection<Row> unnested =
        pipeline
            .apply(Create.of(rows).withRowSchema(NESTED_SCHEMA))
            .apply(
                Select.<Row>flattenedSchema()
                    .keepMostNestedFieldName()
                    .withFieldNameAs("nested2.field1", "n2field1")
                    .withFieldNameAs("nested2.field2", "n2field2"));
    assertEquals(CLASHING_NAME_UNNESTED_SCHEMA, unnested.getSchema());
    pipeline.run();
  }

  @Test
  @Category(NeedsRunner.class)
  public void testFlattenWithOutputSchema() {
    List<Row> bottomRow =
        IntStream.rangeClosed(0, 2)
            .mapToObj(i -> Row.withSchema(SIMPLE_SCHEMA).addValues(i, Integer.toString(i)).build())
            .collect(Collectors.toList());
    List<Row> rows =
        bottomRow.stream()
            .map(r -> Row.withSchema(NESTED_SCHEMA).addValues(r, r).build())
            .collect(Collectors.toList());

    PCollection<Row> unnested =
        pipeline
            .apply(Create.of(rows).withRowSchema(NESTED_SCHEMA))
            .apply(Select.<Row>flattenedSchema().withOutputSchema(CLASHING_NAME_UNNESTED_SCHEMA));
    assertEquals(CLASHING_NAME_UNNESTED_SCHEMA, unnested.getSchema());
    pipeline.run();
  }
}


text:
"use strict";

var _ = require('lodash');
var express = require('express');
var app = express();
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var fs = require('fs-promise');
var path = require('path');
var readYaml = require('read-yaml-promise');
var serveContent = require('serve-content');
var jade = require('jade');

console.log('cwd',process.cwd());

var execToHtml=require('../..');

app.use(cookieParser());
app.use(bodyParser.urlencoded({extended:true}));

function serveJade(pathToFile,anyFile){
    return function(req,res,next){
        if(path.extname(req.path)){
            console.log('req.path',req.path);
            return next();
        }
        Promise.resolve().then(function(){
            var fileName=pathToFile+(anyFile?req.path+'.jade':'');
            return fs.readFile(fileName, {encoding: 'utf8'})
        }).catch(function(err){
            if(anyFile && err.code==='ENOENT'){
                throw new Error('next');
            }
            throw err;
        }).then(function(fileContent){
            var htmlText=jade.render(fileContent);
            serveHtmlText(htmlText)(req,res);
        }).catch(serveErr(req,res,next));
    }
}

// probar con http://localhost:12348/ajax-example
app.use('/',serveJade('examples/client',true));

function serveHtmlText(htmlText){
    return function(req,res){
        res.setHeader('Content-Type', 'text/html; charset=utf-8');
        res.setHeader('Content-Length', htmlText.length);
        res.end(htmlText);
    }
}

function serveErr(req,res,next){
    return function(err){
        if(err.message=='next'){
            return next();
        }
        console.log('ERROR', err);
        console.log('STACK', err.stack);
        var text='ERROR! '+(err.code||'')+'\n'+err.message+'\n------------------\n'+err.stack;
        res.writeHead(200, {
            'Content-Length': text.length,
            'Content-Type': 'text/plain; charset=utf-8'
        });
        res.end(text);
    }
}

var mime = serveContent.mime;

var validExts=[
    'html',
    'jpg','png','gif',
    'css','js','manifest'];

// ajax-best-promise.js
//

app.use('/ajax-best-promise.js',function(req,res){
    res.sendFile(process.cwd()+'/node_modules/ajax-best-promise/bin/ajax-best-promise.js');
});

app.use('/',serveContent('./examples/client', {
    index: ['index.html'],
    extensions:[''],
    staticExtensions:validExts
}));

var actualConfig;

var clientDb;

var PORT=12449;

var server=app.listen(PORT, function(event) {
    console.log('Listening on port %d', server.address().port);
});

app.get('/',serveHtmlText('
Exec-To-Html
'));

// localhost:12449/install?project=auto-deploy
app.use('/tools',execToHtml.middleware({baseDir:'../', control:true}));

redpajama_set_name: RedPajamaGithub


text:
package xtime

import "testing"

func TestDuration_UnmarshalText(t *testing.T) {
	t.Log(nil)
}

func TestTime_Scan(t *testing.T) {
	t.Log(nil)
}

func TestTime_Value(t *testing.T) {
	t.Log(nil)
}


text:
var kTestDirPath = 'mount/test_dir/';
// Test file that will remain unchanged during tests. Used to test read-only
// functionality.
var kTestFilePath = 'mount/test_dir/test_file.foo';
// File that will be used to test delete operation.
var kTestFileToDelete = 'mount/test_dir/test_file_to_delete.foo';
// File that will be used to test write operations.
var kMutableTestFile = 'mount/test_dir/mutable_test_file.foo';
// File that should be created while testing create operation.
// Initialy does not exist.
var kTestFileToCreate = 'mount/test_dir/new_test_file.foo';
// File that will be moved when testing move operation.
var kTestFileToMove = 'mount/test_dir/test_file_to_move.foo';
// Data that will be written when testing write operation.
var kWriteData = '!!!';
// Name of target file in copy operation test.
// The file will be located in the test dir.
var kCopiedFileName = 'copied_file.foo';
// Name of target file in move operation test.
// The file will be located in the test dir.
var kMovedFileName = 'moved_file.foo';
// Initial content of the test files.
var kTestFileContent = "hello, world!";

function TestRunner() {
  this.fileSystem_ = undefined;

  // The entry set in |runGetDirTest|.
  this.testDirEntry = undefined;
  // Read only file under |kTestFilePath|.
  this.testFileEntry = undefined;
  // Last entry set in |runGetFileTest|.
  this.lastFileEntry = undefined;
}

// Sets |testFileEntry| to |lastFileEntry|.
TestRunner.prototype.rememberLastFileEntry = function() {
  chrome.test.assertTrue(!!this.lastFileEntry, 'Cannot set null entry.');
  this.testFileEntry = this.lastFileEntry;
};

// Gets local filesystem used in tests.
TestRunner.prototype.init = function() {
  // Get local FS.
  console.log('Requesting local file system...');
  chrome.fileBrowserPrivate.requestLocalFileSystem(
      this.onFileSystemFetched_.bind(this));
};

TestRunner.prototype.onFileSystemFetched_ = function(fs) {
  chrome.test.assertTrue(!!fs, 'Error getting file system.');

  this.fileSystem_ = fs;
  chrome.test.succeed();
};

TestRunner.prototype.runGetFileTest = function(filePath, create, callback) {
  self = this;
  this.fileSystem_.root.getFile(filePath, {create: create},
      function(entry) {
        self.lastFileEntry = entry;
        callback('getting file', null);
      },
      callback.bind(null, 'getting file'));
};

TestRunner.prototype.runGetDirTest = function(filePath, create, callback) {
  self = this;
  this.fileSystem_.root.getDirectory(filePath, {create: create},
      function(entry) {
        self.testDirEntry = entry;
        callback('getting directory', null);
      },
      callback.bind(null, 'getting directory'));
};

TestRunner.prototype.runReadFileTest = function(entry, expectedText, callback) {
  readFile(entry,
    function(text) {
      chrome.test.assertEq(expectedText, text, 'Unexpected file content');
      callback('reading file', null);
    },
    callback.bind(null, 'reading file'));
};

TestRunner.prototype.runWriteFileTest = function(entry, callback) {
  var self = this;
  entry.createWriter(
    function(writer) {
      writer.onerror = function () {
        callback('writing to file', writer.error);
      };
      writer.onwrite = function(e) {
        callback('writing to file', null);
      };

      writer.write(new Blob([kWriteData], {'type': 'text/plain'}));
    },
    callback.bind(null, 'creating writer'));
};

TestRunner.prototype.runDeleteFileTest = function(entry, callback) {
  entry.remove(
      function() {
        callback('removing file', null);
      },
      callback.bind(null, 'removing file'));
};

TestRunner.prototype.runCopyFileTest = function(sourceEntry,
                                                targetDir,
                                                targetName,
                                                callback) {
  var self = this;
  sourceEntry.copyTo(targetDir, targetName,
      function (entry) {
        callback('copying file', null);
      },
      callback.bind(null, 'copying file'));
};

TestRunner.prototype.runMoveFileTest = function(sourceEntry,
                                                targetDir,
                                                targetName,
                                                callback) {
  var self = this;
  sourceEntry.moveTo(targetDir, targetName,
      function (entry) {
        callback('moving file', null);
      },
      callback.bind(null, 'moving file'));
};

function errorCodeToString(errorCode) {
  switch (errorCode) {
    case FileError.QUOTA_EXCEEDED_ERR:
      return 'QUOTA_EXCEEDED_ERR';
    case FileError.NOT_FOUND_ERR:
      return 'NOT_FOUND_ERR';
    case FileError.SECURITY_ERR:
      return 'SECURITY_ERR';
    case FileError.INVALID_MODIFICATION_ERR:
      return 'INVALID_MODIFICATION_ERR';
    case FileError.INVALID_STATE_ERR:
      return 'INVALID_STATE_ERR';
    default:
      return 'Unknown Error';
  }
}

// Checks operation results and ends the test.
// If the oiperation is supposed to fail, |expectedErrorCode| should be null.
// |error| is error returned by the operation. It is null if the operation
// succeeded.
// |testName| and |operation| parameters are used to make debugging strings
// displayed on test failure clearer and more helpful.
function verifyTestResult(testName, expectedErrorCode, operation, error) {
  if (!error && !expectedErrorCode) {
    chrome.test.succeed();
    return;
  }

  if (expectedErrorCode) {
    chrome.test.assertTrue(!!error,
        testName + ' unexpectedly succeeded. ' +
        'Expected error: ' + errorCodeToString(expectedErrorCode));
  }

  chrome.test.assertEq(expectedErrorCode, error.code,
      testName + ' got unexpected error.'+
      'Expected error: ' + errorCodeToString(expectedErrorCode) + '. ' +
      'Got error' + errorCodeToString(error.code) + ' while ' + operation);

  chrome.test.succeed();
}

chrome.test.runTests([
  function initTests() {
    testRunner = new TestRunner();
    testRunner.init();
  },
  function getFile() {
    testRunner.runGetFileTest(kTestFilePath, false,
        verifyTestResult.bind(null, 'Get Test File', null));
  },
  function saveFile() {
    testRunner.rememberLastFileEntry();
    chrome.test.succeed();
  },
  function getDirectory() {
    testRunner.runGetDirTest(kTestDirPath, false,
        verifyTestResult.bind(null, 'Get Directory', null));
  },
  function readFile() {
    chrome.test.assertTrue(!!testRunner.testFileEntry,
        'Test file entry should have been created by previousd tests.');
    testRunner.runReadFileTest(testRunner.testFileEntry, kTestFileContent,
        verifyTestResult.bind(null, 'Read File', null));
  },
  function copyFile() {
    chrome.test.assertTrue(!!testRunner.testFileEntry,
        'Test file entry should have been created by previousd tests.');
    chrome.test.assertTrue(!!testRunner.testDirEntry,
        'Test dir entry should have been created by previousd tests.');
    testRunner.runCopyFileTest(
        testRunner.testFileEntry,
        testRunner.testDirEntry,
        kCopiedFileName,
        verifyTestResult.bind(null, 'Copy File', FileError.SECURITY_ERR));
  },
  function getFileToMove() {
    testRunner.lastFileEntry = undefined;
    testRunner.runGetFileTest(kTestFileToMove, false,
        verifyTestResult.bind(null, 'Get File To Move', null));
  },
  function moveFile() {
    chrome.test.assertTrue(!!testRunner.lastFileEntry,
        'File entry to move should have been created by previousd tests.');
    chrome.test.assertTrue(!!testRunner.testDirEntry,
        'Test dir entry should have been created by previousd tests.');
    testRunner.runMoveFileTest(
        testRunner.lastFileEntry,
        testRunner.testDirEntry,
        kCopiedFileName,
        verifyTestResult.bind(null, 'Move File', FileError.SECURITY_ERR));
  },
  function getFileToWrite() {
    testRunner.lastFileEntry = undefined;
    testRunner.runGetFileTest(kMutableTestFile, false,
        verifyTestResult.bind(null, 'Get File To Write', null));
  },
  function writeFile() {
    chrome.test.assertTrue(!!testRunner.lastFileEntry,
        'File entry to write should have been created by previousd tests.');
    testRunner.runWriteFileTest(testRunner.lastFileEntry,
        verifyTestResult.bind(null, 'Write File', FileError.SECURITY_ERR));
  },
  function createFile() {
    testRunner.runGetFileTest(kTestFileToCreate, true,
        verifyTestResult.bind(null, 'Create File', FileError.SECURITY_ERR));
  },
  function getFileToDelete() {
    testRunner.lastFileEntry = undefined;
    testRunner.runGetFileTest(kTestFileToDelete, false,
        verifyTestResult.bind(null, 'Get File To Delete', null));
  },
  function deleteFile() {
    chrome.test.assertTrue(!!testRunner.lastFileEntry,
        'File entry to delete should have been created by previousd tests.');
    testRunner.runDeleteFileTest(testRunner.lastFileEntry,
        verifyTestResult.bind(null, 'Delete File', FileError.SECURITY_ERR));
  }
]);


text:
package org.spincast.plugins.jacksonjson;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;

import javax.annotation.Nullable;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spincast.core.config.SpincastConfig;
import org.spincast.core.json.JsonArray;
import org.spincast.core.json.JsonManager;
import org.spincast.core.json.JsonObject;
import org.spincast.core.json.JsonObjectFactory;
import org.spincast.core.json.JsonObjectOrArray;
import org.spincast.core.json.JsonPathUtils;
import org.spincast.core.request.Form;
import org.spincast.core.request.FormFactory;
import org.spincast.core.utils.SpincastStatics;
import org.spincast.core.utils.SpincastUtils;
import org.spincast.shaded.org.apache.commons.lang3.StringUtils;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.core.util.DefaultIndenter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter.Indenter;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;

/**
 * Spincast Jackson Json manager
 */
public class SpincastJsonManager implements JsonManager {

    protected static final Logger logger = LoggerFactory.getLogger(SpincastJsonManager.class);

    public static final String ENUM_SERIALIZER_FIELD_NAME_NAME = "name";
    public static final String ENUM_SERIALIZER_FIELD_NAME_LABEL = "label";

    private final JsonObjectFactory jsonObjectFactory;
    private final Provider<Injector> guiceProvider;
    private final Set<JsonMixinInfo> jsonMixinInfos;
    private final SpincastConfig spincastConfig;
    private final SpincastJsonManagerConfig spincastJsonManagerConfig;
    private final JsonPathUtils jsonPathUtils;
    private final SpincastUtils spincastUtils;
    private final FormFactory formFactory;

    private ObjectMapper objectMapper;
    private JsonSerializer<JsonObject> jsonObjectSerializer;
    private JsonDeserializer<JsonObject> jsonObjectDeserializer;
    private JsonSerializer<JsonArray> jsonArraySerializer;
    private JsonDeserializer<JsonArray> jsonArrayDeserializer;
    private JsonSerializer<Date> dateSerializer;
    private JsonSerializer<Instant> instantSerializer;
    private JsonSerializer<BigDecimal> bigDecimalSerializer;
    private DefaultPrettyPrinter jacksonPrettyPrinter;
    private JsonSerializer<Enum<?>> enumSerializer;

    @Inject
    public SpincastJsonManager(Provider<Injector> guiceProvider,
                               JsonObjectFactory jsonObjectFactory,
                               @Nullable Set<JsonMixinInfo> jsonMixinInfos,
                               SpincastJsonManagerConfig spincastJsonManagerConfig,
                               SpincastConfig spincastConfig,
                               JsonPathUtils jsonPathUtils,
                               SpincastUtils spincastUtils,
                               FormFactory formFactory) {

        this.guiceProvider = guiceProvider;
        this.jsonObjectFactory = jsonObjectFactory;

        if (jsonMixinInfos == null) {
            jsonMixinInfos = new HashSet<JsonMixinInfo>();
        }
        this.jsonMixinInfos = jsonMixinInfos;
        this.spincastJsonManagerConfig = spincastJsonManagerConfig;
        this.spincastConfig = spincastConfig;
        this.jsonPathUtils = jsonPathUtils;
        this.spincastUtils = spincastUtils;
        this.formFactory = formFactory;
    }

    protected Injector getGuice() {
        return this.guiceProvider.get();
    }

    protected JsonObjectFactory getJsonObjectFactory() {
        return this.jsonObjectFactory;
    }

    protected Set<JsonMixinInfo> getJsonMixinInfos() {
        return this.jsonMixinInfos;
    }

    protected SpincastJsonManagerConfig getSpincastJsonManagerConfig() {
        return this.spincastJsonManagerConfig;
    }

    protected SpincastConfig getSpincastConfig() {
        return this.spincastConfig;
    }

    protected JsonPathUtils getJsonPathUtils() {
        return this.jsonPathUtils;
    }

    protected SpincastUtils getSpincastUtils() {
        return this.spincastUtils;
    }

    protected FormFactory getFormFactory() {
        return this.formFactory;
    }

    protected DefaultPrettyPrinter getJacksonPrettyPrinter() {
        if (this.jacksonPrettyPrinter == null) {
            this.jacksonPrettyPrinter = new DefaultPrettyPrinter();

            Indenter indenter = new DefaultIndenter(getJacksonPrettyPrinterIndentation(), getJacksonPrettyPrinterNewline());

            this.jacksonPrettyPrinter.indentObjectsWith(indenter);
            this.jacksonPrettyPrinter.indentArraysWith(indenter);
        }
        return this.jacksonPrettyPrinter;
    }

    protected String getJacksonPrettyPrinterNewline() {
        return getSpincastJsonManagerConfig().getPrettyPrinterNewlineChars();
    }

    protected String getJacksonPrettyPrinterIndentation() {
        return StringUtils.repeat(" ", getSpincastJsonManagerConfig().getPrettyPrinterIndentationSpaceNumber());
    }

    protected ObjectMapper getObjectMapper() {
        if (this.objectMapper == null) {

            ObjectMapper objectMapper = createObjectManager();
            registerCustomModules(objectMapper);
            this.objectMapper = objectMapper;
        }
        return this.objectMapper;
    }

    /**
     * Creates the ObjectMapper
     */
    protected ObjectMapper createObjectManager() {
        ObjectMapper objectMapper = new ObjectMapper();
        configureObjectMapper(objectMapper);
        return objectMapper;
    }

    /**
     * Configuration of the ObjectMapper.
     */
    protected void configureObjectMapper(ObjectMapper objectMapper) {

        objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, isAllowCommentsInJson());

        //==========================================
        // To allow serialization of "empty" POJOs (no properties to serialize)
        // (without this setting, an exception is thrown in those cases)
        //==========================================
        configureEmptyBeans(objectMapper);

        //==========================================
        // Add the mixins, if any.
        //==========================================
        configureMixins(objectMapper);
    }

    /**
     * Should comments be accepted in Json?
     * @see https://github.com/FasterXML/jackson-core/wiki/JsonParser-Features#support-for-non-standard-data-format-constructs
     */
    protected boolean isAllowCommentsInJson() {

        //==========================================
        // Accepted by default
        //==========================================
        return true;
    }

    protected void configureEmptyBeans(ObjectMapper objectMapper) {
        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
    }

    protected void configureMixins(ObjectMapper objectMapper) {
        for (JsonMixinInfo jsonMixinInfo : getJsonMixinInfos()) {
            objectMapper.addMixIn(jsonMixinInfo.getTargetClass(), jsonMixinInfo.getMixinClass());
        }
    }

    protected JsonSerializer<JsonObject> getJsonObjectSerializer() {

        if (this.jsonObjectSerializer == null) {
            this.jsonObjectSerializer = new JsonSerializer<JsonObject>() {

                @Override
                public void serialize(JsonObject jsonObject,
                                      JsonGenerator gen,
                                      SerializerProvider serializers)
                                                                      throws IOException, JsonProcessingException {

                    if (jsonObject == null) {
                        return;
                    }

                    Map<String, Object> asMap = jsonObject.convertToPlainMap();
                    gen.writeObject(asMap);
                }
            };
        }
        return this.jsonObjectSerializer;
    }

    protected JsonSerializer<Enum<?>> getEnumSerializer() {

        if (this.enumSerializer == null) {
            this.enumSerializer = new JsonSerializer<Enum<?>>() {

                @Override
                public void serialize(Enum<?> enumValue,
                                      JsonGenerator gen,
                                      SerializerProvider serializers)
                                                                      throws IOException, JsonProcessingException {

                    if (enumValue == null) {
                        return;
                    }

                    Map<String, Object> enumObj = new HashMap<String, Object>();
                    enumObj.put(ENUM_SERIALIZER_FIELD_NAME_NAME, enumValue.name());
                    enumObj.put(ENUM_SERIALIZER_FIELD_NAME_LABEL, enumValue.toString());

                    gen.writeObject(enumObj);
                }
            };
        }
        return this.enumSerializer;
    }

    protected JsonSerializer<JsonArray> getJsonArraySerializer() {

        if (this.jsonArraySerializer == null) {
            this.jsonArraySerializer = new JsonSerializer<JsonArray>() {

                @Override
                public void serialize(JsonArray jsonArray,
                                      JsonGenerator gen,
                                      SerializerProvider serializers)
                                                                      throws IOException, JsonProcessingException {

                    if (jsonArray == null) {
                        return;
                    }

                    List<Object> asList = jsonArray.convertToPlainList();
                    gen.writeObject(asList);
                }
            };
        }
        return this.jsonArraySerializer;
    }

    protected JsonSerializer<Date> getDateSerializer() {

        if (this.dateSerializer == null) {
            this.dateSerializer = new JsonSerializer<Date>() {

                @Override
                public void serialize(Date date,
                                      JsonGenerator gen,
                                      SerializerProvider serializers)
                                                                      throws IOException, JsonProcessingException {

                    if (date == null) {
                        return;
                    }

                    String dateStr = SpincastStatics.getIso8601DateParserDefault().format(date);
                    gen.writeObject(dateStr);
                }
            };
        }
        return this.dateSerializer;
    }

    protected JsonSerializer<Instant> getInstantSerializer() {

        if (this.instantSerializer == null) {
            this.instantSerializer = new JsonSerializer<Instant>() {

                @Override
                public void serialize(Instant instant,
                                      JsonGenerator gen,
                                      SerializerProvider serializers)
                                                                      throws IOException, JsonProcessingException {

                    if (instant == null) {
                        return;
                    }
                    getDateSerializer().serialize(Date.from(instant), gen, serializers);
                }
            };
        }
        return this.instantSerializer;
    }

    protected JsonSerializer<BigDecimal> getBigDecimalSerializer() {

        if (this.bigDecimalSerializer == null) {
            this.bigDecimalSerializer = new JsonSerializer<BigDecimal>() {

                @Override
                public void serialize(BigDecimal bigDecimal,
                                      JsonGenerator gen,
                                      SerializerProvider serializers)
                                                                      throws IOException, JsonProcessingException {

                    if (bigDecimal == null) {
                        return;
                    }
                    gen.writeObject(bigDecimal.toPlainString());
                }
            };
        }
        return this.bigDecimalSerializer;
    }

    protected JsonDeserializer<JsonObject> getJsonObjectDeserializer() {

        if (this.jsonObjectDeserializer == null) {
            this.jsonObjectDeserializer = new JsonDeserializer<JsonObject>() {

                @Override
                public JsonObject deserialize(JsonParser jsonParser,
                                              DeserializationContext context)
                                                                              throws IOException,
                                                                              JsonProcessingException {

                    JsonObject jsonObject = getJsonObjectFactory().create();

                    JsonToken jsonToken = jsonParser.getCurrentToken();
                    if (jsonToken == JsonToken.START_OBJECT) {
                        jsonToken = jsonParser.nextToken();
                    } else {
                        throw new RuntimeException("Invalid json object");
                    }

                    while (jsonToken != null) {

                        if (jsonToken != JsonToken.FIELD_NAME) {
                            break;
                        }

                        String name = jsonParser.getCurrentName();
                        jsonToken = jsonParser.nextToken();

                        if (jsonToken == JsonToken.START_OBJECT) {
                            jsonObject.set(name, deserialize(jsonParser, context));

                        } else if (jsonToken == JsonToken.START_ARRAY) {
                            jsonObject.set(name, getJsonArrayDeserializer().deserialize(jsonParser, context));

                        } else if (jsonToken == JsonToken.VALUE_EMBEDDED_OBJECT) {
                            jsonObject.set(name, jsonParser.getEmbeddedObject());

                        } else if (jsonToken == JsonToken.VALUE_NULL) {
                            jsonObject.set(name, null);

                        } else if (jsonToken == JsonToken.VALUE_STRING) {
                            jsonObject.set(name, jsonParser.getText());

                        } else if (jsonToken == JsonToken.VALUE_TRUE) {
                            jsonObject.set(name, true);

                        } else if (jsonToken == JsonToken.VALUE_FALSE) {
                            jsonObject.set(name, false);

                        } else if (jsonToken == JsonToken.VALUE_NUMBER_INT ||
                                   jsonToken == JsonToken.VALUE_NUMBER_FLOAT) {
                            jsonObject.set(name, jsonParser.getNumberValue());

                        } else {
                            throw new RuntimeException("Unmanaged json token type : " + jsonToken);
                        }

                        jsonToken = jsonParser.nextToken();
                    }

                    return jsonObject;
                }
            };
        }

        return this.jsonObjectDeserializer;
    }

    protected JsonDeserializer<JsonArray> getJsonArrayDeserializer() {

        if (this.jsonArrayDeserializer == null) {
            this.jsonArrayDeserializer = new JsonDeserializer<JsonArray>() {

                @Override
                public JsonArray deserialize(JsonParser jsonParser,
                                             DeserializationContext context)
                                                                             throws IOException,
                                                                             JsonProcessingException {

                    JsonArray jsonArray = getJsonObjectFactory().createArray();

                    JsonToken jsonToken = jsonParser.getCurrentToken();
                    if (jsonToken == JsonToken.START_ARRAY) {
                        jsonToken = jsonParser.nextToken();
                    } else {
                        throw new RuntimeException("Invalid json array");
                    }

                    while (jsonToken != null) {

                        if (jsonToken == JsonToken.END_ARRAY) {
                            break;
                        }

                        if (jsonToken == JsonToken.START_OBJECT) {
                            jsonArray.add(getJsonObjectDeserializer().deserialize(jsonParser, context));

                        } else if (jsonToken == JsonToken.START_ARRAY) {
                            jsonArray.add(deserialize(jsonParser, context));

                        } else if (jsonToken == JsonToken.VALUE_EMBEDDED_OBJECT) {
                            jsonArray.add(jsonParser.getEmbeddedObject());

                        } else if (jsonToken == JsonToken.VALUE_NULL) {
                            jsonArray.add(null);

                        } else if (jsonToken == JsonToken.VALUE_STRING) {
                            jsonArray.add(jsonParser.getText());

                        } else if (jsonToken == JsonToken.VALUE_TRUE) {
                            jsonArray.add(true);

                        } else if (jsonToken == JsonToken.VALUE_FALSE) {
                            jsonArray.add(false);

                        } else if (jsonToken == JsonToken.VALUE_NUMBER_INT ||
                                   jsonToken == JsonToken.VALUE_NUMBER_FLOAT) {
                            jsonArray.add(jsonParser.getNumberValue());

                        } else {
                            throw new RuntimeException("Unmanaged json token type : " + jsonToken);
                        }

                        jsonToken = jsonParser.nextToken();
                    }
                    return jsonArray;
                }
            };
        }

        return this.jsonArrayDeserializer;
    }

    protected void registerCustomModules(ObjectMapper objectMapper) {
        registerJsonObjectModule(objectMapper);
        registerCustomTypeSerializerModule(objectMapper);
        registerJava8DatatypesModule(objectMapper);
    }

    /**
     * Register our custom (de)serializers for JsonObject
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    protected void registerJsonObjectModule(ObjectMapper objectMapper) {

        SimpleModule module = new SimpleModule();
        module.addSerializer(JsonObject.class, getJsonObjectSerializer());
        module.addDeserializer(JsonObject.class, getJsonObjectDeserializer());
        module.addSerializer(JsonArray.class, getJsonArraySerializer());
        module.addDeserializer(JsonArray.class, getJsonArrayDeserializer());

        if (getSpincastJsonManagerConfig().isSerializeEnumsToNameAndLabelObjects()) {
            module.addSerializer((Class)Enum.class, getEnumSerializer());
        }

        objectMapper.registerModule(module);
    }

    /**
     * Register our custom serializers for some types.
     */
    protected void registerCustomTypeSerializerModule(ObjectMapper objectMapper) {

        SimpleModule module = new SimpleModule();
        module.addSerializer(Date.class, getDateSerializer());
        module.addSerializer(Instant.class, getInstantSerializer());
        module.addSerializer(BigDecimal.class, getBigDecimalSerializer());
        objectMapper.registerModule(module);
    }

    protected void registerJava8DatatypesModule(ObjectMapper objectMapper) {
        objectMapper.registerModule(new Jdk8Module());
    }

    @Override
    public String toJsonString(Object obj) {
        return toJsonString(obj, false);
    }

    @Override
    public String toJsonString(Object obj, boolean pretty) {
        try {
            if (pretty) {
                return getObjectMapper().writer(getJacksonPrettyPrinter()).writeValueAsString(obj);
            } else {
                return getObjectMapper().writeValueAsString(obj);
            }
        } catch (Exception ex) {
            throw SpincastStatics.runtimize(ex);
        }
    }

    /**
     * Once the deserialization of an Object is done,
     * we inject dependencies using Guice.
     */
    protected void injectDependencies(Object obj) {
        if (obj != null) {
            getGuice().injectMembers(obj);
        }
    }

    @Override
    public JsonObject create() {
        return getJsonObjectFactory().create();
    }

    @Override
    public JsonArray createArray() {
        return getJsonObjectFactory().createArray();
    }

    @Override
    public JsonObject fromObject(Object object) {
        JsonObject jsonObj = getObjectMapper().convertValue(object, JsonObject.class);
        return jsonObj;
    }

    @Override
    public <T> T fromString(String jsonString, Class<T> clazz) {
        if (jsonString == null) {
            return null;
        }

        try {
            T jsonObj = getObjectMapper().readValue(jsonString, clazz);
            injectDependencies(jsonObj);
            return jsonObj;
        } catch (Exception ex) {
            throw SpincastStatics.runtimize(ex);
        }
    }

    @Override
    public <T> T fromInputStream(InputStream inputStream, Class<T> clazz) {
        if (inputStream == null) {
            return null;
        }

        try {
            T jsonObj = getObjectMapper().readValue(inputStream, clazz);
            injectDependencies(jsonObj);
            return jsonObj;
        } catch (Exception ex) {
            throw SpincastStatics.runtimize(ex);
        }
    }

    @Override
    public Map<String, Object> fromStringToMap(String jsonString) {
        if (jsonString == null) {
            return null;
        }

        try {
            Map<String, Object> map = getObjectMapper().readValue(jsonString, new TypeReference<Map<String, Object>>() {});
            return map;
        } catch (Exception ex) {
            throw SpincastStatics.runtimize(ex);
        }
    }

    @Override
    public Map<String, Object> fromInputStreamToMap(InputStream inputStream) {
        if (inputStream == null) {
            return null;
        }

        try {
            Map<String, Object> map = getObjectMapper().readValue(inputStream,
                                                                  new TypeReference<Map<String, Object>>() {});
            return map;
        } catch (Exception ex) {
            throw SpincastStatics.runtimize(ex);
        }
    }

    @Override
    public JsonObject fromString(String jsonString) {
        if (jsonString == null) {
            return null;
        }

        try {
            JsonObject obj = getObjectMapper().readValue(jsonString, JsonObject.class);
            return obj;
        } catch (Exception ex) {
            throw SpincastStatics.runtimize(ex);
        }
    }

    @Override
    public JsonObject fromMap(Map<String, ?> params) {
        if (params == null) {
            return null;
        }

        return fromMap(params, false);
    }

    @Override
    public JsonObject fromMap(Map<String, ?> params, boolean parseKeysAsJsonPaths) {
        if (params == null) {
            return null;
        }

        JsonObject root = getJsonObjectFactory().create();
        if (parseKeysAsJsonPaths && params.size() > getMaxNumberOfKeysWhenConvertingMapToJsonObject()) {
            throw new RuntimeException("Too many keys to parse : " + params.size() + " as JsonPaths. " +
                                       "The maximum is currently set to " + getMaxNumberOfKeysWhenConvertingMapToJsonObject());
        }

        for (Entry<String, ?> entry : params.entrySet()) {

            String key = entry.getKey();
            Object value = entry.getValue();

            if (parseKeysAsJsonPaths) {
                putElementAtJsonPath(root, key, value, true);
            } else {
                root.setNoKeyParsing(key, value);
            }
        }

        return root;
    }

    @Override
    public JsonObject fromInputStream(InputStream inputStream) {
        if (inputStream == null) {
            return null;
        }

        try {
            JsonObject obj = getObjectMapper().readValue(inputStream, JsonObject.class);
            return obj;
        } catch (Exception ex) {
            throw SpincastStatics.runtimize(ex);
        }
    }

    @Override
    public JsonObject fromFile(File jsonFile) {
        if (jsonFile == null || !jsonFile.exists()) {
            return null;
        }

        try {
            JsonObject obj = getObjectMapper().readValue(jsonFile, JsonObject.class);
            return obj;
        } catch (Exception ex) {
            throw SpincastStatics.runtimize(ex);
        }
    }

    @Override
    public JsonObject fromFile(String path) {
        Objects.requireNonNull(path, "The path can't be NULL");

        File file = new File(path);
        return fromFile(file);
    }

    @Override
    public JsonObject fromClasspathFile(String path) {
        Objects.requireNonNull(path, "The path can't be NULL");

        String content = getSpincastUtils().readClasspathFile(path);
        return fromString(content);
    }

    @Override
    public JsonArray fromCollectionToJsonArray(Collection<?> collection) {
        JsonArray jsonArray = getObjectMapper().convertValue(collection, JsonArray.class);
        return jsonArray;
    }

    @Override
    public JsonArray fromStringArray(String jsonString) {
        if (jsonString == null) {
            return null;
        }

        try {
            JsonArray obj = getObjectMapper().readValue(jsonString, JsonArray.class);
            return obj;
        } catch (Exception ex) {
            throw SpincastStatics.runtimize(ex);
        }
    }

    @Override
    public JsonArray fromListArray(List<?> elements) {
        if (elements == null) {
            return null;
        }

        JsonArray array = createArray();
        if (elements != null) {
            for (Object element : elements) {
                array.add(element);
            }
        }

        return array;
    }

    @Override
    public JsonArray fromInputStreamArray(InputStream inputStream) {
        if (inputStream == null) {
            return null;
        }

        try {
            JsonArray obj = getObjectMapper().readValue(inputStream, JsonArray.class);
            return obj;
        } catch (Exception ex) {
            throw SpincastStatics.runtimize(ex);
        }
    }

    protected int getMaxNumberOfKeysWhenConvertingMapToJsonObject() {
        return getSpincastConfig().getMaxNumberOfKeysWhenConvertingMapToJsonObject();
    }

    @Override
    public Object getElementAtJsonPath(JsonObject obj, String jsonPath) {
        return getJsonPathUtils().getElementAtJsonPath(obj, jsonPath);
    }

    @Override
    public Object getElementAtJsonPath(JsonObject obj, String jsonPath, Object defaultValue) {
        return getJsonPathUtils().getElementAtJsonPath(obj, jsonPath, defaultValue);
    }

    @Override
    public Object getElementAtJsonPath(JsonArray array, String jsonPath) {
        return getJsonPathUtils().getElementAtJsonPath(array, jsonPath);
    }

    @Override
    public Object getElementAtJsonPath(JsonArray array, String jsonPath, Object defaultValue) {
        return getJsonPathUtils().getElementAtJsonPath(array, jsonPath, defaultValue);
    }

    @Override
    public void putElementAtJsonPath(JsonObjectOrArray objOrArray, String jsonPath, Object value) {
        putElementAtJsonPath(objOrArray, jsonPath, value, false);
    }

    @Override
    public void putElementAtJsonPath(JsonObjectOrArray objOrArray, String jsonPath, Object value, boolean clone) {

        if (clone) {
            value = clone(value);
        }

        getJsonPathUtils().putElementAtJsonPath(objOrArray, jsonPath, value);
    }

    @Override
    public Form createForm(String formName) {
        return getFormFactory().createForm(formName, null);
    }

    @Override
    public String convertToJsonDate(Date date) {
        return SpincastStatics.getIso8601DateParserDefault().format(date);
    }

    /**
     * Currently support ISO 8601 encoded dates.
     */
    @Override
    public Date parseDateFromJson(String str) {
        return SpincastStatics.parseISO8601date(str);
    }

    @Override
    public Object convertToNativeType(Object originalObject) {

        if (originalObject == null) {
            return null;
        }

        //==========================================
        // Already a native type
        //==========================================
        if ((originalObject instanceof String) ||
            (originalObject instanceof Integer) ||
            (originalObject instanceof Long) ||
            (originalObject instanceof Float) ||
            (originalObject instanceof Double) ||
            (originalObject instanceof Boolean) ||
            (originalObject instanceof BigDecimal) ||
            (originalObject instanceof byte[]) ||
            (originalObject instanceof Date) ||
            (originalObject instanceof Instant) ||
            (originalObject instanceof JsonObject) ||
            (originalObject instanceof JsonArray)) {

            return originalObject;
        }

        //==========================================
        // Array or Collection
        //==========================================
        if (originalObject instanceof Collection<?>) {

            JsonArray array = createArray();
            for (Object element : (Collection<?>)originalObject) {
                array.add(element);
            }
            return array;

        } else if (originalObject instanceof Object[]) {

            JsonArray array = createArray();
            for (Object element : (Object[])originalObject) {
                array.add(element);
            }
            return array;

        } else if (originalObject instanceof Map) {

            JsonObject obj = create();

            Map<?, ?> map = (Map<?, ?>)originalObject;
            for (Entry<?, ?> entry : map.entrySet()) {
                if (entry.getKey() == null) {
                    throw new RuntimeException("Cannot convert a Map to a JsonObject when a key is NULL.");
                }
                obj.setNoKeyParsing(String.valueOf(entry.getKey()),
                                    entry.getValue());
            }

            return obj;

        }
        //==========================================
        // Why this? Don't we want ".name" and ".label" to be generated?
        // We would have that using the "Converts to a JsonObject"
        // code below because of our custom Json serializer.
        //
        // But only using the *names* of the enum values
        // is very useful since it is then possible to use
        // the serialized data as is in some filters. For
        // example :
        //
        // {{something | checked(menuItemForm.availabilityTypes)}}
        //
        // Here, if "menuItemForm.availabilityTypes" was an object with
        // ".name" and ".label" properties, the filter wouldn't work.
        //
        // To convert an enum to a "friendly" JsonObject, one can
        // use the "enumToFriendlyJsonObject(...)" and
        // "enumsToFriendlyJsonArray(...)" methods.
        //==========================================
        else if (originalObject instanceof Enum<?>) {
            return ((Enum<?>)originalObject).name();
        }

        //==========================================
        // Converts to a JsonObject or returns as
        // a string
        //==========================================
        String jsonStr = toJsonString(originalObject);

        if (jsonStr.startsWith("\"") && jsonStr.endsWith("\"") && jsonStr.length() > 1) {
            jsonStr = jsonStr.substring(1, jsonStr.length() - 1);
            return jsonStr;
        }

        JsonObject jsonObject = fromString(jsonStr);
        return jsonObject;
    }

    @Override
    public JsonObject cloneJsonObject(JsonObject jsonObject, boolean mutable) {
        return (JsonObject)clone(jsonObject, mutable);
    }

    @Override
    public JsonArray cloneJsonArray(JsonArray jsonArray, boolean mutable) {
        return (JsonArray)clone(jsonArray, mutable);
    }

    @Override
    public Object clone(Object originalObject) {
        return clone(originalObject, true);
    }

    @Override
    public Object clone(Object originalObject, boolean mutable) {

        if (originalObject == null) {
            return null;
        }

        if ((originalObject instanceof String) ||
            (originalObject instanceof Integer) ||
            (originalObject instanceof Long) ||
            (originalObject instanceof Float) ||
            (originalObject instanceof Double) ||
            (originalObject instanceof Boolean) ||
            (originalObject instanceof BigDecimal) ||
            (originalObject instanceof byte[]) ||
            (originalObject instanceof Date)) {
            return originalObject;

        } else if (originalObject instanceof JsonObject) {

            JsonObject jsonObj = (JsonObject)originalObject;

            //==========================================
            // Already immutable, no need to clone!
            //==========================================
            if (!mutable && !jsonObj.isMutable()) {
                return jsonObj;
            }

            Map<String, Object> map = new HashMap<String, Object>();
            for (Entry<String, Object> entry : jsonObj) {
                Object elementClone = clone(entry.getValue(), mutable);
                map.put(entry.getKey(), elementClone);
            }
            return getJsonObjectFactory().create(map, mutable);

        } else if (originalObject instanceof JsonArray) {

            JsonArray array = (JsonArray)originalObject;

            //==========================================
            // Already immutable, no need to clone!
            //==========================================
            if (!mutable && !array.isMutable()) {
                return array;
            }

            List<Object> elements = new ArrayList<Object>();
            for (Object element : array) {
                Object elementClone = clone(element, mutable);
                elements.add(elementClone);
            }

            return getJsonObjectFactory().createArray(elements, mutable);

        } else {
            return convertToNativeType(originalObject);
        }
    }

    @Override
    public void removeElementAtJsonPath(JsonObject obj, String jsonPath) {
        getJsonPathUtils().removeElementAtJsonPath(obj, jsonPath);
    }

    @Override
    public void removeElementAtJsonPath(JsonArray array, String jsonPath) {
        getJsonPathUtils().removeElementAtJsonPath(array, jsonPath);
    }

    @Override
    public boolean isElementExists(JsonObject obj, String jsonPath) {
        return getJsonPathUtils().isElementExists(obj, jsonPath);
    }

    @Override
    public boolean isElementExists(JsonArray array, String jsonPath) {
        return getJsonPathUtils().isElementExists(array, jsonPath);
    }

    @Override
    public JsonObject enumToFriendlyJsonObject(Enum<?> enumValue) {

        if (enumValue == null) {
            return null;
        }
        JsonObject obj = create();
        obj.set(ENUM_SERIALIZER_FIELD_NAME_NAME, enumValue.name());
        obj.set(ENUM_SERIALIZER_FIELD_NAME_LABEL, enumValue.toString());

        return obj;
    }

    @Override
    public JsonArray enumsToFriendlyJsonArray(Enum<?>[] enumValues) {

        JsonArray arr = createArray();
        if (enumValues == null || enumValues.length == 0) {
            return arr;
        }

        for (Enum<?> enumValue : enumValues) {
            arr.add(enumToFriendlyJsonObject(enumValue));
        }

        return arr;
    }

}


text:
package com.thingtrack.konekti.map.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

/**
 * @author Thingtrack S.L.
 *
 */
@SuppressWarnings("serial")
@Entity
@Table(name="CARD")
public class Card implements Serializable {
	@Id
	@Column(name="CARD_ID")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Integer cardId;

	@ManyToOne
	@JoinColumn(name="CARD_TYPE_ID", nullable=false)
	private CardType cardType;

	@ManyToOne
	@JoinColumn(name="MAP_ID", nullable=false)
	private Map map;

	@Column(name="CODE", length=64, unique=true, nullable=false)
	private String code;

	@Column(name="NAME", length=64, nullable=false)
	private String name;

	@Column(name="IMAGE", length=64)
	private String image;

	@Column(name="WEB", length=64)
	private String web;

	@Column(name="EMAIL", length=64)
	private String email;

	@Column(name="FIRST_PHONE", length=64)
	private String firstPhone;

	@Column(name="SECOND_PHONE", length=64)
	private String secondPhone;

	@Column(name="OBSERVATION", length=256)
	private String observation;

	@Column(name="SLOGAN", length=32)
	private String slogan;

	@Column(name="SPONSOR")
	private boolean sponsor;

	@Column(name="COUPONING")
	private boolean couponing;

	@Column(name="SCHEDULE_DATE_FROM")
	@Temporal(TemporalType.TIMESTAMP)
	private Date scheduleDateFrom;

	@Column(name="SCHEDULE_DATE_TO")
	@Temporal(TemporalType.TIMESTAMP)
	private Date scheduleDateTo;

	@OneToMany(mappedBy="card")
	private List<Marker> markers = new ArrayList<Marker>();

	@OneToMany(mappedBy="card")
	private List<Campaign> campaigns = new ArrayList<Campaign>();

	/**
	 * @return the cardId
	 */
	public Integer getCardId() {
		return cardId;
	}

	/**
	 * @param cardId the cardId to set
	 */
	public void setCardId(Integer cardId) {
		this.cardId = cardId;
	}

	/**
	 * @return the cardType
	 */
	public CardType getCardType() {
		return cardType;
	}

	/**
	 * @param cardType the cardType to set
	 */
	public void setCardType(CardType cardType) {
		this.cardType = cardType;
	}

	/**
	 * @return the map
	 */
	public Map getMap() {
		return map;
	}

	/**
	 * @param map the map to set
	 */
	public void setMap(Map map) {
		this.map = map;
	}

	/**
	 * @return the code
	 */
	public String getCode() {
		return code;
	}

	/**
	 * @param code the code to set
	 */
	public void setCode(String code) {
		this.code = code;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the image
	 */
	public String getImage() {
		return image;
	}

	/**
	 * @param image the image to set
	 */
	public void setImage(String image) {
		this.image = image;
	}

	/**
	 * @return the web
	 */
	public String getWeb() {
		return web;
	}

	/**
	 * @param web the web to set
	 */
	public void setWeb(String web) {
		this.web = web;
	}

	/**
	 * @return the email
	 */
	public String getEmail() {
		return email;
	}

	/**
	 * @param email the email to set
	 */
	public void setEmail(String email) {
		this.email = email;
	}

	/**
	 * @return the firstPhone
	 */
	public String getFirstPhone() {
		return firstPhone;
	}

	/**
	 * @param firstPhone the firstPhone to set
	 */
	public void setFirstPhone(String firstPhone) {
		this.firstPhone = firstPhone;
	}

	/**
	 * @return the secondPhone
	 */
	public String getSecondPhone() {
		return secondPhone;
	}

	/**
	 * @param secondPhone the secondPhone to set
	 */
	public void setSecondPhone(String secondPhone) {
		this.secondPhone = secondPhone;
	}

	/**
	 * @return the observation
	 */
	public String getObservation() {
		return observation;
	}

	/**
	 * @param observation the observation to set
	 */
	public void setObservation(String observation) {
		this.observation = observation;
	}

	/**
	 * @return the slogan
	 */
	public String getSlogan() {
		return slogan;
	}

	/**
	 * @param slogan the slogan to set
	 */
	public void setSlogan(String slogan) {
		this.slogan = slogan;
	}

	/**
	 * @return the sponsor
	 */
	public boolean isSponsor() {
		return sponsor;
	}

	/**
	 * @param sponsor the sponsor to set
	 */
	public void setSponsor(boolean sponsor) {
		this.sponsor = sponsor;
	}

	/**
	 * @return the couponing
	 */
	public boolean isCouponing() {
		return couponing;
	}

	/**
	 * @param couponing the couponing to set
	 */
	public void setCouponing(boolean couponing) {
		this.couponing = couponing;
	}

	/**
	 * @return the scheduleDateFrom
	 */
	public Date getScheduleDateFrom() {
		return scheduleDateFrom;
	}

	/**
	 * @param scheduleDateFrom the scheduleDateFrom to set
	 */
	public void setScheduleDateFrom(Date scheduleDateFrom) {
		this.scheduleDateFrom = scheduleDateFrom;
	}

	/**
	 * @return the scheduleDateTo
	 */
	public Date getScheduleDateTo() {
		return scheduleDateTo;
	}

	/**
	 * @param scheduleDateTo the scheduleDateTo to set
	 */
	public void setScheduleDateTo(Date scheduleDateTo) {
		this.scheduleDateTo = scheduleDateTo;
	}

	/**
	 * @return the markers
	 */
	public List<Marker> getMarkers() {
		return markers;
	}

	/**
	 * @param pins the markers to set
	 */
	public void setMarkers(List<Marker> markers) {
		this.markers = markers;
	}

	/**
	 * @return the campaigns
	 */
	public List<Campaign> getCampaigns() {
		return campaigns;
	}

	/**
	 * @param campaigns the campaigns to set
	 */
	public void setCampaigns(List<Campaign> campaigns) {
		this.campaigns = campaigns;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return this.name;

	}

}


text:
<?php //debug($shop_info); ?>

SHOP HEADER

            <?php echo Form::open(array('method' => 'post')); ?>

                   Shop name
                  <input type="textarea" name = "shop_name" class="form-control" id="exampleInputEmail1" placeholder="shop name">

                    Address

                    <?php foreach($master_info['region'] as $master_id => $master_value):?>

                      <input type="radio" name="region" value="<?=$master_id;?>"><?=$master_value;?>

                    <?php endforeach;?>

                 <input type="textarea" name="address" class="form-control" id="exampleInputPassword1" placeholder="Shop address">

                 Phone

                  <input type="text" name="phone" class="form-control" data-inputmask='"mask": "(999) 999-9999"' data-mask>

                   Coupon icon
                  <select class="form-control" name="coupon_icon">
                    <option>ON</option>
                    <option>OFF</option>
                  </select>

                   Report icon
                  <select class="form-control" name="report_icon">
                    <option>ON</option>
                    <option>OFF</option>
                  </select>

                   Genre

                    <?php foreach ($master_info['genre'] as $master_id => $master_value): ?>

                      <input type="checkbox" name="genre_id" value="<?=$master_id;?>"><?=$master_value;?>

                    <?php endforeach; ?>

                   description
                  <input type="textarea" class="form-control" name="description" id="exampleInputEmail1" placeholder="description">

                   Main visual
                  <input type="file" id="exampleInputFile" name="header_img">

                <button type="submit" class="btn btn-primary" style="margin:15px">Submit</button>

SHOP INFO

            <form role="form">

                   Address
                  <input type="textarea" class="form-control" name="address_info" id="exampleInputEmail1" placeholder="Address">

                    Business hours
                  <input type="textarea" class="form-control" name="businesshours" id="exampleInputPassword1" placeholder="Business hours">

                   Average price
                  <input type="textarea" class="form-control" name="price" id="exampleInputPassword1" placeholder="Average price">

                   Credit

                    <?php foreach ($master_info['credit_id'] as $master_id => $master_value): ?>

                      <input type="checkbox" name="credit_id" value="<?=$master_id;?>"><?=$master_value;?>

                    <?php endforeach; ?>

                 Phone

                  <input type="text" class="form-control" name="phone_number" data-inputmask='"mask": "(999) 999-9999"' data-mask>

                   Wi-fi
                  <select class="form-control" name="wi-fi">
                    <option>yes</option>
                    <option>no</option>
                  </select>

                <button type="submit" class="btn btn-primary" style="margin:15px">Submit</button>

            </form>

          <?php echo Form::close(); ?>


text: extern int *get_pids (char *process_name, int get_all);


text:
using namespace BinaryNinja;
using namespace std;

HighLevelILFunction::HighLevelILFunction(Architecture* arch, Function* func)
{
	m_object = BNCreateHighLevelILFunction(arch->GetObject(), func ? func->GetObject() : nullptr);
}

HighLevelILFunction::HighLevelILFunction(BNHighLevelILFunction* func)
{
	m_object = func;
}

Ref<Function> HighLevelILFunction::GetFunction() const
{
	BNFunction* func = BNGetHighLevelILOwnerFunction(m_object);
	if (!func)
		return nullptr;
	return new Function(func);
}

Ref<Architecture> HighLevelILFunction::GetArchitecture() const
{
	Ref<Function> func = GetFunction();
	if (!func)
		return nullptr;
	return func->GetArchitecture();
}

uint64_t HighLevelILFunction::GetCurrentAddress() const
{
	return BNHighLevelILGetCurrentAddress(m_object);
}

void HighLevelILFunction::SetCurrentAddress(Architecture* arch, uint64_t addr)
{
	BNHighLevelILSetCurrentAddress(m_object, arch ? arch->GetObject() : nullptr, addr);
}

HighLevelILInstruction HighLevelILFunction::GetRootExpr()
{
	return GetExpr(BNGetHighLevelILRootExpr(m_object));
}

void HighLevelILFunction::SetRootExpr(ExprId expr)
{
	BNSetHighLevelILRootExpr(m_object, expr);
}

void HighLevelILFunction::SetRootExpr(const HighLevelILInstruction& expr)
{
	BNSetHighLevelILRootExpr(m_object, expr.exprIndex);
}

ExprId HighLevelILFunction::AddExpr(
    BNHighLevelILOperation operation, size_t size, ExprId a, ExprId b, ExprId c, ExprId d, ExprId e)
{
	return BNHighLevelILAddExpr(m_object, operation, size, a, b, c, d, e);
}

ExprId HighLevelILFunction::AddExprWithLocation(BNHighLevelILOperation operation, uint64_t addr, uint32_t sourceOperand,
    size_t size, ExprId a, ExprId b, ExprId c, ExprId d, ExprId e)
{
	return BNHighLevelILAddExprWithLocation(m_object, operation, addr, sourceOperand, size, a, b, c, d, e);
}

ExprId HighLevelILFunction::AddExprWithLocation(BNHighLevelILOperation operation, const ILSourceLocation& loc,
    size_t size, ExprId a, ExprId b, ExprId c, ExprId d, ExprId e)
{
	if (loc.valid)
	{
		return BNHighLevelILAddExprWithLocation(
		    m_object, operation, loc.address, loc.sourceOperand, size, a, b, c, d, e);
	}
	return BNHighLevelILAddExpr(m_object, operation, size, a, b, c, d, e);
}

vector<uint64_t> HighLevelILFunction::GetOperandList(ExprId expr, size_t listOperand)
{
	size_t count;
	uint64_t* operands = BNHighLevelILGetOperandList(m_object, expr, listOperand, &count);
	vector<uint64_t> result;
	result.reserve(count);
	for (size_t i = 0; i < count; i++)
		result.push_back(operands[i]);
	BNMediumLevelILFreeOperandList(operands);
	return result;
}

ExprId HighLevelILFunction::AddOperandList(const vector<ExprId>& operands)
{
	uint64_t* operandList = new uint64_t[operands.size()];
	for (size_t i = 0; i < operands.size(); i++)
		operandList[i] = operands[i];
	ExprId result = (ExprId)BNHighLevelILAddOperandList(m_object, operandList, operands.size());
	delete[] operandList;
	return result;
}

ExprId HighLevelILFunction::AddIndexList(const vector<size_t>& operands)
{
	uint64_t* operandList = new uint64_t[operands.size()];
	for (size_t i = 0; i < operands.size(); i++)
		operandList[i] = operands[i];
	ExprId result = (ExprId)BNHighLevelILAddOperandList(m_object, operandList, operands.size());
	delete[] operandList;
	return result;
}

ExprId HighLevelILFunction::AddSSAVariableList(const vector<SSAVariable>& vars)
{
	uint64_t* operandList = new uint64_t[vars.size() * 2];
	for (size_t i = 0; i < vars.size(); i++)
	{
		operandList[i * 2] = vars[i].var.ToIdentifier();
		operandList[(i * 2) + 1] = vars[i].version;
	}
	ExprId result = (ExprId)BNHighLevelILAddOperandList(m_object, operandList, vars.size() * 2);
	delete[] operandList;
	return result;
}

BNHighLevelILInstruction HighLevelILFunction::GetRawExpr(size_t i) const
{
	return BNGetHighLevelILByIndex(m_object, i, true);
}

BNHighLevelILInstruction HighLevelILFunction::GetRawNonASTExpr(size_t i) const
{
	return BNGetHighLevelILByIndex(m_object, i, false);
}

HighLevelILInstruction HighLevelILFunction::operator[](size_t i)
{
	return GetInstruction(i);
}

HighLevelILInstruction HighLevelILFunction::GetInstruction(size_t i)
{
	size_t expr = GetIndexForInstruction(i);
	return HighLevelILInstruction(this, GetRawNonASTExpr(expr), expr, false, i);
}

HighLevelILInstruction HighLevelILFunction::GetExpr(size_t i, bool asFullAst)
{
	if (asFullAst)
		return HighLevelILInstruction(this, GetRawExpr(i), i, true, GetInstructionForExpr(i));
	return HighLevelILInstruction(this, GetRawNonASTExpr(i), i, false, GetInstructionForExpr(i));
}

size_t HighLevelILFunction::GetIndexForInstruction(size_t i) const
{
	return BNGetHighLevelILIndexForInstruction(m_object, i);
}

size_t HighLevelILFunction::GetInstructionForExpr(size_t expr) const
{
	return BNGetHighLevelILInstructionForExpr(m_object, expr);
}

size_t HighLevelILFunction::GetInstructionCount() const
{
	return BNGetHighLevelILInstructionCount(m_object);
}

size_t HighLevelILFunction::GetExprCount() const
{
	return BNGetHighLevelILExprCount(m_object);
}

vector<Ref<BasicBlock>> HighLevelILFunction::GetBasicBlocks() const
{
	size_t count;
	BNBasicBlock** blocks = BNGetHighLevelILBasicBlockList(m_object, &count);

	vector<Ref<BasicBlock>> result;
	result.reserve(count);
	for (size_t i = 0; i < count; i++)
		result.push_back(new BasicBlock(BNNewBasicBlockReference(blocks[i])));

	BNFreeBasicBlockList(blocks, count);
	return result;
}

Ref<BasicBlock> HighLevelILFunction::GetBasicBlockForInstruction(size_t i) const
{
	BNBasicBlock* block = BNGetHighLevelILBasicBlockForInstruction(m_object, i);
	if (!block)
		return nullptr;
	return new BasicBlock(block);
}

Ref<HighLevelILFunction> HighLevelILFunction::GetSSAForm() const
{
	BNHighLevelILFunction* func = BNGetHighLevelILSSAForm(m_object);
	if (!func)
		return nullptr;
	return new HighLevelILFunction(func);
}

Ref<HighLevelILFunction> HighLevelILFunction::GetNonSSAForm() const
{
	BNHighLevelILFunction* func = BNGetHighLevelILNonSSAForm(m_object);
	if (!func)
		return nullptr;
	return new HighLevelILFunction(func);
}

size_t HighLevelILFunction::GetSSAInstructionIndex(size_t instr) const
{
	return BNGetHighLevelILSSAInstructionIndex(m_object, instr);
}

size_t HighLevelILFunction::GetNonSSAInstructionIndex(size_t instr) const
{
	return BNGetHighLevelILNonSSAInstructionIndex(m_object, instr);
}

size_t HighLevelILFunction::GetSSAExprIndex(size_t expr) const
{
	return BNGetHighLevelILSSAExprIndex(m_object, expr);
}

size_t HighLevelILFunction::GetNonSSAExprIndex(size_t expr) const
{
	return BNGetHighLevelILNonSSAExprIndex(m_object, expr);
}

size_t HighLevelILFunction::GetSSAVarDefinition(const SSAVariable& var) const
{
	return BNGetHighLevelILSSAVarDefinition(m_object, &var.var, var.version);
}

size_t HighLevelILFunction::GetSSAMemoryDefinition(size_t version) const
{
	return BNGetHighLevelILSSAMemoryDefinition(m_object, version);
}

set<size_t> HighLevelILFunction::GetSSAVarUses(const SSAVariable& var) const
{
	size_t count;
	size_t* instrs = BNGetHighLevelILSSAVarUses(m_object, &var.var, var.version, &count);

	set<size_t> result;
	for (size_t i = 0; i < count; i++)
		result.insert(instrs[i]);

	BNFreeILInstructionList(instrs);
	return result;
}

set<size_t> HighLevelILFunction::GetSSAMemoryUses(size_t version) const
{
	size_t count;
	size_t* instrs = BNGetHighLevelILSSAMemoryUses(m_object, version, &count);

	set<size_t> result;
	for (size_t i = 0; i < count; i++)
		result.insert(instrs[i]);

	BNFreeILInstructionList(instrs);
	return result;
}

bool HighLevelILFunction::IsSSAVarLive(const SSAVariable& var) const
{
	return BNIsHighLevelILSSAVarLive(m_object, &var.var, var.version);
}

bool HighLevelILFunction::IsSSAVarLiveAt(const SSAVariable& var, const size_t instr) const
{
	return BNIsHighLevelILSSAVarLiveAt(m_object, &var.var, var.version, instr);
}

bool HighLevelILFunction::IsVarLiveAt(const Variable& var, const size_t instr) const
{
	return BNIsHighLevelILVarLiveAt(m_object, &var, instr);
}

set<size_t> HighLevelILFunction::GetVariableDefinitions(const Variable& var) const
{
	size_t count;
	size_t* instrs = BNGetHighLevelILVariableDefinitions(m_object, &var, &count);

	set<size_t> result;
	for (size_t i = 0; i < count; i++)
		result.insert(instrs[i]);

	BNFreeILInstructionList(instrs);
	return result;
}

set<size_t> HighLevelILFunction::GetVariableUses(const Variable& var) const
{
	size_t count;
	size_t* instrs = BNGetHighLevelILVariableUses(m_object, &var, &count);

	set<size_t> result;
	for (size_t i = 0; i < count; i++)
		result.insert(instrs[i]);

	BNFreeILInstructionList(instrs);
	return result;
}

size_t HighLevelILFunction::GetSSAVarVersionAtInstruction(const Variable& var, size_t instr) const
{
	return BNGetHighLevelILSSAVarVersionAtILInstruction(m_object, &var, instr);
}

size_t HighLevelILFunction::GetSSAMemoryVersionAtInstruction(size_t instr) const
{
	return BNGetHighLevelILSSAMemoryVersionAtILInstruction(m_object, instr);
}

Ref<MediumLevelILFunction> HighLevelILFunction::GetMediumLevelIL() const
{
	BNMediumLevelILFunction* result = BNGetMediumLevelILForHighLevelILFunction(m_object);
	if (!result)
		return nullptr;
	return new MediumLevelILFunction(result);
}

size_t HighLevelILFunction::GetMediumLevelILExprIndex(size_t expr) const
{
	return BNGetMediumLevelILExprIndexFromHighLevelIL(m_object, expr);
}

set<size_t> HighLevelILFunction::GetMediumLevelILExprIndexes(size_t expr) const
{
	size_t count;
	size_t* exprs = BNGetMediumLevelILExprIndexesFromHighLevelIL(m_object, expr, &count);

	set<size_t> result;
	for (size_t i = 0; i < count; i++)
		result.insert(exprs[i]);

	BNFreeILInstructionList(exprs);
	return result;
}

void HighLevelILFunction::UpdateInstructionOperand(size_t i, size_t operandIndex, ExprId value)
{
	BNUpdateHighLevelILOperand(m_object, i, operandIndex, value);
}

void HighLevelILFunction::ReplaceExpr(size_t expr, size_t newExpr)
{
	BNReplaceHighLevelILExpr(m_object, expr, newExpr);
}

void HighLevelILFunction::Finalize()
{
	BNFinalizeHighLevelILFunction(m_object);
}

void HighLevelILFunction::GenerateSSAForm(const set<Variable>& aliases)
{
	BNVariable* aliasList = new BNVariable[aliases.size()];

	size_t i = 0;
	for (auto& alias : aliases)
	{
		aliasList[i].type = alias.type;
		aliasList[i].index = alias.index;
		aliasList[i].storage = alias.storage;
		i++;
	}

	BNGenerateHighLevelILSSAForm(m_object, aliasList, aliases.size());

	delete[] aliasList;
}

vector<DisassemblyTextLine> HighLevelILFunction::GetExprText(ExprId expr, bool asFullAst, DisassemblySettings* settings)
{
	size_t count;
	BNDisassemblyTextLine* lines =
	    BNGetHighLevelILExprText(m_object, expr, asFullAst, &count, settings ? settings->GetObject() : nullptr);

	vector<DisassemblyTextLine> result;
	result.reserve(count);
	for (size_t i = 0; i < count; i++)
	{
		DisassemblyTextLine line;
		line.addr = lines[i].addr;
		line.instrIndex = lines[i].instrIndex;
		line.highlight = lines[i].highlight;
		line.tokens = InstructionTextToken::ConvertInstructionTextTokenList(lines[i].tokens, lines[i].count);
		line.tags = Tag::ConvertTagList(lines[i].tags, lines[i].tagCount);
		result.push_back(line);
	}

	BNFreeDisassemblyTextLines(lines, count);
	return result;
}

vector<DisassemblyTextLine> HighLevelILFunction::GetExprText(
    const HighLevelILInstruction& instr, bool asFullAst, DisassemblySettings* settings)
{
	return GetExprText(instr.exprIndex, asFullAst, settings);
}

vector<DisassemblyTextLine> HighLevelILFunction::GetInstructionText(
    size_t i, bool asFullAst, DisassemblySettings* settings)
{
	HighLevelILInstruction instr = GetInstruction(i);
	return GetExprText(instr, asFullAst, settings);
}

Confidence<Ref<Type>> HighLevelILFunction::GetExprType(size_t expr)
{
	BNTypeWithConfidence result = BNGetHighLevelILExprType(m_object, expr);
	if (!result.type)
		return nullptr;
	return Confidence<Ref<Type>>(new Type(BNNewTypeReference(result.type)), result.confidence);
}

Confidence<Ref<Type>> HighLevelILFunction::GetExprType(const HighLevelILInstruction& expr)
{
	return GetExprType(expr.exprIndex);
}

void HighLevelILFunction::SetExprType(size_t expr, const Confidence<Ref<Type>>& type)
{
	BNTypeWithConfidence tc;
	tc.type = type->GetObject();
	tc.confidence = type.GetConfidence();
	BNSetHighLevelILExprType(m_object, expr, &tc);
}

void HighLevelILFunction::SetExprType(const BinaryNinja::HighLevelILInstruction& expr,
										const Confidence<Ref<BinaryNinja::Type>>& type)
{
	SetExprType(expr.exprIndex, type);
}

void HighLevelILFunction::VisitAllExprs(const function<bool(const HighLevelILInstruction& expr)>& func)
{
	GetRootExpr().VisitExprs([&](const HighLevelILInstruction& expr) { return func(expr); });
}

Ref<FlowGraph> HighLevelILFunction::CreateFunctionGraph(DisassemblySettings* settings)
{
	BNFlowGraph* graph = BNCreateHighLevelILFunctionGraph(m_object, settings ? settings->GetObject() : nullptr);
	return new CoreFlowGraph(graph);
}

size_t HighLevelILFunction::GetExprIndexForLabel(uint64_t label)
{
	return BNGetHighLevelILExprIndexForLabel(m_object, label);
}

set<size_t> HighLevelILFunction::GetUsesForLabel(uint64_t label)
{
	size_t count;
	size_t* uses = BNGetHighLevelILUsesForLabel(m_object, label, &count);

	set<size_t> result;
	for (size_t i = 0; i < count; i++)
		result.insert(uses[i]);

	BNFreeILInstructionList(uses);
	return result;
}


text:
// Copyright (C) 2011 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package gerrit;

import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.LabelValue;
import com.google.gerrit.rules.StoredValues;

import com.googlecode.prolog_cafe.lang.IntegerTerm;
import com.googlecode.prolog_cafe.lang.ListTerm;
import com.googlecode.prolog_cafe.lang.Operation;
import com.googlecode.prolog_cafe.lang.Predicate;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.PrologException;
import com.googlecode.prolog_cafe.lang.StructureTerm;
import com.googlecode.prolog_cafe.lang.SymbolTerm;
import com.googlecode.prolog_cafe.lang.Term;

import java.util.List;

/**
 * Obtain a list of label types from the server configuration.
 *

 * Unifies to a Prolog list of: {@code label_type(Label, Fun, Min, Max)}
 * where:
 *

 *
{@code Label} - the newer style label name

 *
{@code Fun} - legacy function name

 *
{@code Min, Max} - the smallest and largest configured values.

 *

 */
class PRED_get_legacy_label_types_1 extends Predicate.P1 {
  private static final SymbolTerm NONE = SymbolTerm.intern("none");

  PRED_get_legacy_label_types_1(Term a1, Operation n) {
    arg1 = a1;
    cont = n;
  }

  @Override
  public Operation exec(Prolog engine) throws PrologException {
    engine.setB0();
    Term a1 = arg1.dereference();
    List<LabelType> list =
        StoredValues.CHANGE_CONTROL.get(engine).getLabelTypes().getLabelTypes();
    Term head = Prolog.Nil;
    for (int idx = list.size() - 1; 0 <= idx; idx--) {
      head = new ListTerm(export(list.get(idx)), head);
    }

    if (!a1.unify(head, engine.trail)) {
      return engine.fail();
    }
    return cont;
  }

  static final SymbolTerm symLabelType = SymbolTerm.intern(
      "label_type", 4);

  static Term export(LabelType type) {
    LabelValue min = type.getMin();
    LabelValue max = type.getMax();
    return new StructureTerm(symLabelType,
        SymbolTerm.intern(type.getName()),
        SymbolTerm.intern(type.getFunctionName()),
        min != null ? new IntegerTerm(min.getValue()) : NONE,
        max != null ? new IntegerTerm(max.getValue()) : NONE);
  }
}