text:
[![Build Status](https://travis-ci.org/adleroliveira/dreamjs.svg?branch=master)](https://travis-ci.org/adleroliveira/dreamjs)

# [![Dream Logo](https://d3bw40wmlrvrtr.cloudfront.net/dreamjs.png)](https://github.com/adleroliveira/dreamjs)

#### A lightweight json data generator.

This library can output random data from a Json Schema using standard types like String, Number, Date, Boolean, Array,
or with the 60+ built-in custom types like Name, Age, Address, Word, Sentence, paragraph, gender, (RGB) color etc.

The built-in Custom Types are mostly provided by the module [Chance][Chance] but the library also allows you to create
your own Custom Types.

It can be used with multiple Schemas that can be selected before usage and the it is also chainable, meaning that you
can chain several configurations before finally output the processed json.

## Installation

```js
npm install --save dreamjs
```

## Usage

### Hello World

```js
var dream = require('dreamjs');

var helloworld = dream.output();
```

The variable helloworld now contains:
```js
{ Dream: 'Hello World' }
```

### Callbacks

Currently there is two ways you can get the output from DreamJS. By storing it in a variable or by passing a callback
to it to receive the result. In the future it will also be possible to use it with Promises and Streams.

Storing in a variable:
```js
var helloword = dream.output();
```

Passing a callback:
```js
dream.output(function (err, result) {
  console.log(result);
});
```

### Generic Schema / Named Schema

The simplest way to use DreamJS is by defining a generic schema.
If any other generic Schema is created after that it will replace the previous one.

```js
var data = dream
  .schema({
    name: String
  })
  .output();
```

The variable data now contains:
```js
{ name: '' }
```

It is also possible to create named Schemas and use them when necessary.

```js
dream.schema('User', {
  name: String,
  age: Number
});

dream.schema('Location', {
  address: String,
  postcode: Number
});

var data = dream
  .useSchema('Location')
  .output();
```

The variable data now contains:
```js
{ address: '', postcode: 0 }
```

### Generate() and GenerateRnd()

The methods `Generate()` and `GenerateRnd()` will generate a given amount of instances of the selected Schema
respecting the data types specified on the Schema.
The method `Generate()` will bring empty values and the method `GenerateRnd()` will bring values with random data.

```js
dream.schema('User', {
  name: String
});

var data1 = dream
  .useSchema('User')
  .generate(3)
  .output();

var data2 = dream
  .useSchema('User')
  .generateRnd(3)
  .output();
```

The variable **data1** and **data2** now contains:
```js
// data1
[ { name: '' }, { name: '' }, { name: '' } ]

// data2
[ { name: 'Jlxokrs' }, { name: 'oHiklkss' }, { name: 'mNeiOlsaa' } ]
```

### Custom Types

DreamJS comes with the power of the [Chance][Chance] library integrated with it and allow you to use their 60+ random
generator as built-in Custom Types.
It is also possible to create your own Custom Types or just just pass a function or a RegularExpression statement to
use a generic Custom Type.

A full list of all the possible built-in Custom Types provided by chance can be found on their website: http://chancejs.com

```js

dream.customType('pi', function () {
  return Math.PI;
});

dream.customType('hello', /hello+ (world|to you)/);

dream
  .schema({
    name: 'name',
    age: 'age',
    address: 'address',
    contact: {
      phone: 'phone',
      servicePhone: /^(800[1-9]{6})$/
    },
    foo: function () {
      return 'bar';
    },
    pi: 'pi',
    hello: 'hello'
  })
  .generateRnd(2)
  .output(function (err, result) {
    console.log(result);
  });
```

Result:
```js
[
  {
    name: 'Dorothy Conner',
    age: 32,
    address: '702 Kimes Extension',
    contact: {
      phone: '(985) 255-2142',
      servicePhone: '800493159'
    },
    foo: 'bar',
    pi: 3.141592653589793,
    hello: 'hellooooooooooo world'
  },
  {
    name: 'Nathaniel Payne',
    age: 50,
    address: '1811 Bani Manor',
    contact: {
      phone: '(212) 389-6644',
      servicePhone: '800157977'
    },
    foo: 'bar',
    pi: 3.141592653589793,
    hello: 'hellooooooooooooooooooooooo to you'
  }
]
```

## Dream Helper

Whenever you build your own Custom Type, DreamJS provides to your Custom Type callback a helper object that contains
some useful tools like:

### Chance Instance

An instance of the library chance, that allows you to make full use of their methods with custom configuration.

```js
dream.customType('FiveWordsSentence', function (helper) {
  return helper.chance.sentence({words: 5});
});

dream
  .schema({
    phrase: 'FiveWordsSentence'
  })
  .generateRnd(2)
  .output(function (err, result) {
    console.log(result);
  });
```

Result:
```js
[
  { phrase: 'Laf woelimev vu vazpazap upecu.' },
  { phrase: 'Batunwa ziti laralsuc ve rudeoze.' }
]
```

### Input

It is possible to define an input to the DreamJS data flow, that will be available through the helper so you can use
this data to interact with your Custom Type.

```js
dream.customType('customTypeWithInput', function (helper) {
  return helper.input.value;
});

dream
  .input({value: 'Provided by an input'})
  .schema({
    result: 'customTypeWithInput'
  })
  .generateRnd()
  .output(function (err, result) {
    console.log(result);
  });
```

Result:
```js
{ result: 'Provided by an input' }
```

### oneOf()

A method that allows you to pick a single random value from a provided array. This way you can explicitly specify the
scope of what is being returned from your Custom Type.

```js
dream.customType('iceCreamTruckDay', function (helper) {
  var businessDays = ['Monday', 'Wednesday', 'Friday'];
  return helper.oneOf(businessDays);
});

dream
  .schema({
    iceCreamDay: 'iceCreamTruckDay'
  })
  .generateRnd(2)
  .output(function (err, result) {
    console.log(result);
  });
```

Result:
```js
[
  { iceCreamDay: 'Wednesday' },
  { iceCreamDay: 'Friday' }
]
```

### Previous Item

The helper also exposes the previous generated item to the current one. This way, you will always have access to previous generated values if you need them to generate the next ones, like for example an incremental id.

```js
dream.schema('User', {
	id: 'incrementalId',
	name: 'name',
	age: 'age'
});

dream.customType('incrementalId', function(helper){
	return helper.previousItem ? helper.previousItem.id+1 : 1;
});

dream
	.useSchema('User')
	.generateRnd(5)
	.output(function(err, result){
		console.log(result);
	});
```

Result:
```js
[
  { id: 1, name: 'Bess Franklin', age: 60 },
  { id: 2, name: 'Verna Brown', age: 45 },
  { id: 3, name: 'Travis Poole', age: 42 },
  { id: 4, name: 'Theresa Sanchez', age: 29 },
  { id: 5, name: 'Ruth Lane', age: 33 }
]
```

## From CLI
Dreamjs can be used from CLI generating data from a `schema.js` in the current directory

### Install globally
```
sudo npm install -g dreamjs
```
now you can call

```
dream <schema_name> <repetitions> -f
```

### usage
- recommended have `NODE_PATH` set so you can include global modules
- dreamjs can take 3 parameter in any order
	- schema name
	- repetitions
	- and `-f` flag to fill fields or generate empty fields
- Create a new `schema.js` file somewhere
	- define define your schemas and custome fields in this file

```javascript
// schema.js

// This will include the globally installed dreamjs which required NODE_PATH to be set
// or include from local install
var dream = require('dreamjs');

dream.customType('pi', function () {
  return Math.PI;
});

dream.customType('incrementalId', function(helper){
    return helper.previousItem ? helper.previousItem.id+1 : 1;
});

dream.schema('user', {
	id: 'incrementalId',
	name: 'name',
	age: 'age',
	piField: 'pi'
});
```

now in the same directoy as your schema.js

```
$ dream user 4 -f

[
    {
        "id": 1,
        "name": "Marie Lloyd",
        "age": 20
    },
    {
        "id": 2,
        "name": "Isabella Page",
        "age": 44
    },
    {
        "id": 3,
        "name": "Evan Barrett",
        "age": 21
    },
    {
        "id": 4,
        "name": "David Dawson",
        "age": 41
    }
]
```

without `-f` flag

```
$ dream user 4
[
    {
        "id": 0,
        "name": "",
        "age": 0
    },
    {
        "id": 0,
        "name": "",
        "age": 0
    },
    {
        "id": 0,
        "name": "",
        "age": 0
    },
    {
        "id": 0,
        "name": "",
        "age": 0
    }
]
```

## TODO

The next step is to update DreamJS to allow the use with promises and streams.

[Chance]: http://chancejs.com/


text:
<?xml version="1.0" encoding="UTF-8"?>
<!-- BSD 2-Clause License Copyright (c) 2016-2017, Jochen Seeber All rights reserved. Redistribution and use in source and
    binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions
    of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions
    in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
    FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
    USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -->
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module name="Checker">
    <property name="severity" value="warning"/>
    <property name="charset" value="UTF-8"/>
    <property name="fileExtensions" value="java, properties, xml"/>
    <module name="SuppressionFilter">
        <property name="file" value="${config_loc}/suppressions.xml"/>
        <property name="optional" value="true"/>
    </module>
    <module name="FileTabCharacter">
        <property name="severity" value="error"/>
        <property name="eachLine" value="true"/>
    </module>
    <module name="TreeWalker">
        <module name="LineLength">
            <property name="severity" value="warning"/>
            <property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://|@see"/>
            <property name="max" value="120"/>
        </module>
        <module name="JavadocMethod">
            <property name="severity" value="warning"/>
            <property name="allowMissingJavadoc" value="true"/>
            <property name="allowMissingParamTags" value="true"/>
            <property name="allowMissingPropertyJavadoc" value="true"/>
            <property name="allowMissingReturnTag" value="true"/>
            <property name="allowMissingThrowsTags" value="true"/>
            <property name="minLineCount" value="-1"/>
            <property name="suppressLoadErrors" value="false"/>
        </module>
    </module>
</module>

redpajama_set_name: RedPajamaGithub


text:
 - Upgrade dependencies : Mapbox GL JS 1.12.0, Angular 10, etc
 - Add Basque language #71

## ✨ Features
 - First iteration of opening_hours interface. It use a part of [YoHours](https://framagit.org/PanierAvide/YoHours) by Adrien Pavie (#63)
    - This first version only allows you to add simple "opening_hours" format (without specific days, weeks or holidays)

# 1.3.0
 - Fix #66 : Restaurant as self service laundry
 - Import tags from id
 - Update mapbox gl js : 1.12.0

# 1.2.0
 - Import tags from id 2.17
 - Update mapbox gl js : 1.10.0
 - #62 Fix butcher ( kosher, halal)

# 1.1.1
## Bug Fixes
 - Js target ES5 for compatibility with < Android 7

# 1.1.0
## Bug Fixes
 - #61 Sprites x1 or x2

## Translation
 - en & de : @m-rey
 - cs : @kudlav

# 1.0.0
## Tags & presets
 - Refactoring Tags & Presets configuration
    - Configuration by tags (not only  by primary key /  value).
        - amenity=fast_food => Fast food
        - amenity=fast_food & cuisine=pizza => Fast food Pizza
    - One files for all language
    - Tags & presets can be filter by country code
 - Import tags & presets from iD
 - Import deprecated presets from ID
 - Import "brand" from name-suggestion-index/
 - Import languages translation from iD ! ( tags & presets)
 - Add keys : aerialway, playground, attraction, barrier, power, telecom, etc..
 - Import descriptions from TagInfo

## ✨ Features
 - You can save and restore fields
 - You can fix deprecated presets automatically (with a button)
 - Deprecated items are now highlighted on the map
 - Ability to hide / show some tags on the in a dedicated menu
 - You can choose between "check_date" and "survey_date" in settings menu

## Deleting Features
 - Deleting the live update mode
 - OsmGo-Admin has its [own repository](https://github.com/DoFabien/OsmGo-admin)

## 🍏 Improvements
 - Ionic 5 & Angular 9
 - Adding some unit test
 - Mapbox gl js 1.7.0
 - Icons are now stored in a sprite ( no SVG)

## UI
 - Select multi features components
 - If the name is undefined but the ref attribute is present, the latter will be displayed on the map
 - The 20 last tags used are saved and display in a list. If you want to choose another preset, you must type 3 letters in the searchbar
 - Add icon and color on the information sheet

# 0.12.0
## Features
 - osmgo.com ( translation interface : admin.osmgo.com )
 - Add Capacitor instead of Cordova
 - Osm Go! PWA is now fully operational ( tested on Chrome and Android 9)
 - Osm Go has its own .osm converter! (./scripts/osmToOsmgo)
 - Data converter and all heavy calculation that run entirely in the background (in a webworker)
 - Osm Go now uses OAuth to log in on web and PWA ( it still use basic authentification on Android app)
 - We can activate the "developer mode" and switch to the OSM dev server
   - To activate it, go to About page & tap 5 times on version card.  Now you can switch to the osm dev server in settings

## Tags
 - Changing the structure of tags configuration
   - deleting "lbl_alt"
   - adding "terms", "description", "warning"
 - Add tags club=*
 - Add tags translation from iD

## Bug Fixes
  - It's now forbidden to move a node belonging to a way
  - It's now possible to delete a node belonging to a way .. not the node itself, the tags only !
  - missing  translation (#37)

# 0.11.0
## Miscellaneous
    - Back to cordova (capacitor is buggy and we can't build an APK without Firebase, GMS, etc...)
    - PWA improvement ( cache with serviceworker, icon, etc...)
    - Download data : OverpassApi is too slow... => Api06 as default

## Interface
    - Display the geolocation status if denied
    - Display an icon on map on old objects (4 y by default) and objects with "fixme" tag (you can disable & configure this)

# 0.10.0
## Miscellaneous
    - Migrating from Cordova to Capacitor
    - There is now only one sprite (instead of one sprite per country). This image is generated from the fr-FR configuration.
    If an icon is missing, the application will dynamically generate it
    - The list of base maps now depends on the configuartion of the countries (basemap.json)
    - Upgrade Mapbox Gl js 1.3.0
    - Swipe left on the menu => close
    - First tests with PWA : https://osmgo.dogeo.fr

# 0.9.4
## Fix
    - Translation (#21, #22)
    - Add source=survey to the changeset (instead of the object) (#23)

## Miscellaneous
    - Add link to this Github repository to About page (#24)
    - Upgrade Mapbox Gl js 1.2.0

# 0.9.2
## Fix
    - Le token d'API Mapbox a changé ... (?)

# 0.9.1
## Fix
    - Il n'est plus possible d'envoyer 2 fois un même changeset... Cela pouvait créer des doublons !

# 0.9.0
## Interface
    - i18n : English version as default language !

## Divers
    - OsmGoAdmin permet de traduire l'interface et de créer des configurations des tags & presets selon les langues/pays

# 0.8.0
## Divers
    * Ajout et corrections de tags
    * Par défaut, à la création ou à la modification d'un objet, une source "survey" est ajouté.
        - Si il n'y a aucune "source" : source = survey
        - Si il y a une source mais qu'il n'y a pas le mot "survey", : source : survey; {l'ancienne source}
    * L'ajout de la source peut être désactivé dans les paramètres
    * Suppression de dépendances et de fichiers qui n'étaient plus utilisés ou facilement remplaçable par plus simple (leaflet extra marker, etc.)
    * La dépendance "sharp" a été remplacé par "svg2img", plus rapide et compatible Windows (pour la génération des sprites )
    * mapbox.mapbox-streets-v7.json est désormais en local...

### Fix
    * # 15 [Affichage de la carte](https://github.com/DoFabien/OsmGo/issues/15) devrait être fixé pour toutes les plateformes
    * Pour les tags non connus, le nom et et la clé principale apparaissait ce qui créait un doublon d'affichage
    * Un objet qui n'a pas été modifié ne peut plus être envoyé à OSM

### Osm Go Admin
Introduction d'Osm Go tag qui est un outil d'aide a la création et a la modifications des tags et presets. Il est au stade embryonnaire mais peut déjà être utile. Il est sous forme d'une application web avec une partie frontend (angular) et backend (express).
A terme, il pourra être utilisé pour faciliter la collaboration,  les traductions et éventuellement pouvoir personaliser ses popres tags par utilisateur.
Un script permet de creer les statistiques d'utilisations des tags à partir d'un PBF ( actuelement sur le France).
Plus de docs bientôt...

# 0.7.3
## Divers
    * Mapbox Gl js 0.54.0

### Fix
    * # 15 [Affichage de la carte](https://github.com/DoFabien/OsmGo/issues/15)

# 0.7.2
### Fix
    * Les "clés" peuvent contenir des majuscules ... (ex : ref:FR_FINESS)

## Interface
    *  Affichage de la dernière modification depuis maintenant. Ex : Modifié il y a 4 mois

# 0.7.0
## Divers
    * Migration de Ionic 3 à Ionic 4
    * Mapbox Gl js 0.53.0

## Interface
    * Modification de quelques CSS
    * Un utilisateur non connecté peut désormais suivre ses modifications et les supprimer (il ne peut bien sûr pas les envoyer)
    * Retour haptique lors d'un clique sur un objet (avant l'ouverture de la fiche)
    * Le commentaire du dernier changeset est enregistré et proposé par défaut pour le suivant

# 0.6.0
### Fix
    * Fiche : affichage de l'utilisateur après l'envoi d'une modification
    * Fiche : le bouton survey:date devient un bouton classique avec une alerte de confirmation
    * Le markers sans tag connu pouvaient ne pas apparaître

## Interface
    * Ajout et harmonisation des icons
    * Lors d'un clic sur plusieur objet, on devra choisir le quel on veut séléctionner

## Config
    * Un tag peut être "obsolète", il n'apparaîtra pas dans la liste des tags
    * Possibilité d'ajouter des valeurs par défaut pour la création d'un objet
    * Ajout de la key "highway"
    * Possibilité de ne pas prendre en compte certaines valeurs si l'objet est un "way"
    * Ajout de tags et de presets

## Divers
    * Utilisation d'un unique web worker pour traiter les données (style/ filtre / wayTopoint / merge )
    * Upgrade Mapbox GL JS 0.50.0
    * Le repértoire "platforms" est sorti du .gitignore ( => FDroid)

# 0.5.(1-2-3)
### Fix
    * Certains markers pouvaient de pas s'afficher ("none" à la place de "" )
    * La key "tag" était systématiquement écrasé

# 0.5.0
## Interface
    * Ajout de nombreux tags (dont la historic=*)

## Features
    * Possibilité de filtrer les objets linéaires et surfaciques supérieur à une certaine surface/longueur
    * Possibilité d'avoir des presets spécifiques sur une même key

## Divers
    * Simplification du code de la fiche
    * Mapbox Gl Js 0.49.0

# 0.4.0

## Interface
    * Utilisation des "select" (combobox) de Ionic
    * Ajout d'un tooltip à l'ouverture indiquant de télécharger les données en cliquant sur le bouton qui va bien
    * Le "toast" affichant le nombre d'objets déjà stocké à l'ouverturr s'affiche désormais en haut. La partie basse contient les 3 boutons les plus utiles, autant ne pas les cacher.
    * La barre de statut n'est plus cacher.
    * Le symbole représentant la position de l'utilisateur à changé de forme et de type. Il est de type ["marker"](https://www.mapbox.com/mapbox-gl-js/api/#marker), son changement d'état n'engendre pas le rendu de toute la carte, le CPU et la batterie apprécient.
    * Si l'orientation n'est pas disponible le symbole devient un point.
    * Le cercle indiquant la précision de la localisation est maintenant de type ["circle"](https://www.mapbox.com/mapbox-gl-js/style-spec#layers-circle). C'est plus joli et moins couteux en ressource.

## Features
    * Il est possible d'accéder à la carte sans géolocalisation. Soit en refusant l'accès, soit en cliquant sur le bouton qui permet de forcer l'accès à la carte
    * Il est possible, depuis la fiche de consultation, d'ajouter un tag "survey:date" à la date du jour. Pour cela il suffit de presser longuement le bouton vert en bas à droite
    * Il est possible de choisir l'imagerie aerienne de Mapbox dans les paramètres. Celle ci remplace celle de l'IGN qui est plus précise mais ne couvrant que la France

## Fix
    * Lors du téléchargement des données à travers l'overpassapi, ce dernier peut envoyer un timout avec un code 200. Il y'a donc maintenant une verification du contenu (balise "remark")
    * La création d'une nouvelle clé pouvait poser des problèmes à cause du "toLowercase" à chaque frappe
    * Lorsque le menu, la fiche ou une autre page sont ouverts, le rendu de la carte est désactivé, sinon, ceci pouvait provoquer de gros ralentissements (seulement depuis la version 0.42 de mapbox, étrange..)

## Divers
    * On ne peut télécharger des données qu'a partir du zoom 14, c'est déjà énorme et pas forcement conseillé...
    * Il n'est plus possible d'incliner la carte à 60° (pitch). Ce n'était vraiment pas d'une grande utilité et ça engendrait pas mal de contraintes liées à la perspective.
    * Adaptation pour un usage web
    * Mapbox GL JS 0.42 => 0.47


text:
<?php

namespace Neoxygen\Neogen\Schema;

class GraphSchemaBuilder
{
    /**
     *
     */
    public function __construct()
    {

    }

    /**
     * Build a graph definition based on the user parsed schema
     *
     * @param  array                               $userSchema
     * @return \Neoxygen\Neogen\Schema\GraphSchema
     */
    public function buildGraph(array $userSchema)
    {
        $graphSchema = new GraphSchema();
        foreach ($userSchema['nodes'] as $id => $nodeInfo) {
            $node = $this->buildNode($id, $nodeInfo);
            $graphSchema->addNode($node);
        }
        if (!isset($userSchema['relationships'])) {
            $userSchema['relationships'] = [];
        }
        foreach ($userSchema['relationships'] as $rel) {
            $relationship = $this->buildRelationship($rel);
            $graphSchema->addRelationship($relationship);
        }

        return $graphSchema;
    }

    /**
     * @param  string $identifier
     * @param  array  $nodeInfo
     * @return Node
     */
    public function buildNode($identifier, array $nodeInfo)
    {
        $node = new Node($identifier);
        $node->setAmount($nodeInfo['count']);
        if (is_string($nodeInfo['labels'])) {
            $node->addLabel($nodeInfo['labels']);
        } elseif (is_array($nodeInfo['labels'])) {
            $node->addLabels($nodeInfo['labels']);
        }
        if (!is_array($nodeInfo['properties'])){
            $nodeInfo['properties'] = [];
        }
        foreach ($nodeInfo['properties'] as $key => $info) {
            $property = $this->buildNodeProperty($key, $info);
            $node->addProperty($property);
        }

        return $node;
    }

    /**
     * @param  string       $name
     * @param  string|array $info
     * @return NodeProperty
     */
    public function buildNodeProperty($name, $info)
    {
        $property = new NodeProperty($name);
        if (is_array($info)) {
            $property->setProvider($info['type'], $info['params']);
        } else {
            $property->setProvider($info);
        }

        return $property;
    }

    /**
     * Builds the relationship object based on user schema
     *
     * @param  array        $relInfo relationship info from user schema
     * @return Relationship
     */
    public function buildRelationship(array $relInfo)
    {
        $relationship = new Relationship($relInfo['start'], $relInfo['end'], $relInfo['type']);
        $relationship->setCardinality($relInfo['mode']);
        if (isset($relInfo['properties'])) {
            foreach ($relInfo['properties'] as $name => $info) {
                $property = $this->buildRelationshipProperty($name, $info);
                $relationship->addProperty($property);
            }
        }

        return $relationship;
    }

    /**
     * @param  string               $name
     * @param  string|array         $info
     * @return RelationshipProperty
     */
    public function buildRelationshipProperty($name, $info)
    {
        if (0 === strpos($name, '!')) {
            $name = substr($name, 1, strlen($name)-1);
            $unique = true;
        } else {
            $unique = false;
        }
        $property = new RelationshipProperty($name);
        if (is_array($info)) {
            $property->setProvider($info['type'], $info['params']);
        } else {
            $property->setProvider($info);
        }

        if ($unique) {
            $property->setUnique();
        }

        return $property;
    }
}


text:
|travis| |coveralls| |downloads| |latest-release| |python-versions|

``mitmproxy`` is an interactive, SSL-capable man-in-the-middle proxy for HTTP
with a console interface.

``mitmdump`` is the command-line version of mitmproxy. Think tcpdump for HTTP.

``libmproxy`` is the library that mitmproxy and mitmdump are built on.

Documentation & Help
--------------------

Documentation, tutorials and distribution packages can be found on the
mitmproxy website.

|site|

Installation Instructions are available in the docs.

|docs|

You can join our developer chat on Slack.

|slack|

Features
--------

- Intercept HTTP requests and responses and modify them on the fly.
- Save complete HTTP conversations for later replay and analysis.
- Replay the client-side of an HTTP conversations.
- Replay HTTP responses of a previously recorded server.
- Reverse proxy mode to forward traffic to a specified server.
- Transparent proxy mode on OSX and Linux.
- Make scripted changes to HTTP traffic using Python.
- SSL certificates for interception are generated on the fly.
- And much, much more.

``mitmproxy`` is tested and developed on OSX, Linux and OpenBSD.
On Windows, only mitmdump is supported, which does not have a graphical user interface.

Hacking
-------

To get started hacking on mitmproxy, make sure you have Python_ 2.7.x. with
virtualenv_ installed (you can find installation instructions for virtualenv here_).
Then do the following:

.. code-block:: text

    git clone https://github.com/mitmproxy/mitmproxy.git
    git clone https://github.com/mitmproxy/netlib.git
    git clone https://github.com/mitmproxy/pathod.git
    cd mitmproxy
    source ./dev

The *dev* script will create a virtualenv environment in a directory called
"venv.mitmproxy", and install all of mitmproxy's development requirements, plus
all optional modules. The primary mitmproxy components - mitmproxy, netlib and
pathod - are all installed "editable", so any changes to the source in the git
checkouts will be reflected live in the virtualenv.

To confirm that you're up and running, activate the virtualenv, and run the
mitmproxy test suite:

.. code-block:: text

    . ../venv.mitmproxy/bin/activate # ..\venv.mitmproxy\Scripts\activate.bat on Windows
    nosetests ./test

Note that the main executables for the project - ``mitmdump``, ``mitmproxy`` and
``mitmweb`` - are all created within the virtualenv. After activating the
virtualenv, they will be on your $PATH, and you can run them like any other
command:

.. code-block:: text

    mitmdump --version

For convenience, the project includes an autoenv_ file (`.env`_) that
auto-activates the virtualenv when you cd into the mitmproxy directory.

Testing
-------

If you've followed the procedure above, you already have all the development
requirements installed, and you can simply run the test suite:

.. code-block:: text

    nosetests --with-cov --cov-report term-missing

Please ensure that all patches are accompanied by matching changes in the test
suite. The project maintains 100% test coverage.

Docs
----

The mitmproxy documentation is build using Sphinx_, which is installed automatically if you set up a development
environment as described above.
After installation, you can render the documentation like this:

.. code-block:: text

    cd docs
    make clean
    make html
    make livehtml

The last command invokes `sphinx-autobuild`_, which watches the Sphinx directory and rebuilds
the documentation when a change is detected.

.. |site| image:: https://img.shields.io/badge/https%3A%2F%2F-mitmproxy.org-blue.svg
    :target: https://mitmproxy.org/
    :alt: mitmproxy.org

.. |docs| image:: https://readthedocs.org/projects/mitmproxy/badge/
    :target: http://docs.mitmproxy.org/en/latest/
    :alt: Documentation

.. |slack| image:: http://slack.mitmproxy.org/badge.svg
    :target: http://slack.mitmproxy.org/
    :alt: Slack Developer Chat

.. |travis| image:: https://img.shields.io/travis/mitmproxy/mitmproxy/master.svg
    :target: https://travis-ci.org/mitmproxy/mitmproxy
    :alt: Build Status

.. |coveralls| image:: https://img.shields.io/coveralls/mitmproxy/mitmproxy/master.svg
    :target: https://coveralls.io/r/mitmproxy/mitmproxy
    :alt: Coverage Status

.. |downloads| image:: https://img.shields.io/pypi/dm/mitmproxy.svg?color=orange
    :target: https://pypi.python.org/pypi/mitmproxy
    :alt: Downloads

.. |latest-release| image:: https://img.shields.io/pypi/v/mitmproxy.svg
    :target: https://pypi.python.org/pypi/mitmproxy
    :alt: Latest Version

.. |python-versions| image:: https://img.shields.io/pypi/pyversions/mitmproxy.svg
    :target: https://pypi.python.org/pypi/mitmproxy
    :alt: Supported Python versions

.. _Python: https://www.python.org/
.. _virtualenv: https://virtualenv.pypa.io/en/latest/
.. _here: https://virtualenv.pypa.io/en/latest/installation.html
.. _autoenv: https://github.com/kennethreitz/autoenv
.. _.env: https://github.com/mitmproxy/mitmproxy/blob/master/.env
.. _Sphinx: http://sphinx-doc.org/
.. _sphinx-autobuild: https://pypi.python.org/pypi/sphinx-autobuild


text:
.. graph_help.rst

.. This is a port of the original SasView html help file to ReSTructured text
.. by S King, ISIS, during SasView CodeCamp-III in Feb 2015.

Plotting Data/Models
====================

SasView generates three different types of graph window: one that displays *1D data*
(i.e., $I(Q)$ vs $Q$), one that displays *1D residuals* (ie, the difference between the
experimental data and the theory at the same $Q$ values), and *2D color maps*.

Graph window options
--------------------

.. _Invoking_the_graph_menu:

Invoking the graph menu
^^^^^^^^^^^^^^^^^^^^^^^

To invoke the *Graph Menu* simply right-click on a data/theory plot, or click
the *Graph Menu* (bullet list) icon in the toolbar at the bottom of the plot.
Then select a menu item.

How to Hide-Show-Delete a graph
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

To expand a plot window, click the *Maximise* (square) icon in the top-right
corner.

To shrink a plot window, click the *Restore down* (square-on-square) icon in
the top-right corner.

To hide a plot, click the *Minimise* (-) icon in the top-right corner of the
plot window.

To show a hidden plot, select the *Restore up* (square-on-square) icon on the
minimised window.

To delete a plot, click the *Close* (x) icon in the top-right corner of the
plot window.

.. note::
    *If a residuals graph (when fitting data) is hidden, it will not show up
    after computation.*

Dragging a plot
^^^^^^^^^^^^^^^

Select the *Pan* (crossed arrows) icon in the toolbar at the bottom of the plot
to activate this option. Move the mouse pointer to the plot. It will change to
a hand. Then left-click and drag the plot around. The axis values will adjust
accordingly.

To disable dragging mode, unselect the *crossed arrows* icon on the toolbar.

Zooming In-Out on a plot
^^^^^^^^^^^^^^^^^^^^^^^^

Select the *Zoom* (magnifying glass) button in the toolbar at the bottom of
the plot to activate this option. Move the mouse pointer to the plot. It will
change to a cross-hair. Then left-click and drag the pointer around to generate
a region of interest. Release the mouse button to generate the new view.

To disable zoom mode, unselect the *Zoom* button on the toolbar.

After zooming in on a a region, the *left arrow* or *right arrow* buttons on
the toolbar will switch between recent views.

The axis range can also be specified manually.  To do so go to the *Graph Menu*
(see Invoking_the_graph_menu_ for further details), choose the *Set Graph Range*
option and enter the limits in the pop box.

*NOTE! If a wheel mouse is available scrolling the wheel will zoom in/out
on the current plot (changing both axes). Alternatively, point at the numbers
on one axis and scroll the wheel to zoom in/out on just that axis.*

To return to the original view of the data, click the the *Reset* (home) icon
in the toolbar at the bottom of the plot (see Resetting_the_graph_ for further details).

Saving a plot image
^^^^^^^^^^^^^^^^^^^

To save the current plot as an image file, right click on the plot to bring up
the *Graph Menu* (see Invoking_the_graph_menu_) and select *Save Image*.
Alternatively, click on the *Save* (floppy disk) icon in the toolbar at the
bottom of the plot.

A dialog window will open. Select a folder, enter a filename, choose an output
image type, and click *Save*.

The currently supported image types are:

*  EPS (encapsulated postscript)
*  EMF (enhanced metafile)
*  JPG/JPEG (joint photographics experts group)
*  PDF (portable documant format)
*  PNG (portable network graphics)
*  PS (postscript)
*  RAW/RGBA (bitmap, stored as 935x635 pixels of depth 8)
*  SVG/SVGA (scalable vector graphics)
*  TIF/TIFF (tagged iamge file)

Printing a plot
^^^^^^^^^^^^^^^

To send the current plot to a printer, click on the *Print* (printer) icon in
the toolbar at the bottom of the plot.

.. _Resetting_the_graph:

Resetting the graph
^^^^^^^^^^^^^^^^^^^

To reset the axis range of a graph to its initial values select *Reset Graph
Range* on the *Graph Menu* (see Invoking_the_graph_menu_). Alternatively, use
the *Reset* (home) icon in the toolbar at the bottom of the plot.

Modifying the graph
^^^^^^^^^^^^^^^^^^^

It is possible to make custom modifications to plots including:

*  changing the plot window title
*  changing the default legend location and toggling it on/off
*  changing the axis label text
*  changing the axis label units
*  changing the axis label font & font colour
*  adding/removing a text string
*  adding a grid overlay

The legend and text strings can be drag and dropped around the plot

These options are accessed through the *Graph Menu* (see Invoking_the_graph_menu_)
and selecting *Modify Graph Appearance* (for axis labels, grid overlay and
legend position) or *Add Text* to add textual annotations, selecting font, color,
style and size. *Remove Text* will remove the last annotation added. To change
the legend. *Window Title* allows a custom title to be entered instead of Graph
x.

Changing scales
^^^^^^^^^^^^^^^

This menu option is only available with 1D data.

From the *Graph Menu* (see Invoking_the_graph_menu_) select *Change Scale*. A
dialog window will appear in which it is possible to choose different
transformations of the x (usually Q) or y (usually I(Q)) axes, including:

*  x, x^2, x^4, ln(x), log10(x), log10(x^4)
*  y, 1/y, ln(y), y^2, y.(x^4), 1/sqrt(y),
*  log10(y), ln(y.x), ln(y.x^2), ln(y.x^4), log10(y.x^4)

A *View* option includes short-cuts to common SAS transformations, such as:

*  linear
*  Guinier
*  X-sectional Guinier
*  Porod
*  Kratky

For properly corrected and scaled data, these SAS transformations can be used
to estimate, for example, Rg, rod diameter, or SANS incoherent background
levels, via a linear fit (see Making_a_linear_fit_).

Toggling scales
^^^^^^^^^^^^^^^

This menu option is only available with 2D data.

From the *Graph Menu* (see Invoking_the_graph_menu_) select *Toggle Linear/Log
Scale* to switch between a linear to log intensity scale. The type of scale
selected is written alongside the colour scale.

2D color maps
^^^^^^^^^^^^^

This menu option is only available with 2D data.

From the *Graph Menu* (see Invoking_the_graph_menu_) select *2D Color Map* to
choose a different color scale for the image and/or change the maximum or
minimum limits of the scale.

Getting data coordinates
^^^^^^^^^^^^^^^^^^^^^^^^

Clicking anywhere in the plot window will cause the current coordinates to be
displayed in the status bar at the very bottom-left of the SasView window.

.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ

Dataset menu options
--------------------

.. _Invoking_the_dataset_menu:

Invoking the dataset menu
^^^^^^^^^^^^^^^^^^^^^^^^^

From the *Graph Menu* (see Invoking_the_graph_menu_) highlight a plotted
dataset.

Getting data info
^^^^^^^^^^^^^^^^^

In the *Dataset Menu* (see Invoking_the_dataset_menu_), highlight a data set
and select *DataInfo* to bring up a data information dialog panel for that
data set.

Saving data
^^^^^^^^^^^

In the *Dataset Menu* (see Invoking_the_dataset_menu_), select *Save Points as
a File* (if 1D data) or *Save as a file(DAT)* (if 2D data). A save dialog will
appear.

1D data can be saved in either ASCII text (.TXT) or CanSAS/SASXML (.XML)
formats (see :ref:`Formats`).

2D data can only be saved in the NIST 2D format (.DAT) (see :ref:`Formats`).

.. _Making_a_linear_fit:

Making a linear fit
^^^^^^^^^^^^^^^^^^^

Linear fit performs a simple $y(x)=ax+b$ linear fit within the plot window.

In the *Dataset Menu* (see Invoking_the_dataset_menu_), select *Linear Fit*. A
fitting dialog will appear. Set some initial parameters and data limits and
click *Fit*. The fitted parameter values are displayed and the resulting line
calculated from them is added to the plot.

This option is most useful for performing simple Guinier, XS Guinier, and
Porod type analyses, for example, to estimate $R_g$, a rod diameter, or incoherent
background level, respectively.

The following figure shows an example of a Guinier analysis using this option

image:: guinier_fit.png

Removing data from the plot
^^^^^^^^^^^^^^^^^^^^^^^^^^^

In the *Dataset Menu* (see Invoking_the_dataset_menu_), select *Remove*. The
selected data will be removed from the plot.

.. note::
    The Remove data set action cannot be undone.

Show-Hide error bars
^^^^^^^^^^^^^^^^^^^^

In the *Dataset Menu* (see Invoking_the_dataset_menu_), select *Show Error Bar*
or *Hide Error Bar* to switch between showing/hiding the errors associated
with the chosen dataset.

Modify plot properties
^^^^^^^^^^^^^^^^^^^^^^

In the *Dataset Menu* (see Invoking_the_dataset_menu_), select *Modify Plot
Property* to change the size, color, or shape of the displayed marker for the
chosen dataset, or to change the dataset label that appears in the plot legend
box.

.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ

2D data averaging
-----------------

Purpose
^^^^^^^

This feature is only available with 2D data.

2D data averaging allows you to perform different types of averages on your
data. The region to be averaged is displayed in the plot window and its limits
can be modified by dragging the boundaries around.

How to average
^^^^^^^^^^^^^^

In the *Dataset Menu* (see Invoking_the_dataset_menu_), select one of the
following averages

*  Perform Circular Average
*  Sector [Q view]
*  Annulus [Phi view]
*  Box sum
*  Box averaging in Qx
*  Box averaging on Qy

A 'slicer' will appear (except for *Perform Circular Average*) in the plot that
you can drag by clicking on a slicer's handle. When the handle is highlighted
in red, it means that the slicer can move/change size.

*NOTE! The slicer size will reset if you try to select a region greater than
the size of the data.*

Alternatively, you can also select the region to
average by bringing back the *Dataset Menu* and selecting *Edit Slicer
Parameters*. A dialog window will appear in which you can enter values to
define a region or select the number of points to plot (*nbins*).

A separate plot window will also have appeared, displaying the requested
average.

.. note::
    The displayed average only updates when input focus is moved back to
    that window; ie, when the mouse pointer is moved onto that plot.

Selecting *Box Sum* automatically brings up the 'Slicer Parameters' dialog in
order to display the average numerically, rather than graphically.

A slicer can be applied to any or all existing 2D data plots using the *Edit Slicer
Parameters* window. Batch slicing options are available in the right pane *Batch Slicing*.
Select the 2D plots you want to apply the slicer to. Current 2D plot is selected by default.
The resulting 1D data for all slicers can be saved as a text file and then sent to fitting by selecting the Auto save generated 1D check box.
Sending data to the fitting perspective requires the data be saved.

Once the auto save check box is selected, you can select where the files are saved.
The file name for the saved data is the slicer name plus the file name of the original data set,
plus what is in the Append to file name field. The default value in the append to field includes the names and values for all of the slicer parameters.

The batch of slices can be sent to fitting if desired, with three options available.
The first is to not fit the data, the second is to send the slices to individual fit pages,
and the third is to send all sliced data to a single batch fit window.

Clicking *Apply* will create a slicer for each selected plot with the parameters entered in the 'Slicer Parameters' window of the 'Slicer' tab.
Depending on the options selected the data may then be saved, loaded as separate data sets in the data manager panel, and finally sent to fitting.

To remove a 'slicer', bring back the *Dataset menu* and select *Clear Slicer*. Alternatively, you can select *None* in the 'Slicer type' dropdown
list in the 'Slicer Parameters' dialog.

Unmasked circular average
^^^^^^^^^^^^^^^^^^^^^^^^^

This operation will perform an average in constant $Q$ rings around the (x,y)
pixel location of the beam center.

Masked circular average
^^^^^^^^^^^^^^^^^^^^^^^

This operation is the same as 'Unmasked Circular Average' except that any
masked region is excluded.

Sector average [Q View]
^^^^^^^^^^^^^^^^^^^^^^^

This operation averages in constant $Q$ arcs.

The width of the sector is specified in degrees ($\pm\delta|\phi|$) each side
of the central angle $\phi$.

Annular average [:math:`\phi`]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This operation performs an average between two $Q$ values centered on (0,0),
and averaged over a specified number of pixels.

The data is returned as a function of angle $\phi$ in degrees with zero
degrees at the 3 O'clock position.

Box sum
^^^^^^^

This operation performs a sum of counts in a 2D region of interest.

When editing the slicer parameters, the user can enter the length and the width
the rectangular slicer and the coordinates of the center of the rectangle.

Box Averaging in Qx
^^^^^^^^^^^^^^^^^^^

This operation computes an average $I(Q_x)$ for the region of interest.

When editing the slicer parameters, the user can control the length and the
width the rectangular slicer. The averaged output is calculated from constant
bins with rectangular shape. The resultant $Q$ values are nominal values, that
is, the central value of each bin on the x-axis.

Box Averaging in Qy
^^^^^^^^^^^^^^^^^^^

This operation computes an average $I(Q_y)$ for the region of interest.

When editing the slicer parameters, the user can control the length and the
width the rectangular slicer. The averaged output is calculated from constant
bins with rectangular shape. The resultant $Q$ values are nominal values, that
is, the central value of each bin on the x-axis.

.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ

.. note::  This help document was last modified by Paul Butler, 05 September, 2016


text:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace ContactSample.Models.viewModel
{
    public class ContactMessageToGrid
    {
        public int Id { get; set; }
        public DateTime CreationDate { get; set; }

        [JsonConverter(typeof(StringEnumConverter))]
        public BusinessAreaEnum BusinessArea { get; set; }
        [JsonConverter(typeof(StringEnumConverter))]
        public MessageTypeEnum MessageType { get; set; }

        public string Username { get; set; }

    }
}


text:
---
description: A detailed look at the various REST actions supported by the Audit Logs resource of the Losant API. Learn more.
---

# Audit Logs Actions

https://api.losant.com/orgs/**`ORG_ID`**/audit-logs

Below are the various requests that can be performed against the
Audit Logs resource, as well as the expected
parameters and the potential responses.

## Get

Returns the audit logs for the organization

### Method And Url

GET https://api.losant.com/orgs/**`ORG_ID`**/audit-logs

### Authentication

A valid api access token is required to access this endpoint. The token must
include at least one of the following scopes:
all.Organization, all.Organization.read, all.User, all.User.read, auditLogs.*, or auditLogs.get.

### Request Path Components

| Path Component | Description | Example |
| -------------- | ----------- | ------- |
| ORG_ID | ID associated with the organization | 575ed6e87ae143cd83dc4aa8 |

### Request Query Parameters

| Name | Required | Description | Default | Example |
| ---- | -------- | ----------- | ------- | ------- |
| sortField | N | Field to sort the results by. Accepted values are: creationDate, responseStatus, actorName | creationDate | sortField=creationDate |
| sortDirection | N | Direction to sort the results by. Accepted values are: asc, desc | desc | sortDirection=asc |
| page | N | Which page of results to return | 0 | page=0 |
| perPage | N | How many items to return per page | 1000 | perPage=10 |
| start | N | Start of time range for audit log query |  | start=1465790400000 |
| end | N | End of time range for audit log query |  | end=1465790400000 |
| auditLogFilter | N | Filters for the audit log query. See [Audit Log Filter](schemas.md#audit-log-filter) for more details. |  | auditLogFilter[primaryTarget][0][type]=Dashboard&auditLogFilter[primaryTarget][1][type]=Application&auditLogFilter[primaryTarget][1][id]=575ec8687ae143cd83dc4a97&auditLogFilter[actor][0][type]=User&auditLogFilter[actor][0][id]=575ed70c7ae143cd83dc4aa9 |

### Request Headers

| Name | Required | Description | Default |
| ---- | -------- | ----------- | ------- |
| Authorization | Y | The token for authenticating the request, prepended with Bearer | |

### Curl Example

```bash
curl -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -H 'Authorization: Bearer YOUR_API_ACCESS_TOKEN' \
    -X GET \
    https://api.losant.com/orgs/ORG_ID/audit-logs
```

### Successful Responses

| Code | Type | Description |
| ---- | ---- | ----------- |
| 200 | [Audit Logs](schemas.md#audit-logs) | Collection of audit logs |

### Error Responses

| Code | Type | Description |
| ---- | ---- | ----------- |
| 400 | [Error](schemas.md#error) | Error if malformed request |
| 404 | [Error](schemas.md#error) | Error if organization was not found |


text:
module FixtureHelpers
  def fixture_file(file_name)
    File.read("./spec/fixtures/#{file_name}.xml").strip.gsub(/"/, "'")
  end
end


text:
package ru.otus.kirillov.myorm.commands.select;

import org.apache.commons.lang3.tuple.Pair;
import ru.otus.kirillov.model.DataSet;
import ru.otus.kirillov.myorm.commands.AbstractCommand;
import ru.otus.kirillov.myorm.commands.CommandInvoker;
import ru.otus.kirillov.myorm.commands.generatesql.GenerateSQLRequest;
import ru.otus.kirillov.myorm.executors.SelectExecutor;
import ru.otus.kirillov.myorm.schema.elements.AbstractFieldDescriptor;
import ru.otus.kirillov.myorm.schema.elements.EntityDescriptor;
import ru.otus.kirillov.myorm.schema.elements.FieldDescriptors.OneToOneFieldDescriptor;
import ru.otus.kirillov.myorm.schema.elements.FieldDescriptors.OneToManyFieldDescriptor;
import ru.otus.kirillov.utils.ReflectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Алгоритм:
 * 1. Генерируем запрос (без учета OneToMany)
 * 2. Исполняем его - на выходе мапа
 * 3. Обрабатываем OneToOne:
 * 3.1. Селектим объект из связанной таблицы, по id - полученному из синтетического поля для OneToOne
 * 3.2. Удаляем из мапы полей данные о данном синтетическом поле
 * 3.3. Заносим в мапу объект, полученный из результата
 * 4. Обрабатываем OneToMany:
 * 4.1. Со своим id селектим синтетическое поле из сущности, на которое ссылаемся
 * 4.2. Заносим его в мапу, по соответствующему полю
 * 5. Из мапы формируем результирующий объект
 * 5* - уточнение, необходимо обрабатывать коллекции особым образом! - хотя бы самым примитивным
 * (только для Collection, Set и List)
 * Created by Александр on 30.01.2018.
 */
public class SelectCommand extends AbstractCommand<SelectRequest, List<? extends DataSet>> {

    public SelectCommand(CommandInvoker invoker) {
        super(invoker);
    }

    @Override
    public List<? extends DataSet> execute(SelectRequest request) {
        //1. Генерируем запрос (без учета OneToMany)
        GenerateSQLRequest generatedRequest = createGenerateRequest(request);
        //2. Исполняем его - на выходе мапа
        String query = createQuery(generatedRequest);
        List<Map<AbstractFieldDescriptor, Object>> selectionResults =
                new SelectExecutor(getConnection()).execute(query,
                        request.getEntityDescriptor().getFieldDescriptors(f -> f.isSQLVisibleFields()),
                        request.getWhereClojure()
                );

        List<DataSet> result = new ArrayList<>();

        for (Map<AbstractFieldDescriptor, Object> resultObjectFields : selectionResults) {
            //3. Обрабатываем OneToOne:
            processOneToOneRefs(resultObjectFields, request.getEntityDescriptor());
            //4. Обрабатываем OneToMany:
            processOneToManyRefs(resultObjectFields, request.getEntityDescriptor());
            //5. Мапа сформирована, можно из нее создавать результирующий объект
            result.add(buildResultObject(request.getEntityDescriptor(), resultObjectFields));
        }

        return result;
    }

    private String createQuery(GenerateSQLRequest request) {
        return getInvoker().invoke(request);
    }

    private GenerateSQLRequest createGenerateRequest(SelectRequest request) {
        return GenerateSQLRequest.selectRequest(
                request.getEntityDescriptor(),
                request.getWhereClojure().stream()
                        .map(Pair::getKey)
                        .collect(Collectors.toList())
        );
    }

    private void processOneToOneRefs(Map<AbstractFieldDescriptor, Object> selectionResult,
                                     EntityDescriptor descriptor) {
        descriptor.getOneToOneFields()
                .forEach(f -> {
                    Object refIdValue = selectionResult.get(f.getRefIdFieldDescriptor());
                    DataSet result = null;

                    if(refIdValue != null) {
                        //3.1. Селектим объект из связанной таблицы, по id - полученному из синтетического поля для OneToOne
                        result = getOneToOneRefObject(f, refIdValue);
                    }
                    //3.2. Удаляем из мапы полей данные о данном синтетическом поле
                    selectionResult.remove(f.getRefIdFieldDescriptor());
                    //3.3. Заносим в мапу объект, полученный из результата
                    selectionResult.put(f, result);
                });
    }

    private DataSet getOneToOneRefObject(OneToOneFieldDescriptor oneToOneField, Object refIdVal) {
        EntityDescriptor refEntityDescriptor = oneToOneField.getEntityDescriptor();
        List<? extends DataSet> result = getInvoker().invoke(new SelectRequest(refEntityDescriptor,
                Collections.singletonList(
                        Pair.of(refEntityDescriptor.getGeneratedIdField(), refIdVal)
                )));
        return result.get(0);
    }

    private void processOneToManyRefs(Map<AbstractFieldDescriptor, Object> selectionResult,
                                      EntityDescriptor descriptor) {
        Object entityId = selectionResult.get(descriptor.getGeneratedIdField());
        descriptor.getOneToManyFields()
                .forEach(f -> {
                    //4.1. Со своим id селектим синтетическое поле из сущности, на которое ссылаемся
                    List<? extends DataSet> result = getOneToManyRefs(f, entityId);
                    //4.2. Заносим его в мапу, по соответствующему полю
                    selectionResult.put(f, result);
                });
    }

    private List<? extends DataSet> getOneToManyRefs(OneToManyFieldDescriptor oneToManyField, Object entityId) {
        List<? extends DataSet> result = getInvoker().invoke(new SelectRequest(oneToManyField.getEntityDescriptor(),
                Collections.singletonList(
                        Pair.of(oneToManyField.getBackRefIdFieldDescriptor(), entityId)
                )));
        return result;
    }

    private DataSet buildResultObject(EntityDescriptor descriptor, Map<AbstractFieldDescriptor, Object> fieldValues) {
        boolean syntheticFieldPresent = fieldValues.keySet().stream()
                .filter(f -> f.isSyntheticField())
                .findAny().isPresent();

        //Если после всез обработок остались синтетические поля - очевидно, что это back-reference
        if(syntheticFieldPresent) {
            System.out.println(String.format("In result map\n(%s)\nretains synthetic field", fieldValues));
            fieldValues = fieldValues.entrySet().stream()
                    .filter(e -> !e.getKey().isSyntheticField())
                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        }

        DataSet result = ReflectionUtils.instantiate(descriptor.getEntityClass());
        fieldValues.forEach(
                (k, v) -> {
                    if (Collections.class.isAssignableFrom(k.getJavaField().getType())) {
                        ReflectionUtils.setFieldCollectionValue(result, k.getJavaField(), (Collection) v);
                    } else {
                        ReflectionUtils.setFieldValue(result, k.getJavaField(), v);
                    }
                }
        );

        return result;
    }
}


text:
package org.apache.axis2.transport.sms;

import org.apache.axis2.description.Parameter;
import org.apache.axis2.description.TransportInDescription;
import org.apache.axis2.description.TransportOutDescription;
import org.apache.axis2.description.ParameterInclude;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.transport.sms.smpp.SMPPImplManager;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.engine.AxisEngine;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.ArrayList;

/**
 * SMS manager will manage all SMS implementation managers
 * and it will dispatch the Message to the Axis2 Engine
 */
public class SMSManager {

    private SMSImplManager currentImplimentation;
    private boolean inited;
    private ConfigurationContext configurationContext;
    private SMSMessageBuilder messageBuilder;
    private SMSMessageFormatter messageFormatter;
    private String phoneNumber = null;
    private boolean invertSourceAndDestination = true;

     /** the reference to the actual commons logger to be used for log messages */
    protected Log log = LogFactory.getLog(this.getClass());

    /**
     * initialize the SMS manager with TransportinDiscription
     * if Manager is already inited it will only set the TransportInDiscription
     * in the current Implimentation manager
     * @param transportInDescription
     * @param configurationContext
     * @throws AxisFault
     */
    public void init(TransportInDescription transportInDescription ,ConfigurationContext  configurationContext) throws
            AxisFault {
        if (!inited) {
            basicInit(transportInDescription , configurationContext);
        }

        Parameter builderClass = transportInDescription.getParameter(SMSTransportConstents.BUILDER_CLASS);

        if(builderClass == null) {
            messageBuilder = new DefaultSMSMessageBuilderImpl();
        } else {
            try {
                messageBuilder = (SMSMessageBuilder)Class.forName((String)builderClass.getValue()).newInstance();

            } catch (Exception e) {
               throw new AxisFault("Error while instentiating class " + builderClass.getValue() , e );
            }
        }
        currentImplimentation.setTransportInDetails(transportInDescription);
           // get the Axis phone number form the configuration file
        Parameter phoneNum = transportInDescription.getParameter(SMSTransportConstents.PHONE_NUMBER);
        if(phoneNum != null) {
            this.phoneNumber = (String)phoneNum.getValue();
        }
        inited = true;
    }

    /**
     * Initialize the SMS Maneger with TransportOutDiscription
     * if the Maneger is already inited  it will set the Transport Outdetails
     * in the Current Implimentation Manage
     * @param transportOutDescription
     * @param configurationContext
     */
    public void init(TransportOutDescription transportOutDescription , ConfigurationContext configurationContext) throws
            AxisFault {
        if(!inited) {
            basicInit(transportOutDescription , configurationContext);
        }

        Parameter formatterClass = transportOutDescription.getParameter(SMSTransportConstents.FORMATTER_CLASS);

        if(formatterClass == null) {
            messageFormatter = new DefaultSMSMessageFormatterImpl();
        }else {
            try {
                messageFormatter = (SMSMessageFormatter)Class.forName((String)formatterClass.getValue()).newInstance();
            } catch (Exception e) {
                throw new AxisFault("Error while instentiating the Class: " +formatterClass.getValue() ,e);
            }
        }
        currentImplimentation.setTransportOutDetails(transportOutDescription);

        Parameter invertS_n_D = transportOutDescription.getParameter(
                SMSTransportConstents.INVERT_SOURCE_AND_DESTINATION);
        if(invertS_n_D != null) {
            String val = (String)invertS_n_D.getValue();
            if("false".equals(val)) {
                invertSourceAndDestination = false;
            } else if("true".equals(val)) {
                invertSourceAndDestination = true;
            } else {
                log.warn("Invalid parameter value set to the parameter invert_source_and_destination," +
                        "setting the default value :true ");
                invertSourceAndDestination = true;
            }
        }
        inited = true;
    }

    private void basicInit(ParameterInclude transportDescription, ConfigurationContext configurationContext) throws
            AxisFault {
        this.configurationContext = configurationContext;
        Parameter p = transportDescription.getParameter(SMSTransportConstents.IMPLIMENTAION_CLASS);

        if (p == null) {
            currentImplimentation = new SMPPImplManager();
        } else {
            String implClass = (String) p.getValue();

            try {

                currentImplimentation = (SMSImplManager) Class.forName(implClass).newInstance();
            } catch (Exception e) {
                throw new AxisFault("Error while instentiating class " + implClass, e);
            }
        }
        currentImplimentation.setSMSInManager(this);

    }
    /**
     * Dispatch the SMS message to Axis2 Engine
     * @param sms
     */
    public void dispatchToAxis2(SMSMessage sms)  {
        try {
            MessageContext msgctx = messageBuilder.buildMessaage(sms,configurationContext);
            msgctx.setReplyTo(new EndpointReference("sms://"+sms.getSender()+"/"));
            AxisEngine.receive(msgctx);
        } catch (InvalidMessageFormatException e) {
            log.debug("Invalid message format " + e);

        } catch (AxisFault axisFault) {
            log.debug(axisFault);
        } catch (Throwable e) {
            log.debug("Unknown Exception " , e);
        }

    }

    /**
     * send a SMS form the message comming form the Axis2 Engine
     * @param messageContext that is comming form the Axis2
     */
    public void sendSMS(MessageContext messageContext) {
        try {
            SMSMessage sms = messageFormatter.formatSMS(messageContext);
            sms.addProperty(SMSTransportConstents.INVERT_SOURCE_AND_DESTINATION ,"" + invertSourceAndDestination);
            currentImplimentation.sendSMS(sms);
        } catch (Exception e) {
            log.error("Error while sending the SMS " , e);
        }

    }

    /**
     * send the information SMS messages other than messages comming form the Axis2 Engine
     * @param sms
     */
    public void sentInfo(SMSMessage sms) {
        currentImplimentation.sendSMS(sms);
    }

    public SMSImplManager getCurrentImplimentation() {
        return currentImplimentation;
    }

    public void setCurrentImplimentation(SMSImplManager currentImplimentation) {
        this.currentImplimentation = currentImplimentation;
    }

    public void start() {
        currentImplimentation.start();
    }

    public void stop() {
        currentImplimentation.stop();
    }

    public boolean isInited() {
        return inited;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public boolean isInvertSourceAndDestination() {
        return invertSourceAndDestination;
    }

    public void setInvertSourceAndDestination(boolean invertSourceAndDestination) {
        this.invertSourceAndDestination = invertSourceAndDestination;
    }
}


text:
package org.apache.commons.dbutils.handlers.properties;

import org.apache.commons.dbutils.PropertyHandler;

import java.sql.Timestamp;
import java.util.Date;

/**
 * {@link PropertyHandler} for date fields. Will convert {@link java.sql.Date}, {@link java.sql.Time}, and
 * {@link java.sql.Timestamp} from SQL types to java types.
 */
public class DatePropertyHandler implements PropertyHandler {
    @Override
    public boolean match(final Class<?> parameter, final Object value) {
        if (value instanceof Date) {
            final String targetType = parameter.getName();
            if ("java.sql.Date".equals(targetType)) {
                return true;
            }
            if ("java.sql.Time".equals(targetType)) {
                return true;
            }
            if ("java.sql.Timestamp".equals(targetType)
                    && !Timestamp.class.isInstance(value)) {
                return true;
            }
        }

        return false;
    }

    @Override
    public Object apply(final Class<?> parameter, Object value) {
        final String targetType = parameter.getName();
        final Date dateValue = (Date) value;
        final long time = dateValue.getTime();

        if ("java.sql.Date".equals(targetType)) {
            value = new java.sql.Date(time);
        } else
        if ("java.sql.Time".equals(targetType)) {
            value = new java.sql.Time(time);
        } else
        if ("java.sql.Timestamp".equals(targetType)) {
            value = new Timestamp(time);
        }

        return value;
    }
}


text:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeGeneration;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.Utilities;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.ReplacePropertyWithMethods
{
    [ExportCodeRefactoringProvider(LanguageNames.CSharp, LanguageNames.VisualBasic,
       Name = PredefinedCodeRefactoringProviderNames.ReplacePropertyWithMethods), Shared]
    internal class ReplacePropertyWithMethodsCodeRefactoringProvider :
        CodeRefactoringProvider,
        IEqualityComparer<(IPropertySymbol property, ReferenceLocation location)>
    {
        private const string GetPrefix = "Get";
        private const string SetPrefix = "Set";

        [ImportingConstructor]
        [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")]
        public ReplacePropertyWithMethodsCodeRefactoringProvider()
        {
        }

        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var (document, _, cancellationToken) = context;
            var service = document.GetLanguageService<IReplacePropertyWithMethodsService>();
            if (service == null)
                return;

            var propertyDeclaration = await service.GetPropertyDeclarationAsync(context).ConfigureAwait(false);
            if (propertyDeclaration == null)
                return;

            var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            var propertySymbol = semanticModel.GetDeclaredSymbol(propertyDeclaration) as IPropertySymbol;

            Contract.ThrowIfNull(propertySymbol);
            var propertyName = propertySymbol.Name;

            var accessorCount =
                (propertySymbol.GetMethod == null ? 0 : 1) +
                (propertySymbol.SetMethod == null ? 0 : 1);

            var resourceString = accessorCount == 1
                ? FeaturesResources.Replace_0_with_method
                : FeaturesResources.Replace_0_with_methods;

            context.RegisterRefactoring(
                CodeAction.Create(
                    string.Format(resourceString, propertyName),
                    c => ReplacePropertyWithMethodsAsync(document, propertySymbol, context.Options, c),
                    propertyName),
                propertyDeclaration.Span);
        }

        private async Task<Solution> ReplacePropertyWithMethodsAsync(
           Document document,
           IPropertySymbol propertySymbol,
           CodeGenerationOptionsProvider fallbackOptions,
           CancellationToken cancellationToken)
        {
            var desiredMethodSuffix = NameGenerator.GenerateUniqueName(propertySymbol.Name,
                n => !HasAnyMatchingGetOrSetMethods(propertySymbol, n));

            var desiredGetMethodName = GetPrefix + desiredMethodSuffix;
            var desiredSetMethodName = SetPrefix + desiredMethodSuffix;

            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var originalSolution = document.Project.Solution;
            var propertyReferences = await SymbolFinder.FindReferencesAsync(propertySymbol, originalSolution, cancellationToken).ConfigureAwait(false);

            // Get the warnings we'd like to put at the definition site.
            var definitionWarning = GetDefinitionIssues(propertyReferences);
            var definitionToBackingField = CreateDefinitionToBackingFieldMap(propertyReferences);

            var q = from r in propertyReferences
                    where r.Definition is IPropertySymbol
                    from loc in r.Locations
                    select (property: (IPropertySymbol)r.Definition, location: loc);

            var referencesByDocument = q.ToLookup(t => t.location.Document);

            // References and definitions can overlap (for example, references to one property
            // inside the definition of another).  So we do a multi phase rewrite.  We first
            // rewrite all references to point at the new methods instead.  Then we remove all
            // the actual property definitions and replace them with the new methods.
            var updatedSolution = originalSolution;

            updatedSolution = await UpdateReferencesAsync(
                updatedSolution, referencesByDocument, definitionToBackingField,
                desiredGetMethodName, desiredSetMethodName, cancellationToken).ConfigureAwait(false);

            updatedSolution = await ReplaceDefinitionsWithMethodsAsync(
                originalSolution, updatedSolution, propertyReferences, definitionToBackingField,
                desiredGetMethodName, desiredSetMethodName, fallbackOptions, cancellationToken).ConfigureAwait(false);

            return updatedSolution;
        }

        private static ImmutableDictionary<IPropertySymbol, IFieldSymbol?> CreateDefinitionToBackingFieldMap(IEnumerable<ReferencedSymbol> propertyReferences)
        {
            var definitionToBackingField = ImmutableDictionary.CreateBuilder<IPropertySymbol, IFieldSymbol?>(SymbolEquivalenceComparer.Instance);

            foreach (var reference in propertyReferences)
            {
                if (reference.Definition is IPropertySymbol property)
                {
                    var backingField = GetBackingField(property);
                    definitionToBackingField[property] = backingField;
                }
            }

            return definitionToBackingField.ToImmutable();
        }

        private static bool HasAnyMatchingGetOrSetMethods(IPropertySymbol property, string name)
        {
            return HasAnyMatchingGetMethods(property, name) ||
                HasAnyMatchingSetMethods(property, name);
        }

        private static bool HasAnyMatchingGetMethods(IPropertySymbol property, string name)
        {
            return property.GetMethod != null &&
                   property.ContainingType.GetMembers(GetPrefix + name)
                                          .OfType<IMethodSymbol>()
                                          .Any(m => m.Parameters.Length == 0);
        }

        private static bool HasAnyMatchingSetMethods(IPropertySymbol property, string name)
        {
            var comparer = SymbolEquivalenceComparer.Instance.SignatureTypeEquivalenceComparer;
            return property.SetMethod != null &&
                   property.ContainingType
                          .GetMembers(SetPrefix + name)
                          .OfType<IMethodSymbol>()
                          .Any(m => m.Parameters.Length == 1 &&
                                    comparer.Equals(m.Parameters[0].Type, property.Type));
        }

        private static IFieldSymbol? GetBackingField(IPropertySymbol property)
        {
            var field = property.GetBackingFieldIfAny();
            if (field == null)
                return null;

            // If the field is something can be referenced with the name it has, then just use
            // it as the backing field we'll generate.  This is the case in VB where the backing
            // field can be referenced as is.
            if (field.CanBeReferencedByName)
                return field;

            // Otherwise, generate a good name for the backing field we're generating.  This is
            // the case for C# where we have mangled names for the backing field and need something
            // actually usable in code.
            var uniqueName = NameGenerator.GenerateUniqueName(
                property.Name.ToCamelCase(),
                n => !property.ContainingType.GetMembers(n).Any());

            return CodeGenerationSymbolFactory.CreateFieldSymbol(
                attributes: default,
                accessibility: field.DeclaredAccessibility,
                modifiers: DeclarationModifiers.From(field),
                type: field.Type,
                name: uniqueName);
        }

#pragma warning disable IDE0060 // Remove unused parameter - Method not completely implemented.
        private static string? GetDefinitionIssues(IEnumerable<ReferencedSymbol> getMethodReferences)
#pragma warning restore IDE0060 // Remove unused parameter
        {
            // TODO: add things to be concerned about here.  For example:
            // 1. If any of the referenced symbols are from metadata.
            // 2. If a symbol is referenced implicitly.
            // 3. if the property has attributes.
            return null;
        }

        private async Task<Solution> UpdateReferencesAsync(
            Solution updatedSolution,
            ILookup<Document, (IPropertySymbol property, ReferenceLocation location)> referencesByDocument,
            ImmutableDictionary<IPropertySymbol, IFieldSymbol?> propertyToBackingField,
            string desiredGetMethodName, string desiredSetMethodName,
            CancellationToken cancellationToken)
        {
            foreach (var group in referencesByDocument)
            {
                cancellationToken.ThrowIfCancellationRequested();

                updatedSolution = await UpdateReferencesInDocumentAsync(
                    updatedSolution, group.Key, group, propertyToBackingField,
                    desiredGetMethodName, desiredSetMethodName, cancellationToken).ConfigureAwait(false);
            }

            return updatedSolution;
        }

        private async Task<Solution> UpdateReferencesInDocumentAsync(
            Solution updatedSolution,
            Document originalDocument,
            IEnumerable<(IPropertySymbol property, ReferenceLocation location)> references,
            ImmutableDictionary<IPropertySymbol, IFieldSymbol?> propertyToBackingField,
            string desiredGetMethodName, string desiredSetMethodName,
            CancellationToken cancellationToken)
        {
            var root = await originalDocument.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var editor = new SyntaxEditor(root, originalDocument.Project.Solution.Workspace.Services);
            var service = originalDocument.GetRequiredLanguageService<IReplacePropertyWithMethodsService>();

            await ReplaceReferencesAsync(
                originalDocument, references, propertyToBackingField, root, editor, service,
                desiredGetMethodName, desiredSetMethodName, cancellationToken).ConfigureAwait(false);

            updatedSolution = updatedSolution.WithDocumentSyntaxRoot(originalDocument.Id, editor.GetChangedRoot());

            return updatedSolution;
        }

        private async Task ReplaceReferencesAsync(
            Document originalDocument,
            IEnumerable<(IPropertySymbol property, ReferenceLocation location)> references,
            IDictionary<IPropertySymbol, IFieldSymbol?> propertyToBackingField,
            SyntaxNode root, SyntaxEditor editor,
            IReplacePropertyWithMethodsService service,
            string desiredGetMethodName, string desiredSetMethodName,
            CancellationToken cancellationToken)
        {
            if (references != null)
            {
                var syntaxFacts = originalDocument.GetRequiredLanguageService<ISyntaxFactsService>();

                // We may hit a location multiple times due to how we do FAR for linked symbols, but each linked symbol
                // is allowed to report the entire set of references it think it is compatible with.  So ensure we're
                // hitting each location only once.
                //
                // Note Use DistinctBy (.Net6) once available.
                foreach (var (property, referenceLocation) in references.Distinct(this))
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var location = referenceLocation.Location;
                    var nameToken = root.FindToken(location.SourceSpan.Start, findInsideTrivia: true);

                    var parent = nameToken.Parent;
                    Contract.ThrowIfNull(parent);

                    if (referenceLocation.IsImplicit || !syntaxFacts.IsIdentifierName(parent))
                    {
                        // Warn the user that we can't properly replace this property with a method.
                        editor.ReplaceNode(parent, parent.WithAdditionalAnnotations(
                            ConflictAnnotation.Create(FeaturesResources.Property_referenced_implicitly)));
                    }
                    else if (syntaxFacts.IsMemberInitializerNamedAssignmentIdentifier(parent))
                    {
                        editor.ReplaceNode(parent, parent.WithAdditionalAnnotations(
                            ConflictAnnotation.Create(FeaturesResources.Property_reference_cannot_be_updated)));
                    }
                    else
                    {
                        var fieldSymbol = propertyToBackingField.GetValueOrDefault(property);
                        await service.ReplaceReferenceAsync(
                            originalDocument, editor, parent,
                            property, fieldSymbol,
                            desiredGetMethodName, desiredSetMethodName,
                            cancellationToken).ConfigureAwait(false);
                    }
                }
            }
        }

        private static async Task<Solution> ReplaceDefinitionsWithMethodsAsync(
            Solution originalSolution,
            Solution updatedSolution,
            IEnumerable<ReferencedSymbol> references,
            ImmutableDictionary<IPropertySymbol, IFieldSymbol?> definitionToBackingField,
            string desiredGetMethodName, string desiredSetMethodName,
            CodeGenerationOptionsProvider fallbackOptions,
            CancellationToken cancellationToken)
        {
            var definitionsByDocumentId = await GetDefinitionsByDocumentIdAsync(originalSolution, references, cancellationToken).ConfigureAwait(false);

            foreach (var (documentId, definitions) in definitionsByDocumentId)
            {
                cancellationToken.ThrowIfCancellationRequested();

                updatedSolution = await ReplaceDefinitionsWithMethodsAsync(
                    updatedSolution, documentId, definitions, definitionToBackingField,
                    desiredGetMethodName, desiredSetMethodName, fallbackOptions, cancellationToken).ConfigureAwait(false);
            }

            return updatedSolution;
        }

        private static async Task<MultiDictionary<DocumentId, IPropertySymbol>> GetDefinitionsByDocumentIdAsync(
           Solution originalSolution,
           IEnumerable<ReferencedSymbol> referencedSymbols,
           CancellationToken cancellationToken)
        {
            var result = new MultiDictionary<DocumentId, IPropertySymbol>();
            foreach (var referencedSymbol in referencedSymbols)
            {
                cancellationToken.ThrowIfCancellationRequested();

                var definition = referencedSymbol.Definition as IPropertySymbol;
                if (definition?.DeclaringSyntaxReferences.Length > 0)
                {
                    var syntax = await definition.DeclaringSyntaxReferences[0].GetSyntaxAsync(cancellationToken).ConfigureAwait(false);
                    if (syntax != null)
                    {
                        var document = originalSolution.GetDocument(syntax.SyntaxTree);
                        if (document != null)
                        {
                            result.Add(document.Id, definition);
                        }
                    }
                }
            }

            return result;
        }

        private static async Task<Solution> ReplaceDefinitionsWithMethodsAsync(
            Solution updatedSolution,
            DocumentId documentId,
            MultiDictionary<DocumentId, IPropertySymbol>.ValueSet originalDefinitions,
            IDictionary<IPropertySymbol, IFieldSymbol?> definitionToBackingField,
            string desiredGetMethodName, string desiredSetMethodName,
            CodeGenerationOptionsProvider fallbackOptions,
            CancellationToken cancellationToken)
        {
            var updatedDocument = updatedSolution.GetRequiredDocument(documentId);
            var semanticModel = await updatedDocument.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            // We've already gone and updated all references.  So now re-resolve all the definitions
            // in the current compilation to find their updated location.
            var currentDefinitions = await GetCurrentPropertiesAsync(
                updatedSolution, semanticModel.Compilation, documentId, originalDefinitions, cancellationToken).ConfigureAwait(false);

            var service = updatedDocument.GetRequiredLanguageService<IReplacePropertyWithMethodsService>();

            var root = await updatedDocument.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var editor = new SyntaxEditor(root, updatedSolution.Workspace.Services);

            // First replace all the properties with the appropriate getters/setters.
            foreach (var (property, declaration) in currentDefinitions)
            {
                cancellationToken.ThrowIfCancellationRequested();

                var members = await service.GetReplacementMembersAsync(
                    updatedDocument,
                    property, declaration,
                    definitionToBackingField.GetValueOrDefault(property),
                    desiredGetMethodName, desiredSetMethodName,
                    fallbackOptions,
                    cancellationToken).ConfigureAwait(false);

                // Properly make the members fit within an interface if that's what
                // we're generating into.
                if (property.ContainingType.TypeKind == TypeKind.Interface)
                {
                    members = members.Select(editor.Generator.AsInterfaceMember)
                                     .WhereNotNull()
                                     .ToImmutableArray();
                }

                var nodeToReplace = service.GetPropertyNodeToReplace(declaration);
                editor.InsertAfter(nodeToReplace, members);
                editor.RemoveNode(nodeToReplace);
            }

            return updatedSolution.WithDocumentSyntaxRoot(documentId, editor.GetChangedRoot());
        }

        private static async Task<ImmutableArray<(IPropertySymbol property, SyntaxNode declaration)>> GetCurrentPropertiesAsync(
            Solution updatedSolution,
            Compilation compilation,
            DocumentId documentId,
            MultiDictionary<DocumentId, IPropertySymbol>.ValueSet originalDefinitions,
            CancellationToken cancellationToken)
        {
            using var _ = ArrayBuilder<(IPropertySymbol property, SyntaxNode declaration)>.GetInstance(out var result);
            foreach (var originalDefinition in originalDefinitions)
            {
                cancellationToken.ThrowIfCancellationRequested();

                var property = GetSymbolInCurrentCompilation(compilation, originalDefinition, cancellationToken);
                var declaration = await GetPropertyDeclarationAsync(property, cancellationToken).ConfigureAwait(false);

                if (property != null && declaration != null && updatedSolution.GetDocument(declaration.SyntaxTree)?.Id == documentId)
                    result.Add((property, declaration));
            }

            return result.ToImmutable();
        }

        private static async Task<SyntaxNode?> GetPropertyDeclarationAsync(
            IPropertySymbol? property, CancellationToken cancellationToken)
        {
            if (property == null)
                return null;

            Debug.Assert(property.DeclaringSyntaxReferences.Length == 1);
            var reference = property.DeclaringSyntaxReferences[0];
            return await reference.GetSyntaxAsync(cancellationToken).ConfigureAwait(false);
        }

        private static TSymbol? GetSymbolInCurrentCompilation<TSymbol>(Compilation compilation, TSymbol originalDefinition, CancellationToken cancellationToken)
            where TSymbol : class, ISymbol
        {
            return originalDefinition.GetSymbolKey(cancellationToken).Resolve(compilation, cancellationToken: cancellationToken).GetAnySymbol() as TSymbol;
        }

        public bool Equals((IPropertySymbol property, ReferenceLocation location) x, (IPropertySymbol property, ReferenceLocation location) y)
        {
            Contract.ThrowIfFalse(x.location.Document == y.location.Document);
            return x.location.Location.SourceSpan == y.location.Location.SourceSpan;
        }

        public int GetHashCode((IPropertySymbol property, ReferenceLocation location) obj)
            => obj.location.Location.SourceSpan.GetHashCode();
    }
}


text:
#ifndef THREADOUTAUDIO_H_
#define THREADOUTAUDIO_H_

extern void * startThreadOutAudio(void * );

#endif /* THREADOUTAUDIO_H_ */


text:
__TIB_DEFINITION_java_lang_NullPointerException __TIB_java_lang_NullPointerException = {
    0, // classInitializationBegan
    0, // classInitialized
    -1, // initializerThreadId
    __INIT_java_lang_NullPointerException, // classInitializer
    "java.lang.NullPointerException", // className
    "java.lang", // package
    JAVA_NULL, // enclosingClassName
    JAVA_NULL, // enclosingMethodName
    JAVA_NULL, // signature
    (__TIB_DEFINITION_TEMPLATE*) &__TIB_java_lang_RuntimeException, // extends
    sizeof(java_lang_NullPointerException), // sizeInstance
    XMLVM_TYPE_CLASS};

JAVA_OBJECT __CLASS_java_lang_NullPointerException;
JAVA_OBJECT __CLASS_java_lang_NullPointerException_1ARRAY;
JAVA_OBJECT __CLASS_java_lang_NullPointerException_2ARRAY;
JAVA_OBJECT __CLASS_java_lang_NullPointerException_3ARRAY;
//XMLVM_BEGIN_IMPLEMENTATION
//XMLVM_END_IMPLEMENTATION

static JAVA_LONG _STATIC_java_lang_NullPointerException_serialVersionUID;

#include "xmlvm-reflection.h"

static XMLVM_FIELD_REFLECTION_DATA __field_reflection_data[] = {
};

static XMLVM_CONSTRUCTOR_REFLECTION_DATA __constructor_reflection_data[] = {
};

static JAVA_OBJECT constructor_dispatcher(JAVA_OBJECT constructor, JAVA_OBJECT arguments)
{
    XMLVM_NOT_IMPLEMENTED();
}

static XMLVM_METHOD_REFLECTION_DATA __method_reflection_data[] = {
};

static JAVA_OBJECT method_dispatcher(JAVA_OBJECT method, JAVA_OBJECT receiver, JAVA_OBJECT arguments)
{
    XMLVM_NOT_IMPLEMENTED();
}

void __INIT_java_lang_NullPointerException()
{
    staticInitializerLock(&__TIB_java_lang_NullPointerException);

    // While the static initializer mutex is locked, locally store the value of
    // whether class initialization began or not
    int initBegan = __TIB_java_lang_NullPointerException.classInitializationBegan;

    // Whether or not class initialization had already began, it has begun now
    __TIB_java_lang_NullPointerException.classInitializationBegan = 1;

    staticInitializerUnlock(&__TIB_java_lang_NullPointerException);

    JAVA_LONG curThreadId = (JAVA_LONG)pthread_self();
    if (initBegan) {
        if (__TIB_java_lang_NullPointerException.initializerThreadId != curThreadId) {
            // Busy wait until the other thread finishes initializing this class
            while (!__TIB_java_lang_NullPointerException.classInitialized) {
                // do nothing
            }
        }
    } else {
        __TIB_java_lang_NullPointerException.initializerThreadId = curThreadId;
        XMLVM_CLASS_USED("java.lang.NullPointerException")
        __INIT_IMPL_java_lang_NullPointerException();
    }
}

void __INIT_IMPL_java_lang_NullPointerException()
{
    // Initialize base class if necessary
    XMLVM_CLASS_INIT(java_lang_RuntimeException)
    __TIB_java_lang_NullPointerException.newInstanceFunc = __NEW_INSTANCE_java_lang_NullPointerException;
    // Copy vtable from base class
    XMLVM_MEMCPY(__TIB_java_lang_NullPointerException.vtable, __TIB_java_lang_RuntimeException.vtable, sizeof(__TIB_java_lang_RuntimeException.vtable));
    // Initialize vtable for this class
    // Initialize interface information
    __TIB_java_lang_NullPointerException.numImplementedInterfaces = 1;
    __TIB_java_lang_NullPointerException.implementedInterfaces = (__TIB_DEFINITION_TEMPLATE* (*)[1]) XMLVM_MALLOC(sizeof(__TIB_DEFINITION_TEMPLATE*) * 1);

    // Initialize interfaces if necessary and assign tib to implementedInterfaces

    XMLVM_CLASS_INIT(java_io_Serializable)

    __TIB_java_lang_NullPointerException.implementedInterfaces[0][0] = &__TIB_java_io_Serializable;
    // Initialize itable for this class
    __TIB_java_lang_NullPointerException.itableBegin = &__TIB_java_lang_NullPointerException.itable[0];

    _STATIC_java_lang_NullPointerException_serialVersionUID = 5162710183389028792;

    __TIB_java_lang_NullPointerException.declaredFields = &__field_reflection_data[0];
    __TIB_java_lang_NullPointerException.numDeclaredFields = sizeof(__field_reflection_data) / sizeof(XMLVM_FIELD_REFLECTION_DATA);
    __TIB_java_lang_NullPointerException.constructorDispatcherFunc = constructor_dispatcher;
    __TIB_java_lang_NullPointerException.declaredConstructors = &__constructor_reflection_data[0];
    __TIB_java_lang_NullPointerException.numDeclaredConstructors = sizeof(__constructor_reflection_data) / sizeof(XMLVM_CONSTRUCTOR_REFLECTION_DATA);
    __TIB_java_lang_NullPointerException.methodDispatcherFunc = method_dispatcher;
    __TIB_java_lang_NullPointerException.declaredMethods = &__method_reflection_data[0];
    __TIB_java_lang_NullPointerException.numDeclaredMethods = sizeof(__method_reflection_data) / sizeof(XMLVM_METHOD_REFLECTION_DATA);
    __CLASS_java_lang_NullPointerException = XMLVM_CREATE_CLASS_OBJECT(&__TIB_java_lang_NullPointerException);
    __TIB_java_lang_NullPointerException.clazz = __CLASS_java_lang_NullPointerException;
    __TIB_java_lang_NullPointerException.baseType = JAVA_NULL;
    __CLASS_java_lang_NullPointerException_1ARRAY = XMLVM_CREATE_ARRAY_CLASS_OBJECT(__CLASS_java_lang_NullPointerException);
    __CLASS_java_lang_NullPointerException_2ARRAY = XMLVM_CREATE_ARRAY_CLASS_OBJECT(__CLASS_java_lang_NullPointerException_1ARRAY);
    __CLASS_java_lang_NullPointerException_3ARRAY = XMLVM_CREATE_ARRAY_CLASS_OBJECT(__CLASS_java_lang_NullPointerException_2ARRAY);
    //XMLVM_BEGIN_WRAPPER[__INIT_java_lang_NullPointerException]
    //XMLVM_END_WRAPPER

    __TIB_java_lang_NullPointerException.classInitialized = 1;
}

void __DELETE_java_lang_NullPointerException(void* me, void* client_data)
{
    //XMLVM_BEGIN_WRAPPER[__DELETE_java_lang_NullPointerException]
    //XMLVM_END_WRAPPER
}

void __INIT_INSTANCE_MEMBERS_java_lang_NullPointerException(JAVA_OBJECT me, int derivedClassWillRegisterFinalizer)
{
    __INIT_INSTANCE_MEMBERS_java_lang_RuntimeException(me, 0 || derivedClassWillRegisterFinalizer);
    //XMLVM_BEGIN_WRAPPER[__INIT_INSTANCE_MEMBERS_java_lang_NullPointerException]
    //XMLVM_END_WRAPPER
}

JAVA_OBJECT __NEW_java_lang_NullPointerException()
{    XMLVM_CLASS_INIT(java_lang_NullPointerException)
java_lang_NullPointerException* me = (java_lang_NullPointerException*) XMLVM_MALLOC(sizeof(java_lang_NullPointerException));
    me->tib = &__TIB_java_lang_NullPointerException;
    __INIT_INSTANCE_MEMBERS_java_lang_NullPointerException(me, 0);
    //XMLVM_BEGIN_WRAPPER[__NEW_java_lang_NullPointerException]
    //XMLVM_END_WRAPPER
    return me;
}

JAVA_OBJECT __NEW_INSTANCE_java_lang_NullPointerException()
{
    JAVA_OBJECT me = JAVA_NULL;
    me = __NEW_java_lang_NullPointerException();
    java_lang_NullPointerException___INIT___(me);
    return me;
}

JAVA_LONG java_lang_NullPointerException_GET_serialVersionUID()
{
    XMLVM_CLASS_INIT(java_lang_NullPointerException)
    return _STATIC_java_lang_NullPointerException_serialVersionUID;
}

void java_lang_NullPointerException_PUT_serialVersionUID(JAVA_LONG v)
{
    XMLVM_CLASS_INIT(java_lang_NullPointerException)
_STATIC_java_lang_NullPointerException_serialVersionUID = v;
}

void java_lang_NullPointerException___INIT___(JAVA_OBJECT me)
{
    //XMLVM_BEGIN_WRAPPER[java_lang_NullPointerException___INIT___]
    XMLVM_ENTER_METHOD("java.lang.NullPointerException", "<init>", "?")
    XMLVMElem _r0;
    _r0.o = me;
    XMLVM_SOURCE_POSITION("NullPointerException.java", 36)
    XMLVM_CHECK_NPE(0)
    java_lang_RuntimeException___INIT___(_r0.o);
    XMLVM_SOURCE_POSITION("NullPointerException.java", 37)
    XMLVM_EXIT_METHOD()
    return;
    //XMLVM_END_WRAPPER
}

void java_lang_NullPointerException___INIT____java_lang_String(JAVA_OBJECT me, JAVA_OBJECT n1)
{
    //XMLVM_BEGIN_WRAPPER[java_lang_NullPointerException___INIT____java_lang_String]
    XMLVM_ENTER_METHOD("java.lang.NullPointerException", "<init>", "?")
    XMLVMElem _r0;
    XMLVMElem _r1;
    _r0.o = me;
    _r1.o = n1;
    XMLVM_SOURCE_POSITION("NullPointerException.java", 47)
    XMLVM_CHECK_NPE(0)
    java_lang_RuntimeException___INIT____java_lang_String(_r0.o, _r1.o);
    XMLVM_SOURCE_POSITION("NullPointerException.java", 48)
    XMLVM_EXIT_METHOD()
    return;
    //XMLVM_END_WRAPPER
}