text:
package net.sourceforge.schemaspy.view;

import java.io.File;
import java.io.IOException;
import java.text.NumberFormat;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import net.sourceforge.schemaspy.Config;
import net.sourceforge.schemaspy.model.Database;
import net.sourceforge.schemaspy.model.ForeignKeyConstraint;
import net.sourceforge.schemaspy.model.Table;
import net.sourceforge.schemaspy.model.TableColumn;
import net.sourceforge.schemaspy.model.TableIndex;
import net.sourceforge.schemaspy.model.View;
import net.sourceforge.schemaspy.util.CaseInsensitiveMap;
import net.sourceforge.schemaspy.util.HtmlEncoder;
import net.sourceforge.schemaspy.util.LineWriter;

/**
 * The page that contains the details of a specific table or view
 *
 * @author John Currier
 */
public class HtmlTablePage extends HtmlFormatter {
    private static final HtmlTablePage instance = new HtmlTablePage();
    private int columnCounter = 0;

    private final Map<String, String> defaultValueAliases = new HashMap<String, String>();
    {
        defaultValueAliases.put("CURRENT TIMESTAMP", "now"); // DB2
        defaultValueAliases.put("CURRENT TIME", "now");      // DB2
        defaultValueAliases.put("CURRENT DATE", "now");      // DB2
        defaultValueAliases.put("SYSDATE", "now");           // Oracle
        defaultValueAliases.put("CURRENT_DATE", "now");      // Oracle
    }

    /**
     * Singleton: Don't allow instantiation
     */
    private HtmlTablePage() {
    }

    /**
     * Singleton accessor
     *
     * @return the singleton instance
     */
    public static HtmlTablePage getInstance() {
        return instance;
    }

    public WriteStats write(Database db, Table table, boolean hasOrphans, File outputDir, WriteStats stats, LineWriter out) throws IOException {
        File diagramsDir = new File(outputDir, "diagrams");
        boolean hasImplied = generateDots(table, diagramsDir, stats);

        writeHeader(db, table, null, hasOrphans, out);
        out.writeln("
");
        out.writeln("
");
        writeHeader(table, hasImplied, out);
        out.writeln("	");
        writeLegend(true, out);
        out.writeln("
");
        writeMainTable(table, out);
        writeNumRows(db, table, out);
        out.writeln("

");
        writeCheckConstraints(table, out);
        writeIndexes(table, out);
        writeView(table, db, out);
        writeDiagram(table, stats, diagramsDir, out);
        writeFooter(out);

        return stats;
    }

    private void writeHeader(Table table, boolean hasImplied, LineWriter html) throws IOException {
        html.writeln("<form name='options' action=''>");
        if (hasImplied) {
            html.write(" <input type=checkbox id='implied'");
            if (table.isOrphan(false))
                html.write(" checked");
            html.writeln(">Implied relationships");
        }

        // initially show comments if any of the columns contain comments
        boolean showCommentsInitially = false;
        for (TableColumn column : table.getColumns()) {
            if (column.getComments() != null) {
                showCommentsInitially = true;
                break;
            }
        }

        html.writeln(" <input type=checkbox id='showRelatedCols'>Related columns");
        html.writeln(" <input type=checkbox id='showConstNames'>Constraints");
        html.writeln(" <input type=checkbox " + (showCommentsInitially  ? "checked " : "") + "id='showComments'>Comments");
        html.writeln(" <input type=checkbox checked id='showLegend'>Legend");
        html.writeln("</form>");
    }

    public void writeMainTable(Table table, LineWriter out) throws IOException {
        HtmlColumnsPage.getInstance().writeMainTableHeader(table.getId() != null, null, out);

        out.writeln("
");
        Set<TableColumn> primaries = new HashSet<TableColumn>(table.getPrimaryColumns());
        Set<TableColumn> indexedColumns = new HashSet<TableColumn>();
        for (TableIndex index : table.getIndexes()) {
            indexedColumns.addAll(index.getColumns());
        }

        boolean showIds = table.getId() != null;
        for (TableColumn column : table.getColumns()) {
            writeColumn(column, null, primaries, indexedColumns, false, showIds, out);
        }
        out.writeln("
");
    }

    public void writeColumn(TableColumn column, String tableName, Set<TableColumn> primaries, Set<TableColumn> indexedColumns, boolean slim, boolean showIds, LineWriter out) throws IOException {
        boolean even = columnCounter++ % 2 == 0;
        if (even)
            out.writeln("
");
        else
            out.writeln("
");

        if (showIds) {
            out.write(" ");
            out.write(String.valueOf(column.getId()));
            out.writeln("	");
        }
        if (tableName != null) {
            out.write(" ");
            out.write(tableName);
            out.writeln("	");
        }
        if (primaries.contains(column))
            out.write(" ");
        else if (indexedColumns.contains(column))
            out.write(" ");
        else
            out.write(" ");
        out.write(column.getName());
        out.writeln("	");
        out.write(" ");
        out.write(column.getType().toLowerCase());
        out.writeln("	");
        out.write(" ");
        out.write(column.getDetailedSize());
        out.writeln("	");
        out.write("  √ ");
        else
            out.write(">");
        out.writeln("	");
        out.write("  √ ");
        } else {
            out.write(">");
        }
        out.writeln("	");

        Object defaultValue = column.getDefaultValue();
        if (defaultValue != null || column.isNullable()) {
            Object alias = defaultValueAliases.get(String.valueOf(defaultValue).trim());
            if (alias != null) {
                out.write(" ");
                out.write(alias.toString());
                out.writeln("	");
            } else {
                out.write(" ");
                out.write(String.valueOf(defaultValue));
                out.writeln("	");
            }
        } else {
            out.writeln(" 	");
        }
        if (!slim) {
            out.write(" ");
            String path = tableName == null ? "" : "tables/";
            writeRelatives(column, false, path, even, out);
            out.writeln("	");
            out.write(" ");
            writeRelatives(column, true, path, even, out);
            out.writeln(" 	");
        }
        out.write(" ");
        String comments = column.getComments();
        if (comments != null) {
            if (encodeComments)
                for (int i = 0; i < comments.length(); ++i)
                    out.write(HtmlEncoder.encodeToken(comments.charAt(i)));
            else
                out.write(comments);
        }
        out.writeln("	");
        out.writeln("
");
    }

    /**
     * Write our relatives
     * @param tableName String
     * @param baseRelative TableColumn
     * @param dumpParents boolean
     * @param out LineWriter
     * @throws IOException
     */
    private void writeRelatives(TableColumn baseRelative, boolean dumpParents, String path, boolean even, LineWriter out) throws IOException {
        Set<TableColumn> columns = dumpParents ? baseRelative.getParents() : baseRelative.getChildren();
        final int numColumns = columns.size();
        final String evenOdd = (even ? "even" : "odd");

        if (numColumns > 0) {
            out.newLine();
            out.writeln("
");
        }

        for (TableColumn column : columns) {
            String columnTableName = column.getTable().getName();
            ForeignKeyConstraint constraint = dumpParents ? column.getChildConstraint(baseRelative) : column.getParentConstraint(baseRelative);
            if (constraint.isImplied())
                out.writeln("
");
            else
                out.writeln("
");
            out.write("    ");
            out.write("");
            out.write(columnTableName);
            out.write("");
            out.write(".");
            out.write(column.getName());
            out.writeln("");
            out.writeln("    	");

            out.write("    ");
            out.write(constraint.getName());
            String ruleText = constraint.getDeleteRuleDescription();
            if (ruleText.length() > 0)
            {
                String ruleAlias = constraint.getDeleteRuleAlias();
                out.write(" " + ruleAlias + "");
            }
            out.writeln("	");

            out.writeln("
");
        }
        if (numColumns > 0) {
            out.writeln("
");
        }
    }

    private void writeNumRows(Database db, Table table, LineWriter out) throws IOException {
        out.write("
");
        if (displayNumRows && !table.isView()) {
            out.write("Table contained " + NumberFormat.getIntegerInstance().format(table.getNumRows()) + " rows at ");
        } else {
            out.write("Analyzed at ");
        }
        out.write(db.getConnectTime());
        out.writeln("
");
    }

    private void writeCheckConstraints(Table table, LineWriter out) throws IOException {
        Map<String, String> constraints = table.getCheckConstraints();
        if (constraints != null && !constraints.isEmpty()) {
            out.writeln("
");
            out.writeln("Requirements (check constraints):");
            out.writeln("
<colgroup><colgroup>");
            out.writeln("
");
            out.writeln("
");
            out.writeln("  Constraint	");
            out.writeln("  Constraint Name	");
            out.writeln("
");
            out.writeln("
");
            out.writeln("
");
            for (String name : constraints.keySet()) {
                out.writeln("
");
                out.write("  ");
                out.write(HtmlEncoder.encodeString(constraints.get(name).toString()));
                out.writeln("	");
                out.write("  ");
                out.write(name);
                out.writeln("	");
                out.writeln("
");
            }
            out.writeln("

");
        }
    }

    private void writeIndexes(Table table, LineWriter out) throws IOException {
        boolean showId = table.getId() != null;
        Set<TableIndex> indexes = table.getIndexes();
        if (indexes != null && !indexes.isEmpty()) {
            // see if we've got any strangeness so we can have the correct number of colgroups
            boolean containsAnomalies = false;
            for (TableIndex index : indexes) {
                containsAnomalies = index.isUniqueNullable();
                if (containsAnomalies)
                    break;
            }

            out.writeln("
");
            out.writeln("Indexes:");
            out.writeln("
<colgroup><colgroup><colgroup><colgroup>" + (showId ? "<colgroup>" : "") + (containsAnomalies ? "<colgroup>" : ""));
            out.writeln("
");
            out.writeln("
");
            if (showId)
                out.writeln("  ID	");
            out.writeln("  Column(s)	");
            out.writeln("  Type	");
            out.writeln("  Sort	");
            out.writeln("  Constraint Name	");
            if (containsAnomalies)
                out.writeln("  Anomalies	");
            out.writeln("
");
            out.writeln("
");
            out.writeln("
");

            indexes = new TreeSet<TableIndex>(indexes); // sort primary keys first

            for (TableIndex index : indexes) {
                out.writeln("
");

                if (showId) {
                    out.write("  ");
                    out.write(String.valueOf(index.getId()));
                    out.writeln("	");
                }

                if (index.isPrimaryKey())
                    out.write("  ");
                else
                    out.write("  ");
                String columns = index.getColumnsAsString();
                if (columns.startsWith("+"))
                    columns = columns.substring(1);
                out.write(columns);
                out.writeln("	");

                out.write("  ");
                out.write(index.getType());
                out.writeln("	");

                out.write("  ");
                Iterator<TableColumn> columnsIter = index.getColumns().iterator();
                while (columnsIter.hasNext()) {
                    TableColumn column = columnsIter.next();
                    if (index.isAscending(column))
                        out.write("Asc");
                    else
                        out.write("Desc");
                    if (columnsIter.hasNext())
                        out.write("/");
                }
                out.writeln("	");

                out.write("  ");
                out.write(index.getName());
                out.writeln("	");

                if (index.isUniqueNullable()) {
                    if (index.getColumns().size() == 1)
                        out.writeln("  This unique column is also nullable	");
                    else
                        out.writeln("  These unique columns are also nullable	");
                } else if (containsAnomalies) {
                    out.writeln("   	");
                }
                out.writeln("
");
            }
            out.writeln("
");
            out.writeln("
");
        }
    }

    private void writeView(Table table, Database db, LineWriter out) throws IOException {
        String sql;
        if (table.isView() && (sql = table.getViewSql()) != null) {
            Map<String, Table> tables = new CaseInsensitiveMap
();

            for (Table t : db.getTables())
                tables.put(t.getName(), t);
            for (View v : db.getViews())
                tables.put(v.getName(), v);

            Set
 references = new TreeSet
();
            String formatted = Config.getInstance().getSqlFormatter().format(sql, db, references);

            out.writeln("
");
            out.writeln("  View Definition:");
            out.writeln(formatted);
            out.writeln("
");
            out.writeln("

");

            if (!references.isEmpty()) {
                out.writeln("
");
                out.writeln("  Possibly Referenced Tables/Views:");
                out.writeln("
");
                out.write("  ");
                for (Table t : references) {
                    out.write("");
                    out.write(t.getName());
                    out.write(" ");
                }

                out.writeln("
");
                out.writeln("

");
            }

        }
    }

    /**
     * Generate the .dot file(s) to represent the specified table's relationships.
     *
     * Generates a <TABLENAME>.dot if the table has real relatives.
     *
     * Also generates a <TABLENAME>..implied2degrees.dot if the table has implied relatives within
     * two degrees of separation.
     *
     * @param table Table
     * @param diagramsDir File
     * @throws IOException
     * @return boolean true if the table has implied relatives within two
     *                 degrees of separation.
     */
    private boolean generateDots(Table table, File diagramDir, WriteStats stats) throws IOException {
        File oneDegreeDotFile = new File(diagramDir, table.getName() + ".1degree.dot");
        File oneDegreeDiagramFile = new File(diagramDir, table.getName() + ".1degree.png");
        File twoDegreesDotFile = new File(diagramDir, table.getName() + ".2degrees.dot");
        File twoDegreesDiagramFile = new File(diagramDir, table.getName() + ".2degrees.png");
        File impliedDotFile = new File(diagramDir, table.getName() + ".implied2degrees.dot");
        File impliedDiagramFile = new File(diagramDir, table.getName() + ".implied2degrees.png");

        // delete before we start because we'll use the existence of these files to determine
        // if they should be turned into pngs & presented
        oneDegreeDotFile.delete();
        oneDegreeDiagramFile.delete();
        twoDegreesDotFile.delete();
        twoDegreesDiagramFile.delete();
        impliedDotFile.delete();
        impliedDiagramFile.delete();

        if (table.getMaxChildren() + table.getMaxParents() > 0) {
            Set<ForeignKeyConstraint> impliedConstraints;

            DotFormatter formatter = DotFormatter.getInstance();
            LineWriter dotOut = new LineWriter(oneDegreeDotFile, Config.DOT_CHARSET);
            WriteStats oneStats = new WriteStats(stats);
            formatter.writeRealRelationships(table, false, oneStats, dotOut);
            dotOut.close();

            dotOut = new LineWriter(twoDegreesDotFile, Config.DOT_CHARSET);
            WriteStats twoStats = new WriteStats(stats);
            impliedConstraints = formatter.writeRealRelationships(table, true, twoStats, dotOut);
            dotOut.close();

            if (oneStats.getNumTablesWritten() + oneStats.getNumViewsWritten() == twoStats.getNumTablesWritten() + twoStats.getNumViewsWritten()) {
                twoDegreesDotFile.delete(); // no different than before, so don't show it
            }

            if (!impliedConstraints.isEmpty()) {
                dotOut = new LineWriter(impliedDotFile, Config.DOT_CHARSET);
                formatter.writeAllRelationships(table, true, stats, dotOut);
                dotOut.close();
                return true;
            }
        }

        return false;
    }

    private void writeDiagram(Table table, WriteStats stats, File diagramsDir, LineWriter html) throws IOException {
        if (table.getMaxChildren() + table.getMaxParents() > 0) {
            html.writeln("

");
            if (HtmlTableDiagrammer.getInstance().write(table, diagramsDir, html)) {
                html.writeln("

");
                writeExcludedColumns(stats.getExcludedColumns(), table, html);
            } else {
                html.writeln("

");
                writeInvalidGraphvizInstallation(html);
            }
        }
    }

    @Override
    protected String getPathToRoot() {
        return "../";
    }
}


text:
Szyfrowanie asymetryczne pozwala na szyfrowanie w jedną stronę.
Za pomocą klucza Publicznego.

Jak i deszyfrację za pomocą klucza prywatnego.

Szyfrujemy kluczem publicznym a aby odszyfrować to potrzebny jest klucz prywatny.

Jest wolniejszy od szyfrowania symetrycznego.

##RSA

[Generowanie kluczy i zapisywanie do pliku](RSA_Generowanie_Kluczy.cs)
Proste generowanie kluczy i zapisanie tych kluczy do pliku

[Szyfrowanie i deszyfrowanie](RSA_szyfracja_deszyfracja.cs)
Szyfrowanie i deszyfrowanie bajtów za pomocą RSA.

[Szyfracja i deszyfracja korzystając z kluczy które są niezabezpieczone i zapisane w pliku](RSA_Szyfracja_i_Deszyfracja_z_klucza_plikowym.cs)
Szyfrowanie i deszyfrowanie bajtów za pomocą klucza zapisanego w pliku.

redpajama_set_name: RedPajamaGithub


text:
#include <aws/apigateway/model/GetApiKeysRequest.h>
#include <aws/core/utils/json/JsonSerializer.h>
#include <aws/core/http/URI.h>
#include <aws/core/utils/memory/stl/AWSStringStream.h>

#include <utility>

using namespace Aws::APIGateway::Model;
using namespace Aws::Utils::Json;
using namespace Aws::Utils;
using namespace Aws::Http;

GetApiKeysRequest::GetApiKeysRequest() :
    m_positionHasBeenSet(false),
    m_limit(0),
    m_limitHasBeenSet(false),
    m_nameQueryHasBeenSet(false),
    m_includeValues(false),
    m_includeValuesHasBeenSet(false)
{
}

Aws::String GetApiKeysRequest::SerializePayload() const
{
  return "";
}

void GetApiKeysRequest::AddQueryStringParameters(URI& uri) const
{
    Aws::StringStream ss;
    if(m_positionHasBeenSet)
    {
      ss << m_position;
      uri.AddQueryStringParameter("position", ss.str());
      ss.str("");
    }

    if(m_limitHasBeenSet)
    {
      ss << m_limit;
      uri.AddQueryStringParameter("limit", ss.str());
      ss.str("");
    }

    if(m_nameQueryHasBeenSet)
    {
      ss << m_nameQuery;
      uri.AddQueryStringParameter("name", ss.str());
      ss.str("");
    }

    if(m_includeValuesHasBeenSet)
    {
      ss << m_includeValues;
      uri.AddQueryStringParameter("includeValues", ss.str());
      ss.str("");
    }

}


text:
.. _gallery:

Gallery
========

Here are a few projects using MoviePy. The gallery will fill up as more people start using MoviePy (which is currently one year old). If you have a nice project using MoviePy let us know!

Videos edited with Moviepy
---------------------------

The Cup Song Covers Mix
~~~~~~~~~~~~~~~~~~~~~~~~

This mix of 60 covers of the Cup Song demonstrates the non-linear video editing capabilities of MoviePy. Here is `the (undocumented) MoviePy code <https://nbviewer.ipython.org/github/Zulko/--video-editing---Cup-Song-Covers-Mix/blob/master/CupSongsCovers.ipynb>`_ that generated the video.

.. raw:: html

The (old) MoviePy reel video.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Made when MoviePy was a few weeks old and not as good as now. The code for most scenes can be found
in the :ref:`examples`.

.. raw:: html

Animations edited with MoviePy
------------------------------

GIFs made from videos
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This  `gifs tutorial
<https://zulko.github.io/blog/2014/01/23/making-animated-gifs-from-video-files-with-python/>`_ gives you the basics to make gifs from video files (cutting, croping, adding text...). The last example shows how to remove a (still) background to keep only the animated part of a video.

.. raw:: html

Vector Animations
~~~~~~~~~~~~~~~~~~~

This `vector animations tutorial <https://zulko.github.io/blog/2014/09/20/vector-animations-with-python/>`_ shows how to combine MoviePy with Gizeh to create animations:

.. raw:: html

It is also possible to combine MoviePy with other graphic librairies like matplotlib, etc.

3D animations
~~~~~~~~~~~~~~~~~~~

This `3d animation tutorial <https://zulko.github.io/blog/2014/11/13/things-you-can-do-with-python-and-pov-ray/>`_ shows how to combine MoviePy with Vapory, a library to render 3D scenes using the free ray-tracer POV-Ray

.. raw:: html

With Vapory and MoviePy you can for instance embed a movie in a 3D scene:

.. raw:: html

Or render the result of this physics simulation made with PyODE (`script <https://gist.github.com/Zulko/f828b38421dfbee59daf>`_):

.. raw:: html

Or use `this script <https://gist.github.com/Zulko/b910c8b22e8e1c01fae6>`_ to make piano animations from MIDI files (which are some sort of electronic sheet music):

.. raw:: html

Data animations
----------------

This `data animation tutorial <https://zulko.github.io/blog/2014/11/13/things-you-can-do-with-python-and-pov-ray/>`_ shows how to use MoviePy to animate the different Python vizualization libraries: Mayavi, Vispy, Scikit-image, Matplotlib, etc.

Scientific or technological projects
-------------------------------------

Piano rolls transcription to sheet music
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This `transcribing piano rolls blog post <https://zulko.github.io/blog/2014/02/12/transcribing-piano-rolls/>`_ explains how to transform a video of a piano roll performance into playable sheet music. MoviePy is used for the frame-by-frame analysis of the piano roll video. The last video is also edited with MoviePy:

.. raw:: html

Misc. Programs and Scripts using MoviePy
------------------------------------------
Kapwing
----------

`Kapwing <https://www.kapwing.com/>`_ is an online video meme generator. Content creators use Kapwing to add text around their videos, which results in higher engagement / views on social media sites like Facebook. Kapwing's creation process is powered by MoviePy! MoviePy is used to add the text, borders, and attribution directly to the uploaded videos.

.. raw:: html

        <video src="https://cdn.kapwing.com/video_5e681ac49187d40016ee123e_579130.mp4?" controls style="max-width:70%; height:'auto'; display:block; margin-left: auto;margin-right: auto; margin-bottom:30px;"></video>

Rinconcam
----------

`Rincomcam <http://www.rinconcam.com/month/2014-03>`_ is a camera which films surfers on the Californian beach of Point Rincon. At the end of each day it cuts together a video, puts it online, and tweets it. Everything is entirely automatized with Python.
MoviePy is used to add transitions, titles and music to the videos.

.. raw:: html

Videogrep
----------

Videogrep is a python script written by Sam Lavigne, that goes through the subtitle tracks of movies and makes supercuts based on what it finds. For instance, here is an automatic supercut of every time the White House press secretary tells us what he can tell us:

.. raw:: html

Here are `Videogrep's introductory blog post
<http://lav.io/2014/06/videogrep-automatic-supercuts-with-python/>`_ and the Github `Videogrep page <https://github.com/antiboredom/videogrep/>`_.

If you liked it, also have a look at these Videogrep-inspired projects:

This `Videogrep blog post <https://zulko.github.io/blog/2014/06/21/some-more-videogreping-with-python/>`_ attempts to cut a video precisely at the beginning and end of sentences or words: ::

    words = ["Americans", "must", "develop", "open ", "source",
              " software", "for the", " rest ", "of the world",
              "instead of", " soldiers"]
    numbers = [3,0,4,3,4,0,1,2,0,1,0] # take clip number 'n'

    cuts = [find_word(word)[n] for (word,n) in zip(words, numbers)]
    assemble_cuts(cuts, "fake_speech.mp4")

.. raw:: html

This `other post <https://zulko.github.io/blog/2014/07/04/automatic-soccer-highlights-compilations-with-python/>`_ uses MoviePy to automatically cut together `all the highlights of a soccer game <http://youtu.be/zJtWPFX2bA0>`_, based on the fact that the crowd cheers louder when something interesting happens. All in under 30 lines of Python:


text:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PanFASE
{
    public partial class TelaRelatorio : Form
    {
        public string inicio { get; set; }
        public string fim { get; set; }
        public TelaRelatorio(string inicio, string fim)
        {
            InitializeComponent();
            this.inicio = inicio;
            this.fim = fim;
        }

        private void bt_gerarRelatorio_Click(object sender, EventArgs e)
        {
        }

        private void TelaRelatorio_Load(object sender, EventArgs e)
        {
            RPedidoProduto p = new RPedidoProduto();
            PedidoProdutoBindingSource.DataSource = p.GetPedidos(this.inicio,this.fim);
            this.rv_relatorio.RefreshReport();
        }

        private void dtp_datafinal_ValueChanged(object sender, EventArgs e)
        {

        }
    }
}


text:
Assets
======

Put static files that do not need to be compiled or manipulated here as as the **contents** of this directory will be copied verbatim to the /public folder.


text:
using ChoETL;
using NUnit.Framework;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace ChoXmlWriterTest
{

    public class Emp
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public class Choice
    {
        public string[] Options { get; set; }
        public Emp Emp { get; set; }
        public List<int> Ids { get; set; }
        public Emp[] EmpArr { get; set; }
        //public Dictionary<int, Emp> EmpDict { get; set; }
    }

    [TestFixture]
    [SetCulture("en-US")] // TODO: Check if correct culture is used
    public class Program
    {

        public static void JSON2XML()
        {
            string json = @"{
  ""header"": ""myheader"",
  ""transaction"": {
    ""date"": ""2019-09-24"",
    ""items"": [
      {
        ""number"": ""123"",
        ""unit"": ""EA"",
        ""qty"": 6
      },
      {
        ""number"": ""456"",
        ""unit"": ""CS"",
        ""qty"": 4
      }
    ]
  }
}";
            using (var r = ChoJSONReader.LoadText(json))
            {
                var x = r.FirstOrDefault();
                //Console.WriteLine(x.Dump());
                Console.WriteLine(ChoXmlWriter.ToText(x, new ChoXmlRecordConfiguration().Configure(c =>
                {
                    c.RootName = "Root1";
                    //c.DoNotEmitXmlNamespace = true;
                    //c.TurnOffXmlFormatting = true;
                })));
            }
        }

        public static void JSON2SoapXML()
        {
            string json = @"{
  ""Name"": ""00141169"",
  ""CurrencyCode"": ""EUR"",
  ""Date"": ""2020-04-03"",
}";

            StringBuilder xml = new StringBuilder();
            using (var r = ChoJSONReader.LoadText(json))
            {
                var x = r.FirstOrDefault();
                //Console.WriteLine(x.Dump());

                using (var w = new ChoXmlWriter(xml)
                    .Configure(c => c.NamespaceManager.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/"))
                    .Configure(c => c.NamespaceManager.AddNamespace("tmp", "http://tempuri.org/"))
                    .Configure(c => c.RootName = "soap:Envelope")
                    .Configure(c => c.NodeName = "Body")
                    .Configure(c => c.DefaultNamespacePrefix = "tmp")
                    //.Configure(c => c.Formatting = System.Xml.Formatting.None)
                    )
                {
                    w.Write(new { listdata = x });
                }
            }

            Console.WriteLine(xml.ToString());
        }

        public static void CSVWithSpaceHeader2Xml()
        {
            string csv = @"Id, First Name
1, Tom
2, Mark";

            StringBuilder xml = new StringBuilder();
            using (var r = ChoCSVReader.LoadText(csv)
                .WithFirstLineHeader())
            {
                using (var w = new ChoXmlWriter(xml)
                    //.TurnOffAutoCorrectXNames()
                    .ErrorMode(ChoErrorMode.ThrowAndStop)
                    )
                {
                    w.Write(r);
                }
            }

            Console.WriteLine(xml.ToString());

            //using (var reader = new ChoCSVReader("C:\\Server Media\\test3.csv")
            //    .WithFirstLineHeader()
            //    .Configure(c => c.FileHeaderConfiguration.IgnoreColumnsWithEmptyHeader = true)
            //    )
            //{
            //    using (var writer = new ChoXmlWriter(sb)
            //        .Configure(c => c.RootName = "Records")
            //        .Configure(c => c.NodeName = "Record")
            //        .Configure(c => c.EmptyXmlNodeValueHandling = ChoEmptyXmlNodeValueHandling.Empty)
            //        .Configure(c => c.ErrorMode = ChoErrorMode.ThrowAndStop)
            //        )
            //    {
            //        writer.Write(reader.Select(r =>
            //        {
            //            r.RenameKey("Company Name", "CompanyName");
            //            return r;
            //        }));
            //    }
            //}
        }

        public class FooBar
        {

            private string foo;

            public string Foo
            {
                get
                {
                    return this.foo;
                }
                set
                {
                    this.foo = value;
                }
            }
        }

        static void RootAttributeWithNSTest()
        {
            StringBuilder xml = new StringBuilder();

            using (var w = new ChoXmlWriter<FooBar>(xml)
                //.WithXmlNamespace("", "urn:foobar1")
                .Configure(c => c.DoNotEmitXmlNamespace = true)
                )
            {
                w.Write(new FooBar
                {
                    Foo = "Tom"
                });
            }

            Console.WriteLine(xml.ToString());
        }

        public static void CustomNodeNameTest()
        {
            string xml1 = @"<Root>
  <Node1>
    <Id>1</Id>
    <FirstName>Tom</FirstName>
  </Node1>
  <Node2>
    <Id>2</Id>
    <FirstName>Mark</FirstName>
  </Node2>
</Root>";

            using (var r = ChoXmlReader.LoadText(xml1))
            {
                foreach (var rec in r)
                    Console.WriteLine(rec.Dump());

            }

            return;

            string csv = @"Id, First Name
1, Tom
2, Mark";

            StringBuilder xml = new StringBuilder();
            using (var r = ChoCSVReader.LoadText(csv)
                .WithFirstLineHeader())
            {
                using (var w = new ChoXmlWriter(xml)
                    .ErrorMode(ChoErrorMode.ThrowAndStop)
                    .Setup(s => s.CustomeNodeNameOverride += (o, e) =>
                    {
                        e.NodeName = $"Node{e.Index}";
                    })
                    )
                {
                    w.Write(r);
                }
            }

            Console.WriteLine(xml.ToString());

            //using (var reader = new ChoCSVReader("C:\\Server Media\\test3.csv")
            //    .WithFirstLineHeader()
            //    .Configure(c => c.FileHeaderConfiguration.IgnoreColumnsWithEmptyHeader = true)
            //    )
            //{
            //    using (var writer = new ChoXmlWriter(sb)
            //        .Configure(c => c.RootName = "Records")
            //        .Configure(c => c.NodeName = "Record")
            //        .Configure(c => c.EmptyXmlNodeValueHandling = ChoEmptyXmlNodeValueHandling.Empty)
            //        .Configure(c => c.ErrorMode = ChoErrorMode.ThrowAndStop)
            //        )
            //    {
            //        writer.Write(reader.Select(r =>
            //        {
            //            r.RenameKey("Company Name", "CompanyName");
            //            return r;
            //        }));
            //    }
            //}
        }

        public static void CSVW2XmlNoFormattingTest()
        {
            string csv = @"Id, First Name
1, Tom
2, Mark";

            StringBuilder xml = new StringBuilder();
            using (var r = ChoCSVReader.LoadText(csv)
                .WithFirstLineHeader())
            {
                using (var w = new ChoXmlWriter(xml)
                    .ErrorMode(ChoErrorMode.IgnoreAndContinue)
                    //.IgnoreRootName()
                    //.IgnoreNodeName()
                    //.Configure(c => c.Formatting = System.Xml.Formatting.None)
                    )
                {
                    w.Write(r.First());
                }
            }

            Console.WriteLine(xml.ToString());
        }

        public static void POCOCSVW2XmlNoFormattingTest()
        {
            string csv = @"Id, Name
1, Tom
2, Mark";

            StringBuilder xml = new StringBuilder();
            using (var r = ChoCSVReader<Emp>.LoadText(csv)
                .WithFirstLineHeader())
            {
                using (var w = new ChoXmlWriter<Emp>(xml)
                    .ErrorMode(ChoErrorMode.ThrowAndStop)
                    //.IgnoreRootName()
                    //.IgnoreNodeName()
                    //.Configure(c => c.Formatting = System.Xml.Formatting.None)
                    )
                {
                    w.Write(r.First());
                }
            }

            Console.WriteLine(xml.ToString());
        }

        static void Test2()
        {
            StringBuilder xml = new StringBuilder();

            using (var parser = new ChoXmlWriter(xml).WithXPath("//ticket//Employees/Employee")
                )
            {
                parser.Write(new object[] { new { Id = 1, Name = "Mark" }, new { Id = 1, Name = "Mark" } });
            }

            Console.WriteLine(xml.ToString());
        }

        static void ListTest()
        {
            StringBuilder xml = new StringBuilder();

            using (var w = new ChoXmlWriter<string>(xml).UseXmlSerialization().WithXPath("t1/t2/r4/t5/Employees/Employee"))
            {
                w.Write(new List<string> { "Tom", "Mark" });
            }

            Console.WriteLine(xml.ToString());

        }

        static void DictTest()
        {
            StringBuilder xml = new StringBuilder();

            using (var w = new ChoXmlWriter(xml).UseXmlSerialization().WithXPath("Employees/Employee"))
            {
                w.Write(new Dictionary<int, string> { { 1, "Tom" }, { 2, "Mark" } });
            }

            Console.WriteLine(xml.ToString());

        }

        static void MergeXml()
        {
            IDictionary<string, dynamic[]> lookup = null;
            using (var r2 = new ChoXmlReader("XMLFile2.xml")
                .WithXPath("//Transaction")
                )
            {
                lookup = r2.GroupBy(rec1 => (string)rec1.JID).ToDictionary(lu => lu.Key, lu => lu.ToArray());
            }

            dynamic[] nodes = null;
            using (var r1 = new ChoXmlReader("XMLFile1.xml")
                .WithXPath("//Journals")
                )
            {
                nodes = r1.ToArray();
            }

            foreach (var rec in nodes)
            {
                if (lookup.ContainsKey((string)rec.JournalID))
                {
                    rec.Add("Transactions", lookup[(string)rec.JournalID]);
                }
            }

            foreach (var rec in nodes)
                Console.WriteLine(rec.Dump());

            StringBuilder xml = new StringBuilder();
            using (var w = new ChoXmlWriter(xml)
                .Configure(c => c.UseXmlArray = false)
                )
            {
                w.Write(nodes);
            }

            Console.WriteLine(xml.ToString());
        }

        //[XmlRoot(ElementName = "readCase", Namespace = "http://tempuri")]
        public class ReadCase
        {
            //[XmlElement(ElementName = "versionAsOf", Namespace = "http://tempuri")]
            public BaseUtcTimeStamp VersionAsOf { get; set; }
        }
        public struct BaseUtcTimeStamp
        {
            private string _utcTimestamp;
            [XmlText]
            public string UtcTimestamp { get => _utcTimestamp; set { } } // set is needed for XmlSerializer

            public BaseUtcTimeStamp(DateTime utcDateTime)
            {
                //if (utcDateTime.Kind != DateTimeKind.Utc)
                //{
                //    throw new ArgumentException("Given dateTime must be Utc.");
                //}

                _utcTimestamp = utcDateTime.ToString("yyyy-MM-ddTHH:mm:ssZ");
            }
        }

        static void XmlTextTest()
        {
            StringBuilder xml = new StringBuilder();

            using (var w = new ChoXmlWriter<ReadCase>(xml)
                .ErrorMode(ChoErrorMode.IgnoreAndContinue)
                //.UseXmlSerialization()
                //.WithDefaultNamespacePrefix("case")
                //.WithXmlNamespace("case", "http://tempuri")
                //.WithNodeName("xxx")
                //.WithRootName("zzz")
                .Configure(c => c.OmitXsiNamespace = true)
                )
            {
                w.Write(new ReadCase
                {
                    VersionAsOf = new BaseUtcTimeStamp(DateTime.Now)
                });
            }

            Console.WriteLine(xml.ToString());
        }

        static void Xml3Test()
        {
            StringBuilder csv1 = new StringBuilder();
            //using (var r = new ChoXmlReader("XmlFile3.xml")
            //    .WithXPath("/Company")
            //    )
            //{
            //    using (var w = new ChoCSVWriter(csv1)
            //        .WithFirstLineHeader()
            //        .Configure(c => c.IgnoreRootNodeName = true)
            //        )
            //        w.Write(r);
            //}

            StringBuilder csv2 = new StringBuilder();
            using (var r = new ChoXmlReader("XmlFile3.xml")
                .WithXPath("/JobDetails")
                )
            {
                var arr = r.ToArray();
                using (var w = new ChoCSVWriter(csv2)
                    .WithFirstLineHeader()
                    .Configure(c => c.IgnoreRootNodeName = true)
                    )
                    w.Write(arr);
            }

            string combinedCSV = csv1.ToString() + Environment.NewLine + csv2.ToString();

            Console.WriteLine(combinedCSV);
        }

        [Serializable]
        public class TimespanClass
        {
            public int Id { get; set; }
            [XmlElement(Type = typeof(XmlTimeSpan))]
            public TimeSpan TimeSinceLastEvent { get; set; }
        }

        static void TimeSpanTest()
        {
            StringBuilder xml = new StringBuilder();
            using (var w = new ChoXmlWriter<TimespanClass>(xml)
                .UseXmlSerialization()
                )
            {
                w.Write(new TimespanClass
                {
                    Id = 1,
                    TimeSinceLastEvent = TimeSpan.FromDays(1)
                });
            }

            Console.WriteLine(xml.ToString());
            using (var r = new ChoXmlReader<TimespanClass>(xml)
                .UseXmlSerialization()
                )
            {
                r.Print();
            }
        }
        public class XmlTimeSpan
        {
            private const long TICKS_PER_MS = TimeSpan.TicksPerMillisecond;

            private TimeSpan m_value = TimeSpan.Zero;

            public XmlTimeSpan() { }
            public XmlTimeSpan(TimeSpan source) { m_value = source; }

            public static implicit operator TimeSpan?(XmlTimeSpan o)
            {
                return o == null ? default(TimeSpan?) : o.m_value;
            }

            public static implicit operator XmlTimeSpan(TimeSpan? o)
            {
                return o == null ? null : new XmlTimeSpan(o.Value);
            }

            public static implicit operator TimeSpan(XmlTimeSpan o)
            {
                return o == null ? default(TimeSpan) : o.m_value;
            }

            public static implicit operator XmlTimeSpan(TimeSpan o)
            {
                return o == default(TimeSpan) ? null : new XmlTimeSpan(o);
            }

            [XmlText]
            public long Default
            {
                get { return m_value.Ticks / TICKS_PER_MS; }
                set { m_value = new TimeSpan(value * TICKS_PER_MS); }
            }
        }
        public static void Xml2Json1()
        {
            string xml = @"<AdapterCards>
    <cards type=""MCS"">
        <card>
            <id>id1</id>
            <description>desc1</description>
            <mccode>code1</mccode>
        </card>
        <card>
            <id>id2</id>
            <description>desc2</description>
            <mccode>code2</mccode>
        </card>
    </cards>
    <cards type=""MCM"">
        <card>
            <id>id3</id>
            <description>desc3</description>
            <mccode>code3</mccode>
        </card>
        <card>
            <id>id4</id>
            <description>desc4</description>
            <mccode>code4</mccode>
        </card>
    </cards>
    <cards type=""F""/>
    <cards type=""B""/>
</AdapterCards>";

            using (var r = ChoXmlReader.LoadText(xml)
                   .WithXPath("//cards")
                   )
            {
                using (var w = new ChoJSONWriter(Console.Out)
                    .Configure(c => c.FlattenNode = true)
                    .Configure(c => c.IgnoreDictionaryFieldPrefix = true)
                      )
                    w.Write(r);
                //w.Write(r.Select(r1 => r1.ConvertToFlattenObject(true)));
            }
        }

        public static void WriteElemetsWithDifferentNS()
        {
            dynamic item = new ChoDynamicObject("item");
            item.AddNamespace("foo", "http://temp.com");
            item.name = "Mark";
            item.code = "code-123";

            dynamic sub1 = new ChoDynamicObject("sub");
            sub1.AddNamespace("foo1", "http://temp1.com");
            sub1.name = "Tom";
            sub1.address = "101 Main St.";

            item.sub1 = sub1;

            using (var w = new ChoXmlWriter(Console.Out)
                   .ErrorMode(ChoErrorMode.IgnoreAndContinue)
                   .WithXmlNamespace("foo", "http://temp.com")
                   .WithXmlNamespace("foo1", "http://temp.com")
                   )
            {
                w.Write(item);
            }
        }

        public static void AddDifferentNamespaceToSubnode()
        {
            string json = @"
		{
		  'item': {
			'name': 'item #1',
			'code': 'itm-123',
			'image': {
			  '@url': 'http://www.test.com/bar.jpg',
              'title': 'bar'
			}
		  }
		}";
            ChoETLFrxBootstrap.TraceLevel = System.Diagnostics.TraceLevel.Error;

            using (var r = ChoJSONReader.LoadText(json))
            {
                using (var w = new ChoXmlWriter(Console.Out)
                    .IgnoreRootName()
                    .IgnoreNodeName()
                    .WithDefaultXmlNamespace("foo", "http://foo.com")
                    .WithXmlNamespace("temp", "http://temp.com").ErrorMode(ChoErrorMode.IgnoreAndContinue)
                    )
                {
                    w.Write(r.Select(rec =>
                    {
                        rec.item.image.AddNamespace("temp", "http://tem1p.com");
                        return rec;
                    }
                                    )
                           );
                }
            }
        }

        public class Contact
        {
            public string Title { get; set; }
            public string Name { get; set; }
            [ChoXmlArray]
            //[DisplayName("certificateSign")]
            //[XmlArray("Certificate")]
            //[XmlArray]
            //[XmlArrayItem("certificateSign")]
            public Certificate[] certificates { get; set; }
        }

        //[XmlRoot("certificateSign1")]
        public class Certificate
        {
            [XmlText]
            public string certificateSign { get; set; }
        }
        static void Issue197()
        {
            var rec = new Contact
            {
                Name = "Peter",
                certificates = new Certificate[]
                {
                new Certificate
                {
                    certificateSign = "A1"
                },
                new Certificate
                {
                    certificateSign = "A2"
                }
                }
            };

            using (var w = new ChoXmlWriter<Contact>(Console.Out)
                //.UseXmlSerialization()
                .IgnoreRootName()
                )
            {
                w.Write(rec);
            }
        }

        static void Main(string[] args)
        {
            ChoETLFrxBootstrap.TraceLevel = System.Diagnostics.TraceLevel.Error;
            Issue197();
            return;

            AddDifferentNamespaceToSubnode();

            return;

            JSON2XmlDateTimeTest();
            return;
            CustomStringArrayTest();

            using (var file = new FileStream("t.json", FileMode.Append))
            {
                using (var w = new ChoJSONWriter(file))
                {

                }
            }
        }

        [SetUp]
        public void Setup()
        {
            Environment.CurrentDirectory = TestContext.CurrentContext.TestDirectory;
            // Needs to be reset because of some tests changes these settings
            ChoTypeConverterFormatSpec.Instance.Reset();
            ChoXmlSettings.Reset();
        }

        //[Test]
        public static void JSON2XmlDateTimeTest()
        {
            string actual;
            string json = @"{
 ""start"": ""2019-10-24T10:37:27.590Z"",
 ""end"": ""2019-10-24T11:00:00.000Z"",
 ""requests/duration"": {
   ""avg"": 3819.55
 }
}";

            //using (var r = new ChoJSONReader(new StringBuilder(json))
            //    )
            //{
            //    Console.WriteLine(r.First().Dump());
            //}

            actual = ChoJSONWriter.ToText(ChoJSONReader.LoadText(json,
                new ChoJSONRecordConfiguration().Configure(c => c.JsonSerializerSettings = new Newtonsoft.Json.JsonSerializerSettings
                {
                    DateParseHandling = Newtonsoft.Json.DateParseHandling.None
                })).FirstOrDefault()
                );

            Assert.AreEqual(json, actual);
        }
        //[Test]
        public static void CustomStringArrayTest()
        {
            string expected = @"<Root>
  <Days>
    <Monday />
    <Tuesday />
    <Wed />
  </Days>
</Root>";
            string actual = null;

            List<string> s = new List<string>();
            s.Add("Monday");
            s.Add("Tuesday");
            s.Add("Wed");

            StringBuilder sb = new StringBuilder();
            using (var w = new ChoXmlWriter(sb)
                .Configure(c => c.IgnoreNodeName = true)
                .WithField("Days", customSerializer: (v) =>
                {
                    StringBuilder sb1 = new StringBuilder();
                    sb1.AppendLine("<Days>");
                    foreach (var r in (IList)v)
                        sb1.AppendLine("<{0} />".FormatString(r).Indent(2, " "));
                    sb1.Append("</Days>");

                    return sb1.ToString();
                })
                )
                w.Write(new { Days = s });
            actual = sb.ToString();

            Assert.AreEqual(expected, actual);
        }

        //[Test]
        public static void CustomMemberSerialization()
        {
            string expected = @"<Choices>
  <Choice>
    <Emp>
    <Id>0</Id>
    <Name>Raj</Name>
  </Emp>
    <Ids>
    <int>1</int>
    <int>2</int>
    <int>3</int>
  </Ids>
    <EmpArrs>
      <Emp>
    <Id>1</Id>
    <Name>Tom</Name>
  </Emp>
  <Emp>
    <Id>2</Id>
    <Name>Mark</Name>
  </Emp>
  </EmpArrs>
    <Options>op 1,op 2</Options>
  </Choice>
  <Choice>
    <Emp>
    <Id>0</Id>
    <Name>Raj</Name>
  </Emp>
    <Ids>
    <int>1</int>
    <int>2</int>
    <int>3</int>
  </Ids>
    <EmpArrs>
      <Emp>
    <Id>1</Id>
    <Name>Tom</Name>
  </Emp>
  <Emp>
    <Id>2</Id>
    <Name>Mark</Name>
  </Emp>
  </EmpArrs>
    <Options>op 1,op 2</Options>
  </Choice>
</Choices>";
            string actual = null;

            var sb = new StringBuilder();
            using (var p = new ChoXmlWriter<Choice>(sb)
                .WithField("Options", valueConverter: o => String.Join(",", o as string[]))
                //.Configure(c => c.Formatting = System.Xml.Formatting.None)
                )
            {
                List<Choice> l = new List<Choice>
                {
                    new Choice
                {
                    Options = new[] { "op 1", "op 2" },
                    EmpArr = new Emp[] { new Emp { Id = 1, Name = "Tom" }, new Emp { Id = 2, Name = "Mark" }, null },
                    Emp = new Emp {  Id = 0, Name = "Raj"},
                    //EmpDict = new Dictionary<int, Emp> { { 1, new Emp { Id = 11, Name = "Tom1" } } },
                    Ids = new List<int> { 1, 2, 3}
                },
                    new Choice
                {
                    Options = new[] { "op 1", "op 2" },
                    EmpArr = new Emp[] { new Emp { Id = 1, Name = "Tom" }, new Emp { Id = 2, Name = "Mark" }, null },
                    Emp = new Emp {  Id = 0, Name = "Raj"},
                    //EmpDict = new Dictionary<int, Emp> { { 1, new Emp { Id = 11, Name = "Tom1" } } },
                    Ids = new List<int> { 1, 2, 3}
                }
                };
                p.Write(l);
            }
            actual = sb.ToString();

            Console.WriteLine(actual);
            //Assert.AreEqual(expected, actual);
            //Console.WriteLine(ChoXmlWriter.ToText<Choice>(new Choice { Options = new[] { "op 1", "op 2" } }));
        }

        //[Test]
        public static void CustomSerialization()
        {
            string expected = @"<Root>
  <XElement id=""dd"">
    <address>dd</address>
  </XElement>
  <XElement id=""dd"">
    <address>dd</address>
  </XElement>
</Root>";
            string actual = null;

            dynamic address = new ChoDynamicObject();
            address.Street = "10 River Rd";
            address.City = "Princeton";

            dynamic state = new ChoDynamicObject();
            state.State = "NJ";
            state.Zip = "09930";

            address.State = state;

            StringBuilder sb = new StringBuilder();
            using (var w = new ChoXmlWriter(sb)
                .WithXmlAttributeField("id")
                .WithXmlElementField("address")
                .Setup(s => s.RecordFieldWriteError += (o, e) => Console.WriteLine(e.Exception.ToString()))
                .Setup(s => s.RecordFieldSerialize += (o, e) =>
                {
                    e.Source = "dd";
                    //e.Source = "<{0}>DD</{0}>".FormatString(e.PropertyName);
                    //e.Handled = true;
                })
                )
            {
                //w.Write(new KeyValuePair<int, string>(1, "MM"));
                //w.Write(new KeyValuePair<int, string>(1, "MM"));
                w.Write(new { id = "2s->", address = address });
                w.Write(new { id = "1s->", address = address });
            }
            actual = sb.ToString();

            Assert.AreEqual(expected, actual);
        }

        //[Test]
        public static void KVPTest()
        {
            StringBuilder msg = new StringBuilder();
            using (var xr = new ChoXmlWriter(msg)
                .Configure(c => c.NamespaceManager = null)
                .Configure(c => c.NullValueHandling = ChoNullValueHandling.Empty)
                //.Configure(c => c.RootName = "KVP")
                //.Configure(c => c.NodeName = "KeyValue")
                )
            {
                xr.Write((KeyValuePair<string, int>?)null);
                //xr.Write(new KeyValuePair<string, int>("X1", 1));
                xr.Write(1);
                xr.Write(2);
                //xr.Write(new KeyValuePair<string, int>("X2", 2));
            }
            Console.WriteLine(msg.ToString());

            Assert.Fail("Not sure, whats expected");
        }

        //[Test]
        public static void Sample7Test()
        {

            using (var jr = new ChoJSONReader(FileNameSample7JSON).WithJSONPath("$.fathers")
                .WithField("id")
                .WithField("married", fieldType: typeof(bool))
                .WithField("name")
                .WithField("sons")
                )
            {
                using (var w = new ChoXmlWriter(FileNameSample7ActualXML))
                {
                    w.Write(jr);
                }
            }

            FileAssert.AreEqual(FileNameSample7ExpectedXML, FileNameSample7ActualXML);
        }

        //[Test]
        public static void SaveStringList()
        {
            string expected = @"<Root>
  <XElement>1</XElement>
  <XElement>asas</XElement>
  <XElement/>
</Root>";
            string actual = null;

            //List<string> list = new List<string>();
            //list.Add("1/1/2012");
            //list.Add(null);
            ArrayList list = new ArrayList();
            list.Add(1);
            list.Add("asas");
            list.Add(null);

            StringBuilder msg = new StringBuilder();
            using (var w = new ChoXmlWriter(msg)
                )
                w.Write(list);

            actual = msg.ToString();
        }

        //[Test]
        public static void SaveDict()
        {
            string expected = @"<DictionaryEntries>
  <DictionaryEntry>
    <Key>2</Key>
    <Value />
  </DictionaryEntry>
  <DictionaryEntry>
    <Key>1</Key>
    <Value>33</Value>
  </DictionaryEntry>
</DictionaryEntries>";
            string actual = null;

            //Dictionary<int, string> list = new Dictionary<int, string>();
            //list.Add(1, "1/1/2012");
            //list.Add(2, null);
            Hashtable list = new Hashtable();
            list.Add(1, "33");
            list.Add(2, null);

            StringBuilder msg = new StringBuilder();
            using (var w = new ChoXmlWriter(msg)
                )
                w.Write(list);
            actual = msg.ToString();

            Assert.AreEqual(expected, actual);
        }

        //[Test]
        public static void DataTableTest()
        {
            Assert.Fail("Make database testable.");

            string connectionstring = @"Data Source=(localdb)\v11.0;Initial Catalog=TestDb;Integrated Security=True";
            using (var conn = new SqlConnection(connectionstring))
            {
                conn.Open();
                var comm = new SqlCommand("SELECT * FROM Customers", conn);
                SqlDataAdapter adap = new SqlDataAdapter(comm);

                DataTable dt = new DataTable("Customer");
                adap.Fill(dt);

                using (var parser = new ChoXmlWriter("customers.xml").WithXPath("Customers/Customer").Configure(c => c.XmlRecordFieldConfigurations.Add(new ChoXmlRecordFieldConfiguration("CustId") { IsXmlAttribute = true })))
                    parser.Write(dt);
            }
        }

        //[Test]
        public static void DataReaderTest()
        {
            Assert.Fail("Make database testable.");

            string connectionstring = @"Data Source=(localdb)\v11.0;Initial Catalog=TestDb;Integrated Security=True";
            using (var conn = new SqlConnection(connectionstring))
            {
                conn.Open();
                var comm = new SqlCommand("SELECT * FROM Customers", conn);
                using (var parser = new ChoXmlWriter("customers.xml").WithXPath("Customers/Customer"))
                    parser.Write(comm.ExecuteReader());
            }
        }

        //[Test]
        public static void ConfigFirstTest()
        {
            string expected = @"<Employees>
  <Employee>
    <Id>1</Id>
    <Name>Mark</Name>
  </Employee>
  <Employee>
    <Id>2</Id>
    <Name />
  </Employee>
</Employees>";
            string actual = null;

            List<ExpandoObject> objs = new List<ExpandoObject>();
            dynamic rec1 = new ExpandoObject();
            rec1.Id = 1;
            rec1.Name = "Mark";
            rec1.IsActive = true;
            rec1.Message = new ChoCDATA("Test");
            objs.Add(rec1);

            dynamic rec2 = new ExpandoObject();
            rec2.Id = 2;
            rec2.Name = null;
            rec2.IsActive = true;
            rec2.Message = new ChoCDATA("Test");
            objs.Add(rec2);

            ChoXmlRecordConfiguration config = new ChoXmlRecordConfiguration();
            config.XmlRecordFieldConfigurations.Add(new ChoXmlRecordFieldConfiguration("Id"));
            config.XmlRecordFieldConfigurations.Add(new ChoXmlRecordFieldConfiguration("Name"));

            using (var stream = new MemoryStream())
            using (var reader = new StreamReader(stream))
            using (var writer = new StreamWriter(stream))
            using (var parser = new ChoXmlWriter(writer, config).WithXPath("Employees/Employee"))
            {
                parser.Write(objs);

                writer.Flush();
                stream.Position = 0;

                actual = reader.ReadToEnd();
            }

            Assert.AreEqual(expected, actual);
        }
        public static string FileNameQuickPOCOTestActualXML => "QuickPOCOTestActual.xml";
        public static string FileNameQuickPOCOTestExpectedXML => "QuickPOCOTestExpected.xml";
        public static string FileNameSample7JSON => "sample7.json";
        public static string FileNameSample7ExpectedXML => "sample7Expected.xml";
        public static string FileNameSample7ActualXML => "sample7Actual.xml";
        //[Test]
        public static void QuickPOCOTest()
        {
            List<EmployeeRecSimple> objs = new List<EmployeeRecSimple>();

            EmployeeRecSimple rec1 = new EmployeeRecSimple();
            rec1.Id = null;
            rec1.Name = "Mark";
            rec1.Depends = new List<string>() { "AA", "BB" };
            rec1.Courses = new Dictionary<int, string>() { { 1, "AA" }, { 2, "BB" } };
            objs.Add(rec1);

            EmployeeRecSimple rec2 = new EmployeeRecSimple();
            rec2.Id = "2";
            rec2.Name = null;
            objs.Add(rec2);
            objs.Add(null);

            using (var parser = new ChoXmlWriter<EmployeeRecSimple>(FileNameQuickPOCOTestActualXML).WithXPath("Employees/Employee")
                .Configure(e => e.NullValueHandling = ChoNullValueHandling.Default)
                )
            {
                parser.Write(objs);
            }

            FileAssert.AreEqual(FileNameQuickPOCOTestExpectedXML, FileNameQuickPOCOTestActualXML);
            //        using (var reader = new ChoXmlReader("emp.xml").WithXPath("Employees/Employee")
            //.WithField("Id")
            //.WithField("Name")
            //.WithField("Depends", isArray: false, fieldType: typeof(List<string>))
            //.WithField("KVP", isArray: false, fieldType: typeof(List<ChoKeyValuePair<int, string>>))
            //)
            //        {
            //            foreach (var i in reader)
            //                Console.WriteLine(ChoUtility.ToStringEx(i));
            //        }

            //using (var reader = new ChoXmlReader<EmployeeRecSimple>("emp.xml").WithXPath("Employees/Employee"))
            //{
            //    foreach (var i in reader)
            //        Console.WriteLine(ChoUtility.ToStringEx(i));
            //}
        }

        //[Test]
        public static void QuickDynamicTest()
        {
            string expected = @"<Employees>
  <Employee>
    <Id>1</Id>
    <Name>Mark</Name>
    <IsActive>true</IsActive>
    <Message><![CDATA//[Test]]></Message>
    <Array>
    <anyType xmlns:q1=""http://www.w3.org/2001/XMLSchema"" p3:type=""q1:int"" xmlns:p3=""http://www.w3.org/2001/XMLSchema-instance"">1</anyType>
    <anyType xmlns:q2=""http://www.w3.org/2001/XMLSchema"" p3:type=""q2:string"" xmlns:p3=""http://www.w3.org/2001/XMLSchema-instance"">abc</anyType>
  </Array>
    <Lint>
    <int>1</int>
    <int>2</int>
  </Lint>
    <Dict>
    <item>
      <key>
        <int>1</int>
      </key>
      <value>
        <string>abc</string>
      </value>
    </item>
  </Dict>
  </Employee>
  <Employee>
    <Id>2</Id>
    <Name>Jason</Name>
    <IsActive>true</IsActive>
    <Message><![CDATA//[Test]]></Message>
  </Employee>
</Employees>";
            string actual = null;

            ArrayList al = new ArrayList();
            al.Add(1);
            al.Add("abc");

            List<int> lint = new List<int>() { 1, 2 };

            Hashtable ht = new Hashtable();
            ht.Add(1, "abc");

            ChoSerializableDictionary<int, string> dict = new ChoSerializableDictionary<int, string>();
            dict.Add(1, "abc");

            List<ExpandoObject> objs = new List<ExpandoObject>();
            dynamic rec1 = new ExpandoObject();
            rec1.Id = 1;
            rec1.Name = "Mark";
            rec1.IsActive = true;
            rec1.Message = new ChoCDATA("Test");
            rec1.Array = al;
            rec1.Lint = lint;
            //rec1.HT = ht;
            rec1.Dict = dict;
            objs.Add(rec1);

            dynamic rec2 = new ExpandoObject();
            rec2.Id = 2;
            rec2.Name = "Jason";
            rec2.IsActive = true;
            rec2.Message = new ChoCDATA("Test");
            objs.Add(rec2);

            StringBuilder sb = new StringBuilder();
            using (var parser = new ChoXmlWriter(sb).WithXPath("Employees/Employee"))
            {
                parser.Write(objs);
            }
            actual = sb.ToString();

            Assert.AreEqual(expected, actual);

            //var a = ChoXmlReader.LoadText(sb.ToString()).ToArray();
            //var config = new ChoXmlRecordConfiguration();
            ////config.Configure(c => c.RootName = "Root");
            //Console.WriteLine(ChoXmlWriter.ToText(a.First(), config));
        }

        public partial class EmployeeRecSimple1
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }

        public partial class EmployeeRecSimple
        {
            [ChoXmlAttributeRecordField]
            public string Id { get; set; }
            [ChoXmlElementRecordField]
            public string Name { get; set; }
            [ChoXmlElementRecordField]
            public List<string> Depends { get; set; }

            [ChoXmlElementRecordField]
            public List<ChoKeyValuePair<int, string>> KVP
            {
                get { return Courses?.Select(kvp => new ChoKeyValuePair<int, string>(kvp)).ToList(); }
                set { Courses = value != null ? value.ToDictionary(v => v.Key, v => v.Value) : new Dictionary<int, string>(); }
            }
            [ChoIgnoreMember]
            public Dictionary<int, string> Courses { get; set; }
        }
    }
}


text:
package org.geogit.storage;

import static com.tinkerpop.blueprints.Direction.BOTH;
import static com.tinkerpop.blueprints.Direction.IN;
import static com.tinkerpop.blueprints.Direction.OUT;

import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.geogit.api.ObjectId;
import org.geogit.api.Platform;
import org.geogit.api.plumbing.ResolveGeogitDir;

import com.google.common.base.Optional;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import com.tinkerpop.blueprints.CloseableIterable;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Graph;
import com.tinkerpop.blueprints.KeyIndexableGraph;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.gremlin.java.GremlinPipeline;
import com.tinkerpop.pipes.PipeFunction;
import com.tinkerpop.pipes.branch.LoopPipe.LoopBundle;

/**
 * An abstract implementation of {@link GraphDatabase} on top of the <a
 * href="https://github.com/tinkerpop/blueprints/">blueprints</a> {@link IndexableGraph graph API}.
 *
 * @param <DB>
 */
public abstract class BlueprintsGraphDatabase<DB extends KeyIndexableGraph> implements GraphDatabase {

    protected DB graphDB = null;

    protected String dbPath;

    protected static Map<String, ServiceContainer<?>> databaseServices = new ConcurrentHashMap<String, ServiceContainer<?>>();

    protected final Platform platform;

    private Vertex root;

    protected enum CommitRelationshipTypes {
        TOROOT, PARENT, MAPPED_TO
    }

    /**
     * Container class for the database service to keep track of reference counts.
     */
    static protected class ServiceContainer<DB extends Graph> {
        private DB dbService;

        private int refCount;

        public ServiceContainer(DB dbService) {
            this.dbService = dbService;
            this.refCount = 0;
        }

        public void removeRef() {
            this.refCount--;
        }

        public void addRef() {
            this.refCount++;
        }

        public int getRefCount() {
            return this.refCount;
        }

        public DB getService() {
            return this.dbService;
        }
    }

    static {
        // Registers a shutdown hook for the Neo4j instance so that it
        // shuts down nicely when the VM exits (even if you "Ctrl-C" the
        // running example before it's completed)
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                for (Entry<String, ServiceContainer<?>> entry : databaseServices.entrySet()) {
                    File graphPath = new File(entry.getKey());
                    if (graphPath.exists()) {
                        entry.getValue().getService().shutdown();
                    }
                }
                databaseServices.clear();
            }
        });
    }

    public BlueprintsGraphDatabase(Platform platform) {
        this.platform = platform;
    }

    /**
     * Opens the Neo4J graph database.
     */
    @Override
    public void open() {
        if (isOpen()) {
            return;
        }

        URL envHome = new ResolveGeogitDir(platform).call();
        if (envHome == null) {
            throw new IllegalStateException("Not inside a geogit directory");
        }
        if (!"file".equals(envHome.getProtocol())) {
            throw new UnsupportedOperationException(
                    "This Graph Database works only against file system repositories. "
                            + "Repository location: " + envHome.toExternalForm());
        }
        File repoDir;
        try {
            repoDir = new File(envHome.toURI());
        } catch (URISyntaxException e) {
            throw Throwables.propagate(e);
        }
        File graph = new File(repoDir, "graph");
        if (!graph.exists() && !graph.mkdir()) {
            throw new IllegalStateException("Cannot create graph directory '"
                    + graph.getAbsolutePath() + "'");
        }

        dbPath = graph.getAbsolutePath() + "/graphDB.db";

        if (databaseServices.containsKey(dbPath)) {
            @SuppressWarnings("unchecked")
            ServiceContainer<DB> serviceContainer = (ServiceContainer<DB>) databaseServices
                    .get(dbPath);
            serviceContainer.addRef();
            graphDB = serviceContainer.getService();
        } else {
            graphDB = getGraphDatabase();
            ServiceContainer<DB> newContainer = new ServiceContainer<DB>(graphDB);
            newContainer.addRef();
            databaseServices.put(dbPath, newContainer);
        }

        if (!graphDB.getIndexedKeys(Vertex.class).contains("identifier")) {
            graphDB.createKeyIndex("identifiers", Vertex.class);
        }
        Iterable<Vertex> results = graphDB.getVertices("identifier", "root");
        try {
            Iterator<Vertex> iter = results.iterator();
            if (iter.hasNext()) {
                root = iter.next();
                this.rollback();
            } else {
                root = graphDB.addVertex(null);
                root.setProperty("identifier", "root");
                this.commit();
            }
        } catch (Exception e) {
            this.rollback();
            throw Throwables.propagate(e);
        }
    }

    /**
     * Constructs the graph database service.
     *
     * @return the new {@link IndexableGraph}
     */
    protected abstract DB getGraphDatabase();

    /**
     * Destroy the graph database service. This will only happen when the ref count for the database
     * service is 0.
     */
    protected void destroyGraphDatabase() {
        File graphPath = new File(dbPath);
        if (graphPath.exists()) {
            graphDB.shutdown();
        }
        databaseServices.remove(dbPath);
    }

    /**
     * @return true if the database is open, false otherwise
     */
    @Override
    public boolean isOpen() {
        return graphDB != null;
    }

    /**
     * Closes the database.
     */
    @Override
    public void close() {
        if (isOpen()) {
            @SuppressWarnings("unchecked")
            ServiceContainer<DB> container = (ServiceContainer<DB>) databaseServices.get(dbPath);
            container.removeRef();
            if (container.getRefCount() <= 0) {
                destroyGraphDatabase();
                databaseServices.remove(dbPath);
            }
            graphDB = null;
        }
    }

    /**
     * Determines if the given commit exists in the graph database.
     *
     * @param commitId the commit id to search for
     * @return true if the commit exists, false otherwise
     */
    @Override
    public boolean exists(ObjectId commitId) {
        try {
            Iterable<Vertex> results = graphDB.getVertices("identifier", commitId.toString());
            Iterator<Vertex> iterator = results.iterator();
            if (iterator.hasNext()) {
                iterator.next();
                return true;
            } else {
                return false;
            }
        } finally {
            this.rollback();
        }
    }

    /**
     * Retrieves all of the parents for the given commit.
     *
     * @param commitid the commit whose parents should be returned
     * @return a list of the parents of the provided commit
     * @throws IllegalArgumentException
     */
    @Override
    public ImmutableList<ObjectId> getParents(ObjectId commitId) throws IllegalArgumentException {
        try {
            Vertex node = null;
            Iterable<Vertex> results = graphDB.getVertices("identifier", commitId.toString());
            Iterator<Vertex> iterator = results.iterator();
            if (iterator.hasNext()) {
                node = iterator.next();
            }

            Builder<ObjectId> listBuilder = new ImmutableList.Builder<ObjectId>();

            if (node != null) {
                for (Edge edge : node.getEdges(OUT, CommitRelationshipTypes.PARENT.name())) {
                    Vertex parentNode = edge.getVertex(IN);
                    listBuilder
                            .add(ObjectId.valueOf(parentNode.<String> getProperty("identifier")));
                }
            }
            return listBuilder.build();
        } finally {
            this.rollback();
        }
    }

    /**
     * Retrieves all of the children for the given commit.
     *
     * @param commitid the commit whose children should be returned
     * @return a list of the children of the provided commit
     * @throws IllegalArgumentException
     */
    @Override
    public ImmutableList<ObjectId> getChildren(ObjectId commitId) throws IllegalArgumentException {
        try {
            Iterable<Vertex> results = graphDB.getVertices("identifier", commitId.toString());
            Vertex node = null;
            Iterator<Vertex> iterator = results.iterator();
            if (iterator.hasNext()) {
                node = iterator.next();
            }

            Builder<ObjectId> listBuilder = new ImmutableList.Builder<ObjectId>();

            if (node != null) {
                for (Edge child : node.getEdges(IN, CommitRelationshipTypes.PARENT.name())) {
                    Vertex childNode = child.getVertex(OUT);
                    listBuilder.add(ObjectId.valueOf(childNode.<String> getProperty("identifier")));
                }
            }
            return listBuilder.build();
        } finally {
            this.rollback();
        }
    }

    /**
     * Adds a commit to the database with the given parents. If a commit with the same id already
     * exists, it will not be inserted.
     *
     * @param commitId the commit id to insert
     * @param parentIds the commit ids of the commit's parents
     * @return true if the commit id was inserted, false otherwise
     */
    @Override
    public boolean put(ObjectId commitId, ImmutableList<ObjectId> parentIds) {
        boolean updated = false;
        try {
            // See if it already exists
            Vertex commitNode = getOrAddNode(commitId);

            if (parentIds.isEmpty()) {
                if (!commitNode.getEdges(OUT, CommitRelationshipTypes.TOROOT.name()).iterator()
                        .hasNext()) {
                    // Attach this node to the root node
                    commitNode.addEdge(CommitRelationshipTypes.TOROOT.name(), root);
                    updated = true;
                }
            }

            if (!commitNode.getEdges(OUT, CommitRelationshipTypes.PARENT.name()).iterator()
                    .hasNext()) {
                // Don't make relationships if they have been created already
                for (ObjectId parent : parentIds) {
                    Vertex parentNode = getOrAddNode(parent);
                    commitNode.addEdge(CommitRelationshipTypes.PARENT.name(), parentNode);
                    updated = true;
                }
            }
            this.commit();
        } catch (Exception e) {
            this.rollback();
            throw Throwables.propagate(e);
        }
        return updated;
    }

    /**
     * Maps a commit to another original commit. This is used in sparse repositories.
     *
     * @param mapped the id of the mapped commit
     * @param original the commit to map to
     */
    @Override
    public void map(final ObjectId mapped, final ObjectId original) {
        Vertex commitNode = null;
        try {
            // See if it already exists
            commitNode = getOrAddNode(mapped);

            Iterator<Edge> mappedTo = commitNode.getEdges(OUT,
                    CommitRelationshipTypes.MAPPED_TO.name()).iterator();
            if (mappedTo.hasNext()) {
                // Remove old mapping
                Edge toRemove = mappedTo.next();
                graphDB.removeEdge(toRemove);
            }

            // Don't make relationships if they have been created already
            Vertex originalNode = getOrAddNode(original);
            commitNode.addEdge(CommitRelationshipTypes.MAPPED_TO.name(), originalNode);
            this.commit();
        } catch (Exception e) {
            this.rollback();
            throw Throwables.propagate(e);
        }
    }

    /**
     * Gets the id of the commit that this commit is mapped to.
     *
     * @param commitId the commit to find the mapping of
     * @return the mapped commit id
     */
    public ObjectId getMapping(final ObjectId commitId) {
        try {
            Vertex node = null;
            Iterable<Vertex> results = graphDB.getVertices("identifier", commitId.toString());
            node = results.iterator().next();

            ObjectId mapped = ObjectId.NULL;
            Vertex mappedNode = getMappedNode(node);
            if (mappedNode != null) {
                mapped = ObjectId.valueOf(mappedNode.<String> getProperty("identifier"));
            }
            return mapped;
        } finally {
            this.rollback();
        }
    }

    private Vertex getMappedNode(final Vertex commitNode) {
        if (commitNode != null) {
            Iterable<Edge> mappings = commitNode.getEdges(OUT,
                    CommitRelationshipTypes.MAPPED_TO.name());
            if (mappings.iterator().hasNext()) {
                return mappings.iterator().next().getVertex(IN);
            }
        }
        return null;
    }

    /**
     * Gets a node or adds it if it doesn't exist
     *
     * @param commitId
     * @return
     */
    private Vertex getOrAddNode(ObjectId commitId) {
        final String commitIdStr = commitId.toString();
        Iterable<Vertex> matches = graphDB.getVertices("identifier", commitIdStr);
        Iterator<Vertex> iterator = matches.iterator();
        if (iterator.hasNext()) {
            return iterator.next();
        } else {
            Vertex v = graphDB.addVertex(null);
            v.setProperty("identifier", commitIdStr);
            return v;
        }
    }

    /**
     * Gets the number of ancestors of the commit until it reaches one with no parents, for example
     * the root or an orphaned commit.
     *
     * @param commitId the commit id to start from
     * @return the depth of the commit
     */
    @Override
    public int getDepth(final ObjectId commitId) {
        try {
            Vertex commitNode = null;
            Iterable<Vertex> results = graphDB.getVertices("identifier", commitId.toString());
            commitNode = results.iterator().next();
            PipeFunction<LoopBundle<Vertex>, Boolean> expandCriterion = new PipeFunction<LoopBundle<Vertex>, Boolean>() {
                @Override
                public Boolean compute(LoopBundle<Vertex> argument) {
                    Iterable<Edge> edges = argument.getObject().getEdges(OUT,
                            CommitRelationshipTypes.PARENT.name());
                    return edges.iterator().hasNext();
                }
            };
            PipeFunction<LoopBundle<Vertex>, Boolean> emitCriterion = new PipeFunction<LoopBundle<Vertex>, Boolean>() {
                @Override
                public Boolean compute(LoopBundle<Vertex> argument) {
                    Iterable<Edge> edges = argument.getObject().getEdges(OUT,
                            CommitRelationshipTypes.PARENT.name());
                    return !edges.iterator().hasNext();
                }
            };
            @SuppressWarnings("rawtypes")
            PipeFunction<List, List<Edge>> verticesOnly = new PipeFunction<List, List<Edge>>() {
                @Override
                public List<Edge> compute(List argument) {
                    List<Edge> results = new ArrayList<Edge>();
                    for (Object o : argument) {
                        if (o instanceof Edge) {
                            results.add((Edge) o);
                        }
                    }
                    return results;
                }
            };
            GremlinPipeline<Vertex, List<Edge>> pipe = new GremlinPipeline<Vertex, Vertex>()
                    .start(commitNode).as("start").outE(CommitRelationshipTypes.PARENT.name())
                    .inV().loop("start", expandCriterion, emitCriterion).path()
                    .transform(verticesOnly);

            if (pipe.hasNext()) {
                int length = Integer.MAX_VALUE;
                for (List<?> path : pipe) {
                    length = Math.min(length, path.size());
                }
                return length;
            } else {
                return 0;
            }
        } finally {
            this.rollback();
        }
    }

    /**
     * Determines if there are any sparse commits between the start commit and the end commit, not
     * including the end commit.
     *
     * @param start the start commit
     * @param end the end commit
     * @return true if there are any sparse commits between start and end
     */
    public boolean isSparsePath(final ObjectId start, final ObjectId end) {
        try {
            Vertex startNode = null;
            Vertex endNode = null;
            Iterable<Vertex> startResults = graphDB.getVertices("identifier", start.toString());
            startNode = startResults.iterator().next();
            Iterable<Vertex> endResults = graphDB.getVertices("identifier", end.toString());
            endNode = endResults.iterator().next();

            PipeFunction<LoopBundle<Vertex>, Boolean> whileFunction = new PipeFunction<LoopBundle<Vertex>, Boolean>() {
                @Override
                public Boolean compute(LoopBundle<Vertex> argument) {
                    return !argument.getObject().getProperty("identifier").equals(end.toString());
                }
            };

            PipeFunction<LoopBundle<Vertex>, Boolean> emitFunction = new PipeFunction<LoopBundle<Vertex>, Boolean>() {
                @Override
                public Boolean compute(LoopBundle<Vertex> argument) {
                    return argument.getObject().getProperty("identifier").equals(end.toString());
                }
            };

            @SuppressWarnings("rawtypes")
            GremlinPipeline<Vertex, List> pipe = new GremlinPipeline<Vertex, Vertex>()
                    .start(startNode).as("start").outE(CommitRelationshipTypes.PARENT.name()).inV()
                    .loop("start", whileFunction, emitFunction).path();

            for (List<?> path : pipe) {
                for (Object o : path) {
                    if (o instanceof Vertex) {
                        Vertex vertex = (Vertex) o;
                        if (!vertex.equals(endNode)
                                && vertex.getPropertyKeys().contains(SPARSE_FLAG)) {
                            return true;
                        }
                    }
                }
            }

            return false;
        } finally {
            this.rollback();
        }
    }

    /**
     * Set a property on the provided commit node.
     *
     * @param commitId the id of the commit
     */
    public void setProperty(ObjectId commitId, String propertyName, String propertyValue) {
        try {
            Iterable<Vertex> results = graphDB.getVertices("identifier", commitId.toString());
            Vertex commitNode = results.iterator().next();
            commitNode.setProperty(propertyName, propertyValue);
            this.commit();
        } catch (Exception e) {
            this.rollback();
        }
    }

    /**
     * Finds the lowest common ancestor of two commits.
     *
     * @param leftId the commit id of the left commit
     * @param rightId the commit id of the right commit
     * @return An {@link Optional} of the lowest common ancestor of the two commits, or
     *         {@link Optional#absent()} if a common ancestor could not be found.
     */
    @Override
    public Optional<ObjectId> findLowestCommonAncestor(ObjectId leftId, ObjectId rightId) {
        try {
            Set<Vertex> leftSet = new HashSet<Vertex>();
            Set<Vertex> rightSet = new HashSet<Vertex>();

            Queue<Vertex> leftQueue = new LinkedList<Vertex>();
            Queue<Vertex> rightQueue = new LinkedList<Vertex>();

            Vertex leftNode;
            Vertex rightNode;
            Iterable<Vertex> leftResults = graphDB.getVertices("identifier", leftId.toString());
            leftNode = leftResults.iterator().next();
            if (!leftNode.getEdges(OUT).iterator().hasNext()) {
                return Optional.absent();
            }
            leftQueue.add(leftNode);
            Iterable<Vertex> rightResults = graphDB.getVertices("identifier", rightId.toString());
            rightNode = rightResults.iterator().next();
            if (!rightNode.getEdges(OUT).iterator().hasNext()) {
                return Optional.absent();
            }
            rightQueue.add(rightNode);

            List<Vertex> potentialCommonAncestors = new LinkedList<Vertex>();
            while (!leftQueue.isEmpty() || !rightQueue.isEmpty()) {
                if (!leftQueue.isEmpty()) {
                    Vertex commit = leftQueue.poll();
                    if (processCommit(commit, leftQueue, leftSet, rightQueue, rightSet)) {
                        potentialCommonAncestors.add(commit);
                    }
                }
                if (!rightQueue.isEmpty()) {
                    Vertex commit = rightQueue.poll();
                    if (processCommit(commit, rightQueue, rightSet, leftQueue, leftSet)) {
                        potentialCommonAncestors.add(commit);
                    }
                }
            }
            verifyAncestors(potentialCommonAncestors, leftSet, rightSet);

            Optional<ObjectId> ancestor = Optional.absent();
            if (potentialCommonAncestors.size() > 0) {
                ancestor = Optional.of(ObjectId.valueOf((String) potentialCommonAncestors.get(0)
                        .getProperty("identifier")));
            }
            return ancestor;
        } finally {
            this.rollback();
        }
    }

    private boolean processCommit(Vertex commit, Queue<Vertex> myQueue, Set<Vertex> mySet,
            Queue<Vertex> theirQueue, Set<Vertex> theirSet) {
        if (!mySet.contains(commit)) {
            mySet.add(commit);
            if (theirSet.contains(commit)) {
                stopAncestryPath(commit, theirQueue, theirSet);
                return true;
            }
            for (Edge parentEdge : commit.getEdges(OUT, CommitRelationshipTypes.PARENT.name())) {
                Vertex parent = parentEdge.getVertex(IN);
                if (parent.getEdges(OUT).iterator().hasNext()) {
                    myQueue.add(parent);
                }
            }
        }
        return false;

    }

    private void stopAncestryPath(Vertex commit, Queue<Vertex> theirQueue, Set<Vertex> theirSet) {
        Queue<Vertex> ancestorQueue = new LinkedList<Vertex>();
        ancestorQueue.add(commit);
        List<Vertex> processed = new LinkedList<Vertex>();
        while (!ancestorQueue.isEmpty()) {
            Vertex ancestor = ancestorQueue.poll();
            for (Edge parent : ancestor.getEdges(BOTH, CommitRelationshipTypes.PARENT.name())) {
                Vertex parentNode = parent.getVertex(IN);
                if (!parentNode.getId().equals(ancestor.getId())) {
                    if (theirSet.contains(parentNode)) {
                        ancestorQueue.add(parentNode);
                        processed.add(parentNode);
                    }
                } else if (theirQueue.contains(parentNode)) {
                    theirQueue.remove(parentNode);
                }
            }
        }
    }

    private void verifyAncestors(List<Vertex> potentialCommonAncestors, Set<Vertex> leftSet,
            Set<Vertex> rightSet) {
        Queue<Vertex> ancestorQueue = new LinkedList<Vertex>();
        List<Vertex> falseAncestors = new LinkedList<Vertex>();
        List<Vertex> processed = new LinkedList<Vertex>();

        for (Vertex v : potentialCommonAncestors) {
            if (falseAncestors.contains(v)) {
                continue;
            }
            ancestorQueue.add(v);
            while (!ancestorQueue.isEmpty()) {
                Vertex ancestor = ancestorQueue.poll();
                for (Edge parent : ancestor.getEdges(OUT, CommitRelationshipTypes.PARENT.name())) {
                    Vertex parentNode = parent.getVertex(IN);
                    if (parentNode.getId() != ancestor.getId()) {
                        if (leftSet.contains(parentNode) || rightSet.contains(parentNode)) {
                            if (!processed.contains(parentNode)) {
                                ancestorQueue.add(parentNode);
                                processed.add(parentNode);
                            }
                            if (potentialCommonAncestors.contains(parentNode)) {
                                falseAncestors.add(parentNode);
                            }
                        }
                    }
                }
            }
        }
        potentialCommonAncestors.removeAll(falseAncestors);
    }

    @Override
    public void truncate() {
        try {
            Iterator<Edge> edges = graphDB.getEdges().iterator();
            while (edges.hasNext()) {
                graphDB.removeEdge(edges.next());
            }
            Iterator<Vertex> vertices = graphDB.getVertices().iterator();
            while (vertices.hasNext()) {
                graphDB.removeVertex(vertices.next());
            }
            this.commit();
        } catch (RuntimeException e) {
            this.rollback();
            throw e;
        }
    }

    /**
     * Template method for transactional graph db's to override and implement the commit action
     */
    protected void commit() {
        // Stub for transactional graphdb to use
    }

    /**
     * Template method for transactional graph db's to override and implement the rollback action
     */
    protected void rollback() {
        // Stub for transactional graphdb to use
    }
}


text:
#ifndef __OMAP_PCM_H__
#define __OMAP_PCM_H__

struct omap_pcm_dma_data {
	char		*name;		/* stream identifier */
	int		dma_req;	/* DMA request line */
	unsigned long	port_addr;	/* transmit/receive register */
	int		sync_mode;	/* DMA sync mode */
	void (*set_threshold)(struct snd_pcm_substream *substream);
};

extern struct snd_soc_platform omap_soc_platform;

#endif


text:
package com.twitterclient.helpers;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class SharedPrefHelper {

    /**
     * Function to get all the saved preferences
     * @param context
     * @return
     */
    public List<String> getAll(Context context) {

        SharedPreferences sharedPreferences = getSharedPreferences(context);
        Map<String,String> draftsMap = (Map<String, String>) sharedPreferences.getAll();
        List<String> drafts = new ArrayList<>(draftsMap.values());
        if(drafts!=null && !drafts.isEmpty()) {
            Log.d("DEBUG", drafts.get(0));
        }

        return drafts;
    }

    /**
     * Function returns the SharedPreferences
     * @return
     */
    public static SharedPreferences getSharedPreferences(Context context) {
        return context.getSharedPreferences("Drafts", Context.MODE_PRIVATE);
    }

}