$fieldTypes = $config['fieldTypes'];
$dependencyVariables = array();
if (isset($config['dependencyVariables'])) {
    $dependencyVariables = $config['dependencyVariables'];
}
$foundTypes = array();
$unusedTypes = array();
// fields generation
foreach ($fields as $fieldName => $fieldInfo) {
    $dependancyArray = createDependencyArray($fieldInfo, $dependencyVariables);
    createFieldConfig($schemaDoc, $schema, $fieldName, $fieldInfo, $dependancyArray);
}
// fieldTypes generation
// fields generation
foreach ($fieldTypes as $fieldType => $fieldTypeInfo) {
    $dependancyArray = createDependencyArray($fieldTypeInfo, $dependencyVariables);
    createFieldTypeConfig($schemaDoc, $schema, $fieldType, $fieldTypeInfo, $dependancyArray);
}
// parsing XML creating readable schema.xml
$schemaDoc->appendChild($schema);
$xml = $schemaDoc->saveXML();
$xml = preg_replace("/\\s+<!--NEWLINE-->/is", "\n", $xml);
//print $xml;
file_put_contents('target/schema.xml', $xml);
print "missing fieldTypes:" . PHP_EOL;
print_r($foundTypes);
print "unused fieldTypes:" . PHP_EOL;
print_r($unusedTypes);
// methods
function createFieldConfig(&$doc, &$el, $fieldName, $fieldInfo, $dependancyArray)
{
function createQueriesConfig(&$doc, &$el, $fields, $entityQueries, $dependencyVariables)
{
    // select
    $selectFields = array();
    $primaryKeys = array();
    $importFields = array();
    foreach ($fields as $fieldName => $fieldInfo) {
        $dependancyArray = createDependencyArray($fieldInfo, $dependencyVariables);
        foreach ($dependancyArray as $pos => $dependancyData) {
            //            $sourceFieldName = $fieldName;
            $currentFieldName = dependencyParser($fieldName, $dependancyData);
            if (isset($fieldInfo['dataSourceEntity'])) {
                if (isset($fieldInfo['uniqueKey']) && $fieldInfo['uniqueKey']) {
                    $primaryKeys[$fieldInfo['dataSourceEntity']] = $currentFieldName;
                }
                if (!isset($selectFields[$fieldInfo['dataSourceEntity']])) {
                    $selectFields[$fieldInfo['dataSourceEntity']] = array();
                    $importFields[$fieldInfo['dataSourceEntity']] = array();
                }
                $statement = isset($fieldInfo['dataSourceStatement']) ? $fieldInfo['dataSourceStatement'] : "`{$currentFieldName}`";
                if (isset($fieldInfo['dataSourceStatementDependencyMapping'])) {
                    $mapping = array();
                    foreach ($dependancyData as $key => $val) {
                        if (isset($fieldInfo['dataSourceStatementDependencyMapping'][$key]) && isset($fieldInfo['dataSourceStatementDependencyMapping'][$key][$val])) {
                            $mapping[$key . '_map'] = $fieldInfo['dataSourceStatementDependencyMapping'][$key][$val];
                        }
                    }
                    $statement = dependencyParser($statement, $mapping);
                }
                if (isset($fieldInfo['multiValued']) && $fieldInfo['multiValued']) {
                    $statement .= " as `{$currentFieldName}`";
                } else {
                    $statement .= " as `{$currentFieldName}`";
                }
                $selectFields[$fieldInfo['dataSourceEntity']][$currentFieldName] = $statement;
                if (isset($fieldInfo['dataSourceMultivaluedSeperator'])) {
                    $importFields[$fieldInfo['dataSourceEntity']][$currentFieldName] = array('column' => $currentFieldName, 'sourceColName' => $currentFieldName, 'splitBy' => $fieldInfo['dataSourceMultivaluedSeperator']);
                } else {
                    $importFields[$fieldInfo['dataSourceEntity']][$currentFieldName] = array('column' => $currentFieldName, 'name' => $currentFieldName);
                }
            }
        }
    }
    // from
    $entitiesXML = array();
    $tabs = str_repeat("\t", 15);
    $tabs2 = str_repeat("\t", 14);
    $tabs3 = str_repeat("\t", 13);
    foreach ($entityQueries as $entityName => $queryInfo) {
        $entity = $doc->createElement('entity');
        $entity->setAttribute('name', $entityName);
        if (isset($queryInfo['dataSource'])) {
            $entity->setAttribute('dataSource', $queryInfo['dataSource']);
        }
        if (isset($queryInfo['transformers'])) {
            $entity->setAttribute('transformer', implode(",", $queryInfo['transformers']));
        }
        if (isset($queryInfo['pk'])) {
            $entity->setAttribute('pk', $queryInfo['pk']);
        } elseif (isset($primaryKeys[$entityName])) {
            $entity->setAttribute('pk', $primaryKeys[$entityName]);
        }
        foreach ($queryInfo['queries'] as $queryType => $queryTypeData) {
            $query = "SELECT ";
            $select = array();
            if (isset($queryTypeData['fields'])) {
                foreach ($queryTypeData['fields'] as $fieldName) {
                    $select[] = $selectFields[$entityName][$fieldName];
                }
            } else {
                $select = $selectFields[$entityName];
            }
            $query .= "\n{$tabs}" . implode(",\n{$tabs}", $select);
            foreach ($queryTypeData['tables'] as $tableGroup) {
                $query .= " \n{$tabs2}" . implode(" \n{$tabs}", $queryInfo['tables'][$tableGroup]);
            }
            $query .= " \n{$tabs2}" . $queryTypeData['filter'] . ";\n{$tabs3}";
            $entity->setAttribute($queryType, $query);
        }
        $entitiesXML[$entityName] = array('element' => $entity);
        if (isset($queryInfo['parentEntity'])) {
            $entitiesXML[$entityName]['parent'] = $queryInfo['parentEntity'];
        }
    }
    // fields
    foreach ($importFields as $entityName => $data) {
        $parentEl = $entitiesXML[$entityName]['element'];
        foreach ($data as $fieldName => $attributes) {
            $field = $doc->createElement('field');
            foreach ($attributes as $attr => $val) {
                $field->setAttribute($attr, $val);
            }
            $parentEl->appendChild($field);
        }
    }
    foreach ($entitiesXML as $entityName => $entityData) {
        if (!isset($entityData['parent'])) {
            $el->appendChild($entityData['element']);
        } else {
            $entitiesXML[$entityData['parent']]['element']->appendChild($entityData['element']);
        }
    }
}