text:
from __future__ import annotations

from contextlib import contextmanager
from typing import (
    TYPE_CHECKING,
    Generator,
)

from pandas.plotting._core import _get_plot_backend

if TYPE_CHECKING:
    from matplotlib.axes import Axes
    from matplotlib.figure import Figure
    import numpy as np

    from pandas import (
        DataFrame,
        Series,
    )

def table(ax, data, **kwargs):
    """
    Helper function to convert DataFrame and Series to matplotlib.table.

    Parameters
    ----------
    ax : Matplotlib axes object
    data : DataFrame or Series
        Data for table contents.
    **kwargs
        Keyword arguments to be passed to matplotlib.table.table.
        If `rowLabels` or `colLabels` is not specified, data index or column
        name will be used.

    Returns
    -------
    matplotlib table object
    """
    plot_backend = _get_plot_backend("matplotlib")
    return plot_backend.table(
        ax=ax, data=data, rowLabels=None, colLabels=None, **kwargs
    )

def register() -> None:
    """
    Register pandas formatters and converters with matplotlib.

    This function modifies the global ``matplotlib.units.registry``
    dictionary. pandas adds custom converters for

    * pd.Timestamp
    * pd.Period
    * np.datetime64
    * datetime.datetime
    * datetime.date
    * datetime.time

    See Also
    --------
    deregister_matplotlib_converters : Remove pandas formatters and converters.
    """
    plot_backend = _get_plot_backend("matplotlib")
    plot_backend.register()

def deregister() -> None:
    """
    Remove pandas formatters and converters.

    Removes the custom converters added by :func:`register`. This
    attempts to set the state of the registry back to the state before
    pandas registered its own units. Converters for pandas' own types like
    Timestamp and Period are removed completely. Converters for types
    pandas overwrites, like ``datetime.datetime``, are restored to their
    original value.

    See Also
    --------
    register_matplotlib_converters : Register pandas formatters and converters
        with matplotlib.
    """
    plot_backend = _get_plot_backend("matplotlib")
    plot_backend.deregister()

def scatter_matrix(
    frame: DataFrame,
    alpha: float = 0.5,
    figsize: tuple[float, float] | None = None,
    ax: Axes | None = None,
    grid: bool = False,
    diagonal: str = "hist",
    marker: str = ".",
    density_kwds=None,
    hist_kwds=None,
    range_padding: float = 0.05,
    **kwargs,
) -> np.ndarray:
    """
    Draw a matrix of scatter plots.

    Parameters
    ----------
    frame : DataFrame
    alpha : float, optional
        Amount of transparency applied.
    figsize : (float,float), optional
        A tuple (width, height) in inches.
    ax : Matplotlib axis object, optional
    grid : bool, optional
        Setting this to True will show the grid.
    diagonal : {'hist', 'kde'}
        Pick between 'kde' and 'hist' for either Kernel Density Estimation or
        Histogram plot in the diagonal.
    marker : str, optional
        Matplotlib marker type, default '.'.
    density_kwds : keywords
        Keyword arguments to be passed to kernel density estimate plot.
    hist_kwds : keywords
        Keyword arguments to be passed to hist function.
    range_padding : float, default 0.05
        Relative extension of axis range in x and y with respect to
        (x_max - x_min) or (y_max - y_min).
    **kwargs
        Keyword arguments to be passed to scatter function.

    Returns
    -------
    numpy.ndarray
        A matrix of scatter plots.

    Examples
    --------

    .. plot::
        :context: close-figs

        >>> df = pd.DataFrame(np.random.randn(1000, 4), columns=['A','B','C','D'])
        >>> pd.plotting.scatter_matrix(df, alpha=0.2)
        array([[<AxesSubplot: xlabel='A', ylabel='A'>,
            <AxesSubplot: xlabel='B', ylabel='A'>,
            <AxesSubplot: xlabel='C', ylabel='A'>,
            <AxesSubplot: xlabel='D', ylabel='A'>],
           [<AxesSubplot: xlabel='A', ylabel='B'>,
            <AxesSubplot: xlabel='B', ylabel='B'>,
            <AxesSubplot: xlabel='C', ylabel='B'>,
            <AxesSubplot: xlabel='D', ylabel='B'>],
           [<AxesSubplot: xlabel='A', ylabel='C'>,
            <AxesSubplot: xlabel='B', ylabel='C'>,
            <AxesSubplot: xlabel='C', ylabel='C'>,
            <AxesSubplot: xlabel='D', ylabel='C'>],
           [<AxesSubplot: xlabel='A', ylabel='D'>,
            <AxesSubplot: xlabel='B', ylabel='D'>,
            <AxesSubplot: xlabel='C', ylabel='D'>,
            <AxesSubplot: xlabel='D', ylabel='D'>]], dtype=object)
    """
    plot_backend = _get_plot_backend("matplotlib")
    return plot_backend.scatter_matrix(
        frame=frame,
        alpha=alpha,
        figsize=figsize,
        ax=ax,
        grid=grid,
        diagonal=diagonal,
        marker=marker,
        density_kwds=density_kwds,
        hist_kwds=hist_kwds,
        range_padding=range_padding,
        **kwargs,
    )

def radviz(
    frame: DataFrame,
    class_column: str,
    ax: Axes | None = None,
    color: list[str] | tuple[str, ...] | None = None,
    colormap=None,
    **kwds,
) -> Axes:
    """
    Plot a multidimensional dataset in 2D.

    Each Series in the DataFrame is represented as a evenly distributed
    slice on a circle. Each data point is rendered in the circle according to
    the value on each Series. Highly correlated `Series` in the `DataFrame`
    are placed closer on the unit circle.

    RadViz allow to project a N-dimensional data set into a 2D space where the
    influence of each dimension can be interpreted as a balance between the
    influence of all dimensions.

    More info available at the `original article
    <https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.135.889>`_
    describing RadViz.

    Parameters
    ----------
    frame : `DataFrame`
        Object holding the data.
    class_column : str
        Column name containing the name of the data point category.
    ax : :class:`matplotlib.axes.Axes`, optional
        A plot instance to which to add the information.
    color : list[str] or tuple[str], optional
        Assign a color to each category. Example: ['blue', 'green'].
    colormap : str or :class:`matplotlib.colors.Colormap`, default None
        Colormap to select colors from. If string, load colormap with that
        name from matplotlib.
    **kwds
        Options to pass to matplotlib scatter plotting method.

    Returns
    -------
    class:`matplotlib.axes.Axes`

    See Also
    --------
    plotting.andrews_curves : Plot clustering visualization.

    Examples
    --------

    .. plot::
        :context: close-figs

        >>> df = pd.DataFrame(
        ...     {
        ...         'SepalLength': [6.5, 7.7, 5.1, 5.8, 7.6, 5.0, 5.4, 4.6, 6.7, 4.6],
        ...         'SepalWidth': [3.0, 3.8, 3.8, 2.7, 3.0, 2.3, 3.0, 3.2, 3.3, 3.6],
        ...         'PetalLength': [5.5, 6.7, 1.9, 5.1, 6.6, 3.3, 4.5, 1.4, 5.7, 1.0],
        ...         'PetalWidth': [1.8, 2.2, 0.4, 1.9, 2.1, 1.0, 1.5, 0.2, 2.1, 0.2],
        ...         'Category': [
        ...             'virginica',
        ...             'virginica',
        ...             'setosa',
        ...             'virginica',
        ...             'virginica',
        ...             'versicolor',
        ...             'versicolor',
        ...             'setosa',
        ...             'virginica',
        ...             'setosa'
        ...         ]
        ...     }
        ... )
        >>> pd.plotting.radviz(df, 'Category')
        <AxesSubplot: xlabel='y(t)', ylabel='y(t + 1)'>
    """
    plot_backend = _get_plot_backend("matplotlib")
    return plot_backend.radviz(
        frame=frame,
        class_column=class_column,
        ax=ax,
        color=color,
        colormap=colormap,
        **kwds,
    )

def andrews_curves(
    frame: DataFrame,
    class_column: str,
    ax: Axes | None = None,
    samples: int = 200,
    color: list[str] | tuple[str, ...] | None = None,
    colormap=None,
    **kwargs,
) -> Axes:
    """
    Generate a matplotlib plot for visualising clusters of multivariate data.

    Andrews curves have the functional form:

    f(t) = x_1/sqrt(2) + x_2 sin(t) + x_3 cos(t) +
           x_4 sin(2t) + x_5 cos(2t) + ...

    Where x coefficients correspond to the values of each dimension and t is
    linearly spaced between -pi and +pi. Each row of frame then corresponds to
    a single curve.

    Parameters
    ----------
    frame : DataFrame
        Data to be plotted, preferably normalized to (0.0, 1.0).
    class_column : label
        Name of the column containing class names.
    ax : axes object, default None
        Axes to use.
    samples : int
        Number of points to plot in each curve.
    color : str, list[str] or tuple[str], optional
        Colors to use for the different classes. Colors can be strings
        or 3-element floating point RBG values.
    colormap : str or matplotlib colormap object, default None
        Colormap to select colors from. If a string, load colormap with that
        name from matplotlib.
    **kwargs
        Options to pass to matplotlib plotting method.

    Returns
    -------
    class:`matplotlip.axis.Axes`

    Examples
    --------

    .. plot::
        :context: close-figs

        >>> df = pd.read_csv(
        ...     'https://raw.github.com/pandas-dev/'
        ...     'pandas/main/pandas/tests/io/data/csv/iris.csv'
        ... )
        >>> pd.plotting.andrews_curves(df, 'Name')
        <AxesSubplot: title={'center': 'width'}>
    """
    plot_backend = _get_plot_backend("matplotlib")
    return plot_backend.andrews_curves(
        frame=frame,
        class_column=class_column,
        ax=ax,
        samples=samples,
        color=color,
        colormap=colormap,
        **kwargs,
    )

def bootstrap_plot(
    series: Series,
    fig: Figure | None = None,
    size: int = 50,
    samples: int = 500,
    **kwds,
) -> Figure:
    """
    Bootstrap plot on mean, median and mid-range statistics.

    The bootstrap plot is used to estimate the uncertainty of a statistic
    by relying on random sampling with replacement [1]_. This function will
    generate bootstrapping plots for mean, median and mid-range statistics
    for the given number of samples of the given size.

    .. [1] "Bootstrapping (statistics)" in \
    https://en.wikipedia.org/wiki/Bootstrapping_%28statistics%29

    Parameters
    ----------
    series : pandas.Series
        Series from where to get the samplings for the bootstrapping.
    fig : matplotlib.figure.Figure, default None
        If given, it will use the `fig` reference for plotting instead of
        creating a new one with default parameters.
    size : int, default 50
        Number of data points to consider during each sampling. It must be
        less than or equal to the length of the `series`.
    samples : int, default 500
        Number of times the bootstrap procedure is performed.
    **kwds
        Options to pass to matplotlib plotting method.

    Returns
    -------
    matplotlib.figure.Figure
        Matplotlib figure.

    See Also
    --------
    DataFrame.plot : Basic plotting for DataFrame objects.
    Series.plot : Basic plotting for Series objects.

    Examples
    --------
    This example draws a basic bootstrap plot for a Series.

    .. plot::
        :context: close-figs

        >>> s = pd.Series(np.random.uniform(size=100))
        >>> pd.plotting.bootstrap_plot(s)
        <Figure size 640x480 with 6 Axes>
    """
    plot_backend = _get_plot_backend("matplotlib")
    return plot_backend.bootstrap_plot(
        series=series, fig=fig, size=size, samples=samples, **kwds
    )

def parallel_coordinates(
    frame: DataFrame,
    class_column: str,
    cols: list[str] | None = None,
    ax: Axes | None = None,
    color: list[str] | tuple[str, ...] | None = None,
    use_columns: bool = False,
    xticks: list | tuple | None = None,
    colormap=None,
    axvlines: bool = True,
    axvlines_kwds=None,
    sort_labels: bool = False,
    **kwargs,
) -> Axes:
    """
    Parallel coordinates plotting.

    Parameters
    ----------
    frame : DataFrame
    class_column : str
        Column name containing class names.
    cols : list, optional
        A list of column names to use.
    ax : matplotlib.axis, optional
        Matplotlib axis object.
    color : list or tuple, optional
        Colors to use for the different classes.
    use_columns : bool, optional
        If true, columns will be used as xticks.
    xticks : list or tuple, optional
        A list of values to use for xticks.
    colormap : str or matplotlib colormap, default None
        Colormap to use for line colors.
    axvlines : bool, optional
        If true, vertical lines will be added at each xtick.
    axvlines_kwds : keywords, optional
        Options to be passed to axvline method for vertical lines.
    sort_labels : bool, default False
        Sort class_column labels, useful when assigning colors.
    **kwargs
        Options to pass to matplotlib plotting method.

    Returns
    -------
    matplotlib.axis.Axes

    Examples
    --------

    .. plot::
        :context: close-figs

        >>> df = pd.read_csv(
        ...     'https://raw.github.com/pandas-dev/'
        ...     'pandas/main/pandas/tests/io/data/csv/iris.csv'
        ... )
        >>> pd.plotting.parallel_coordinates(
        ...     df, 'Name', color=('#556270', '#4ECDC4', '#C7F464')
        ... )
        <AxesSubplot: xlabel='y(t)', ylabel='y(t + 1)'>
    """
    plot_backend = _get_plot_backend("matplotlib")
    return plot_backend.parallel_coordinates(
        frame=frame,
        class_column=class_column,
        cols=cols,
        ax=ax,
        color=color,
        use_columns=use_columns,
        xticks=xticks,
        colormap=colormap,
        axvlines=axvlines,
        axvlines_kwds=axvlines_kwds,
        sort_labels=sort_labels,
        **kwargs,
    )

def lag_plot(series: Series, lag: int = 1, ax: Axes | None = None, **kwds) -> Axes:
    """
    Lag plot for time series.

    Parameters
    ----------
    series : Series
        The time series to visualize.
    lag : int, default 1
        Lag length of the scatter plot.
    ax : Matplotlib axis object, optional
        The matplotlib axis object to use.
    **kwds
        Matplotlib scatter method keyword arguments.

    Returns
    -------
    matplotlib.axis.Axes

    Examples
    --------
    Lag plots are most commonly used to look for patterns in time series data.

    Given the following time series

    .. plot::
        :context: close-figs

        >>> np.random.seed(5)
        >>> x = np.cumsum(np.random.normal(loc=1, scale=5, size=50))
        >>> s = pd.Series(x)
        >>> s.plot()
        <AxesSubplot: xlabel='Midrange'>

    A lag plot with ``lag=1`` returns

    .. plot::
        :context: close-figs

        >>> pd.plotting.lag_plot(s, lag=1)
        <AxesSubplot: xlabel='y(t)', ylabel='y(t + 1)'>
    """
    plot_backend = _get_plot_backend("matplotlib")
    return plot_backend.lag_plot(series=series, lag=lag, ax=ax, **kwds)

def autocorrelation_plot(series: Series, ax: Axes | None = None, **kwargs) -> Axes:
    """
    Autocorrelation plot for time series.

    Parameters
    ----------
    series : Series
        The time series to visualize.
    ax : Matplotlib axis object, optional
        The matplotlib axis object to use.
    **kwargs
        Options to pass to matplotlib plotting method.

    Returns
    -------
    matplotlib.axis.Axes

    Examples
    --------
    The horizontal lines in the plot correspond to 95% and 99% confidence bands.

    The dashed line is 99% confidence band.

    .. plot::
        :context: close-figs

        >>> spacing = np.linspace(-9 * np.pi, 9 * np.pi, num=1000)
        >>> s = pd.Series(0.7 * np.random.rand(1000) + 0.3 * np.sin(spacing))
        >>> pd.plotting.autocorrelation_plot(s)
        <AxesSubplot: title={'center': 'width'}, xlabel='Lag', ylabel='Autocorrelation'>
    """
    plot_backend = _get_plot_backend("matplotlib")
    return plot_backend.autocorrelation_plot(series=series, ax=ax, **kwargs)

class _Options(dict):
    """
    Stores pandas plotting options.

    Allows for parameter aliasing so you can just use parameter names that are
    the same as the plot function parameters, but is stored in a canonical
    format that makes it easy to breakdown into groups later.
    """

    # alias so the names are same as plotting method parameter names
    _ALIASES = {"x_compat": "xaxis.compat"}
    _DEFAULT_KEYS = ["xaxis.compat"]

    def __init__(self, deprecated: bool = False) -> None:
        self._deprecated = deprecated
        super().__setitem__("xaxis.compat", False)

    def __getitem__(self, key):
        key = self._get_canonical_key(key)
        if key not in self:
            raise ValueError(f"{key} is not a valid pandas plotting option")
        return super().__getitem__(key)

    def __setitem__(self, key, value) -> None:
        key = self._get_canonical_key(key)
        super().__setitem__(key, value)

    def __delitem__(self, key) -> None:
        key = self._get_canonical_key(key)
        if key in self._DEFAULT_KEYS:
            raise ValueError(f"Cannot remove default parameter {key}")
        super().__delitem__(key)

    def __contains__(self, key) -> bool:
        key = self._get_canonical_key(key)
        return super().__contains__(key)

    def reset(self) -> None:
        """
        Reset the option store to its initial state

        Returns
        -------
        None
        """
        # error: Cannot access "__init__" directly
        self.__init__()  # type: ignore[misc]

    def _get_canonical_key(self, key):
        return self._ALIASES.get(key, key)

    @contextmanager
    def use(self, key, value) -> Generator[_Options, None, None]:
        """
        Temporarily set a parameter value using the with statement.
        Aliasing allowed.
        """
        old_value = self[key]
        try:
            self[key] = value
            yield self
        finally:
            self[key] = old_value

plot_params = _Options()


text:
package org.springframework.scheduling.annotation;

import java.lang.reflect.Method;
import java.util.concurrent.Executor;

import org.springframework.aop.interceptor.AsyncExecutionInterceptor;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.core.annotation.AnnotatedElementUtils;

/**
 * Specialization of {@link AsyncExecutionInterceptor} that delegates method execution to
 * an {@code Executor} based on the {@link Async} annotation. Specifically designed to
 * support use of {@link Async#value()} executor qualification mechanism introduced in
 * Spring 3.1.2. Supports detecting qualifier metadata via {@code @Async} at the method or
 * declaring class level. See {@link #getExecutorQualifier(Method)} for details.
 *
 * @author Chris Beams
 * @author Stephane Nicoll
 * @since 3.1.2
 * @see org.springframework.scheduling.annotation.Async
 * @see org.springframework.scheduling.annotation.AsyncAnnotationAdvisor
 */
public class AnnotationAsyncExecutionInterceptor extends AsyncExecutionInterceptor {

	/**
	 * Create a new {@code AnnotationAsyncExecutionInterceptor} with the given executor
	 * and a simple {@link AsyncUncaughtExceptionHandler}.
	 * @param defaultExecutor the executor to be used by default if no more specific
	 * executor has been qualified at the method level using {@link Async#value()};
	 * as of 4.2.6, a local executor for this interceptor will be built otherwise
	 */
	public AnnotationAsyncExecutionInterceptor(Executor defaultExecutor) {
		super(defaultExecutor);
	}

	/**
	 * Create a new {@code AnnotationAsyncExecutionInterceptor} with the given executor.
	 * @param defaultExecutor the executor to be used by default if no more specific
	 * executor has been qualified at the method level using {@link Async#value()};
	 * as of 4.2.6, a local executor for this interceptor will be built otherwise
	 * @param exceptionHandler the {@link AsyncUncaughtExceptionHandler} to use to
	 * handle exceptions thrown by asynchronous method executions with {@code void}
	 * return type
	 */
	public AnnotationAsyncExecutionInterceptor(Executor defaultExecutor, AsyncUncaughtExceptionHandler exceptionHandler) {
		super(defaultExecutor, exceptionHandler);
	}

	/**
	 * Return the qualifier or bean name of the executor to be used when executing the
	 * given method, specified via {@link Async#value} at the method or declaring
	 * class level. If {@code @Async} is specified at both the method and class level, the
	 * method's {@code #value} takes precedence (even if empty string, indicating that
	 * the default executor should be used preferentially).
	 * @param method the method to inspect for executor qualifier metadata
	 * @return the qualifier if specified, otherwise empty string indicating that the
	 * {@linkplain #setExecutor(Executor) default executor} should be used
	 * @see #determineAsyncExecutor(Method)
	 */
	@Override
	protected String getExecutorQualifier(Method method) {
		// Maintainer's note: changes made here should also be made in
		// AnnotationAsyncExecutionAspect#getExecutorQualifier
		Async async = AnnotatedElementUtils.findMergedAnnotation(method, Async.class);
		if (async == null) {
			async = AnnotatedElementUtils.findMergedAnnotation(method.getDeclaringClass(), Async.class);
		}
		return (async != null ? async.value() : null);
	}

}

redpajama_set_name: RedPajamaGithub


text:
<Product>
<ProductName>some string</ProductName>
<UnitPrice>123</UnitPrice>
<SupplierID>123</SupplierID>
<Discontinued>true</Discontinued>
</Product>


text:
from __future__ import unicode_literals

from django.db import migrations

class Migration(migrations.Migration):

    dependencies = [("app2", "1_auto")]


text:
<!DOCTYPE html>

	<link rel="apple-touch-icon" sizes="57x57" href="icons/apple-icon-57x57.png">
    <link rel="apple-touch-icon" sizes="60x60" href="icons/apple-icon-60x60.png">
    <link rel="apple-touch-icon" sizes="72x72" href="icons/apple-icon-72x72.png">
    <link rel="apple-touch-icon" sizes="76x76" href="icons/apple-icon-76x76.png">
    <link rel="apple-touch-icon" sizes="114x114" href="icons/apple-icon-114x114.png">
    <link rel="apple-touch-icon" sizes="120x120" href="icons/apple-icon-120x120.png">
    <link rel="apple-touch-icon" sizes="144x144" href="icons/apple-icon-144x144.png">
    <link rel="apple-touch-icon" sizes="152x152" href="icons/apple-icon-152x152.png">
    <link rel="apple-touch-icon" sizes="180x180" href="icons/apple-icon-180x180.png">
    <link rel="icon" type="image/png" sizes="192x192"  href="icons/android-icon-192x192.png">
    <link rel="icon" type="image/png" sizes="32x32" href="icons/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="96x96" href="icons/favicon-96x96.png">
    <link rel="icon" type="image/png" sizes="16x16" href="icons/favicon-16x16.png">
    <link rel="manifest" href="/manifest.json">
    <meta name="msapplication-TileColor" content="#ffffff">
    <meta name="msapplication-TileImage" content="icons/ms-icon-144x144.png">
    <meta name="theme-color" content="#ffffff">
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Symfony Users</title>

    <link href="css/bootstrap.min.css" rel="stylesheet">

    <link href="css/clean-blog.min.css" rel="stylesheet">

    <link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet" type="text/css">
    <link href='http://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
    <link href='http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>

    <link href = "css/bootstrap-markdown.min.css" rel="stylesheet">

    <link href="css/prism.css" rel="stylesheet">

                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
                    Toggle navigation

                </button>
                Blog

                        Inicio

                        Acerca

                        Contacto

La forma correcta

de crear usuarios

en symfony

                        Posted by Pablo Díaz on July 15,2015

El User Bundle

La mayoría de sistemas web necesitan un sistema de autenticación, registro y perfil de usuarios. En esta ocasión quiero compartir una forma de hacerlo fácil y reutilizable para otros proyectos en symfony. Este material está dirigido a personas que ya posean un poco de conocimiento básico de cómo funciona symfony.

Una vez ya tengan instalado symfony y composer, iniciamos con el proyecto.

1. Crear el proyecto

                            symfony new proyecto 2.7

2. Instalar Friend of Symfony

                            composer require friendsofsymfony/user-bundle

3. Crear el UserBundle

                            php app/console generate:bundle

Ahora habilitamos el bundle en el AppKernel.php

                          4. Habilitar el Bundle

                         En caso de que salga el problema "Warning: date_default_timezone_get()"

     public function __construct($environment, $debug)

 {

  date_default_timezone_set('America/Guatemala');

  parent::__construct($environment, $debug);

 }

5. Configurar los parámetros

 En parameters.yml

 En config.yml

6. Crear clase Usuario y configurarla

 Primero creamos la clase con: php app/console doctrine:generate:entity

 Escogemos formato yml y creamos un campo de nombre desde el generador de symfony.

 Ahora importamos los siguientes bundles en src/UsuarioBundle/Entity/Usuario.php

 Se hereda de la clase BaseUser de FriendOfSymfony, se define el nombre de tabla (Usuarios) y se utiliza Assert para validar el campo de nombre

Observación: el atributo id tiene que ser obligatoriamente protected

El generador de entidades se encargará de colocar los métodos SET y GET de los atributos.

  					Pueden encontrar el código en github.

7. Configurar la ruta de seguridad en app/config/security.yml

security:
    providers:
        fos_userbundle:
            id: fos_user.user_provider.username

    encoders:
        FOS\UserBundle\Model\UserInterface: sha512

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt|error)|css|images|js)/
            security: false
        main:
            pattern: ^/
            form_login:
                provider: fos_userbundle
                csrf_provider: form.csrf_provider
            logout:       true
            anonymous:    true
    access_control:
        - { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/, roles: ROLE_USER }

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: ROLE_ADMIN

8. Registrar las rutas definidas de symfony

#Colocar esto en src/UserBundle/Resources/config/routing.yml
fos_user_security:
    resource: "@FOSUserBundle/Resources/config/routing/security.xml"

fos_user_profile:
    resource: "@FOSUserBundle/Resources/config/routing/profile.xml"
    prefix: /profile

fos_user_register:
    resource: "@FOSUserBundle/Resources/config/routing/registration.xml"
    prefix: /register

fos_user_resetting:
    resource: "@FOSUserBundle/Resources/config/routing/resetting.xml"
    prefix: /resetting

fos_user_change_password:
    resource: "@FOSUserBundle/Resources/config/routing/change_password.xml"
    prefix: /profile

#En app/config/routing.yml tendremos esta ruta, de esta forma las rutas se encuentran dentro del bundle y se vuelve portable
user:
    resource: "@UserBundle/Resources/config/routing.yml"
    prefix:   /

10. Definir la ruta principal del proyecto

Modificamos el archivo DefaultController.php en src/AppBundle/DefaultController para definir la página principal del proyecto

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DefaultController extends Controller
{
    /**
     * @Route("/", name="homepage")
     */
    public function indexAction()
    {
        return $this->render('UserBundle:Default:index.html.twig');
    }
}

Nótese que sigue un patrón definido Bundle:Controller:Action, esto le permite al Routing hallar el controlador especificado, automáticamente Routing resuelve la ubicación del Bundle, el controlador y la acción, sin necesidad de definir los sufijos "Controller" y "Action" correspondientes al controlador y acción. El archivo index.html.twig lo pueden encontrar en el repositorio de github.

11. La primera prueba

Ahora corremos el servidor con: php app/console server:run

En la dirección http://localhost:8000/login nos muestra la interfaz de autenticación

12.1 Incluir css, javascript, fonts y demás archivos estáticos

Lo más fácil para crear una página web decente es utilizar una plantilla por parte de getBooststrap

Una vez definida una plantilla bootstrap, primero incluimos los archivos estáticos en la dirección proyecto/web

12.2 Primero se define el layout.

Para importar los javascript, css, imágenes y demás archivos se pueden importar de la siguiente forma

Ahora la parte más importante del layout.html.twig es definir el espacio donde se pondrán los formularios

El archivo debería estar ubicado en src/UserBundle/Resource/views.

A continuación tienen un ejemplo de como se puede poner. Cualquier elemento encerrado en {} es lenguaje de twig.

div style = "color: #ffffff">
            {% if is_granted("IS_AUTHENTICATED_REMEMBERED") %}
                {{ 'layout.logged_in_as'|trans({'%username%': app.user.username}, 'FOSUserBundle') }} |

                    {{ 'layout.logout'|trans({}, 'FOSUserBundle') }}

            {% else %}

            {% endif %}
        /div>

        {% for type, messages in app.session.flashBag.all %}
            {% for message in messages %}

                    {{ message|trans({}, 'FOSUserBundle') }}

            {% endfor %}
        {% endfor %}

    {% block fos_user_content %}
    {% endblock fos_user_content %}

Entre los elemento de fos_user_content se pondrán todos los formularios.

12.3 Ahora el archivo login.html.twig.

Ahora hay que modificar el archivo login ubicado en src/UserBundle/Resource/views/Security

Debido a que layout es nuestra base tenemos que heredar sus atributos para poder utilizarlos.

Luego básicamente solo hay que modificar el archivo, dejando los elementos importantes que ya tiene el archivo original de FOSUserBundle hasta que quede como se quiere.

13. Override a los formularios.

Primero hay que realizar un paso que faltaba y se puede hacer después de crear la clase Usuario

Es necesario sincronizar la base de datos con el siguiente comando: php app/console doctrine:schema:update --dump-sql (para asegurarse que se crean los campos deseados) y después php app/console doctrine:schema:update --force

Ahora toca realizar la parte de registrar nuevos usuarios, pero para realizar hay que modificar los formularios originales de friend of symfony porque agregamos nuevos campos.

Creamos el archivo RegistrationFormType.php en UserBundle/Form/Type

Primero hay que heredar el formulario de fos y agregar campos nuevos.

Ahora modificamos el archivo en src/UserBundle/Resources/config/services.yml

Por último modificamos el archivo config.yml ubicado en app

 De esta forma el formulario queda con la cantidad de campos deseados pero todavía falta modificar el archivo register_content.html.twig

Esto puede ser un poco tedioso pero que se mire mejor visualmente, lo mejor es colocar campo por campo en el html

Primero se define donde inicia  y termina el formulario en register_content.html.twig con las siguientes instrucciones.

                    {{form_start(form)}}
                    {{form_end(form)}}

Ahora agregamos columna por columna y definimos la clase y el placeholder.

Se puede tener control sobre casi todo, para saber más, recomiendo revisar la documentación oficial de symfony sobre formularios.

{{form_row(form.nombreCompleto,{'attr': {'class': 'form-control','placeholder':'Nombre Completo'}})}}

Finalmente así queda el formulario

14. Ahora se desea modificar el correo de confirmación.

Por defecto friend of symfony enviará un correo de confirmación en texto plano.

Debido a que nuestro sistema será utilizado se desea que tenga un estilo agradable a la vista y para eso es necesario enviar el correo en formato HTML.

Entonces, primero es necesario crear un formato de html para enviar el correo, una vez se tenga todo ya visualmente agradble, lo incluimos en nuestro proyecto de symfony.

Como se desean incluir imágenes en nuestro nuevo archivo html, tendremos que modificar el default Mailer de FOS. Para eso copiamos el archivo de friendofsymfony Mailer/TwigSwiftMailer y lo copiamos en UserBundle/Mailer/CustomTwigSwiftMailer.

Lo modificamos hasta que quede como el siguiente ejemplo.

/*
 * This file is part of the FOSUserBundle package.
 *
 * (c) FriendsOfSymfony http://friendsofsymfony.github.com
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace UserBundle\Mailer;

use FOS\UserBundle\Model\UserInterface;
use FOS\UserBundle\Mailer\TwigSwiftMailer as BaseMailer;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use FOS\UserBundle\Mailer\MailerInterface;

/**
 *
 * Form overriden by  @author Pablo diaz <dia13203@uvg.edu.gt>
 * @author Christophe Coevoet <stof@notk.org>
 */
class CustomTwigSwiftMailer implements MailerInterface
{
    protected $mailer;
    protected $router;
    protected $twig;
    protected $parameters;

    public function __construct(\Swift_Mailer $mailer, UrlGeneratorInterface $router, \Twig_Environment $twig, array $parameters)
    {
        $this->mailer = $mailer;
        $this->router = $router;
        $this->twig = $twig;
        $this->parameters = $parameters;
    }

    public function sendConfirmationEmailMessage(UserInterface $user)
    {
        $template = $this->parameters['template']['confirmation'];
        $url = $this->router->generate('fos_user_registration_confirm', array('token' => $user->getConfirmationToken()), true);
        $context = array(
            'user' => $user,
            'confirmationUrl' => $url
        );

        $this->sendMessage($template, $context, $this->parameters['from_email']['confirmation'], $user->getEmail());
    }

    public function sendResettingEmailMessage(UserInterface $user)
    {
        $template = $this->parameters['template']['resetting'];
        $url = $this->router->generate('fos_user_resetting_reset', array('token' => $user->getConfirmationToken()), true);
        $context = array(
            'user' => $user,
            'confirmationUrl' => $url
        );
        $this->sendMessage($template, $context, $this->parameters['from_email']['resetting'], $user->getEmail());
    }

    /**
     * @param string $templateName
     * @param array  $context
     * @param string $fromEmail
     * @param string $toEmail
     */
    protected function sendMessage($templateName, $context, $fromEmail, $toEmail)
    {
        //new instance
        $message = \Swift_Message::newInstance();
        $context = $this->twig->mergeGlobals($context);//merge context
        $template = $this->twig->loadTemplate($templateName);
        //espacio para agregar imágenes
        $context['image_src'] = $message->embed(\Swift_Image::fromPath('images/email_header.png'));//attach image 1
        $context['fb_image'] = $message->embed(\Swift_Image::fromPath('images/fb.gif'));//attach image 2
        $context['tw_image'] = $message->embed(\Swift_Image::fromPath('images/tw.gif'));//attach image 3
        $context['right_image'] = $message->embed(\Swift_Image::fromPath('images/right.gif'));//attach image 4
        $context['left_image'] = $message->embed(\Swift_Image::fromPath('images/left.gif'));//attach image 5
        $subject = $template->renderBlock('subject', $context);
        $textBody = $template->renderBlock('body_text', $context);
        $htmlBody = $template->renderBlock('body_html', $context);

        $message
            ->setSubject($subject)
            ->setFrom($fromEmail)
            ->setTo($toEmail);

        if (!empty($htmlBody)) {
            $message->setBody($htmlBody, 'text/html')
                ->addPart($textBody, 'text/plain');
        } else {
            $message->setBody($textBody);
        }

        $this->mailer->send($message);
    }
}

Ahora es necesario crear un archivo llamado registration.email.twig en UserBundle/Resources/views de la siguiente forma

{% block subject %}
{% autoescape false %}
{{ 'registration.email.subject'|trans({'%username%': user.username, '%confirmationUrl%': confirmationUrl}, 'FOSUserBundle') }}
{% endautoescape %}
{% endblock %}

{% block body_html %}
{% include 'UserBundle:Registration:email.html.twig' %}
{% endblock %}

La primera parte de este archivo sirve para definir el sujeto del email y la segunda parte para el cuerpo del mensaje

Ahora creamos el archivo email.html.twig en el mismo lugar y colocamos la plantilla html creada anteriormente

En esta plantilla la parte importante será la siguiente:

{% block body_text %}
{% autoescape 'html' %}

Hola {{user.nombreCompleto}}!

 Para completar la validación de tu cuenta - por favor visita el siguiente Link de Activación

Atentamente,

el Equipo.

{% endautoescape %}
{% endblock %}

Para adjuntar imágenes

#el nombre depende a lo definido en el custom mailer.

Ahora es necesario agregar el custom mailer al proyecto.

Primero agregándolo como servicio en UserBundle/Resources/config/services.yml

services:
    user_bundle.registration.form.type:
        class: UserBundle\Form\Type\RegistrationFormType
        tags:
            - { name: form.type, alias: user_registration}
    fos_mail.custom_mailer:
        class: UserBundle\Mailer\CustomTwigSwiftMailer
        public: false
        arguments:
            - '@mailer'
            - '@router'
            - '@twig'
            - template:
                confirmation: %fos_user.registration.confirmation.template%
                resetting: %fos_user.resetting.email.template%
              from_email:
                confirmation: %fos_user.registration.confirmation.from_email%
                resetting: %fos_user.resetting.email.from_email%

Ahora lo agregamos en el config.yml

fos_user:
    db_driver: orm
    firewall_name: main
    user_class: UserBundle\Entity\Usuario
    service:
        mailer: fos_mail.custom_mailer
    registration:
        form:
            type:  user_registration
        confirmation:
            enabled:    true # change to true for required email confirmation
            template:   UserBundle:Registration:registration.email.twig

Finalmente, queda de la siguiente forma

15. Recapitulando

Hasta el momento ya tenemos el inicio de sesión y el registro de usuarios con confirmación al correo

Ahora lo que sigue es la recuperación de la contraseña con correo en HTML

Primero el link para la recuperación de la contraseña debería ser hacia {{ path('fos_user_resetting_request') }}

El segundo paso es configurar el config.yml

  resetting:
        token_ttl: 86400
        email:
            from_email:
                address:        noreply@elearn.com
                sender_name:    In- Learn Platform
            template:   UserBundle:Resetting:resetting.email.twig
        form:
            type:               fos_user_resetting

Ahora es necesario configurar el correo a para la recuperación

Como se puede notar se ha definido el archivo resetting.email.twig ubicado en UserBundle/Resources/Resetting/views como plantilla de envío.

Este archivo es muy parecido al de registration.email.twig

Ahora en el archivo ubicado en UserBundle/Resources/Resetting/views crean el archivo reset.html.twig para mandar el correo de recuperación de contraseña

Al igual que el correo de registro, la parte importante de esta plantilla es la siguiente:

Please enable JavaScript to view the comments powered by Disqus.

Copyright © fcpauldiaz 2015 Powered by Bootstrap

dia13203@uvg.edu.gt


text:
package com.granveaud.mysql2h2converter.sql;

public class NullValue implements Value {
    @Override
    public String toString() {
        return "NULL";
    }
}


text:
<?xml version="1.0" encoding="UTF-8"?>
<!--
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
-->
<pluto-portal-driver xmlns="http://portals.apache.org/pluto/xsd/pluto-portal-driver-config.xsd" xmlns:pa="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://portals.apache.org/pluto/xsd/pluto-portal-driver-config.xsd                         http://portals.apache.org/pluto/pluto-portal/1.1/pluto-portal-driver-config.xsd" version="1.1">
<portal-name>pluto-portal-driver</portal-name>
<portal-version>${project.version}</portal-version>
<container-name>Pluto Portal Driver</container-name>
<supports>
<portlet-mode>view</portlet-mode>
<portlet-mode>edit</portlet-mode>
<portlet-mode>help</portlet-mode>
<portlet-mode>config</portlet-mode>
<window-state>normal</window-state>
<window-state>maximized</window-state>
<window-state>minimized</window-state>
</supports>
<render-config default="About Apache Pluto">
<page xmlns="" name="V3AnnotationPortletArtifactValidityTests" uri="/WEB-INF/themes/pluto-default-theme.jsp">
<portlet context="/${project.artifactId}-${project.version}" name="AnnotationPortletArtifactValidityTests_SPEC3_20_RequestArtifacts"/>
<portlet context="/${project.artifactId}-${project.version}" name="AnnotationPortletArtifactValidityTests_SPEC3_20_ResponseArtifacts"/>
<portlet context="/${project.artifactId}-${project.version}" name="AnnotationPortletArtifactValidityTests_SPEC3_20_ParameterArtifacts"/>
<portlet context="/${project.artifactId}-${project.version}" name="AnnotationPortletArtifactValidityTests_SPEC3_20_PortletArtifacts"/>
</page>
</render-config>
</pluto-portal-driver>


text:
using Test
using PETSc, MPI
using ForwardDiff, SparseArrays
MPI.Initialized() || MPI.Init()

@testset "DMStagCreate1d" begin

    comm = MPI.COMM_WORLD
    mpirank = MPI.Comm_rank(comm)
    mpisize = MPI.Comm_size(comm)
    for petsclib in PETSc.petsclibs
        PETSc.initialize(petsclib)
        PetscScalar = PETSc.scalartype(petsclib)
        PetscInt    = PETSc.inttype(petsclib)

        # Create 1D DMStag
        dm = PETSc.DMStagCreate1d(
                petsclib,
                comm,
                PETSc.DM_BOUNDARY_PERIODIC,
                20,
                2,
                2,
                PETSc.DMSTAG_STENCIL_BOX,
                2)
        @test PETSc.DMStagGetBoundaryTypes(dm)==PETSc.DM_BOUNDARY_PERIODIC
        PETSc.destroy(dm)

        # Create 1D DMStag with array of local @ of points
        dm = PETSc.DMStagCreate1d(petsclib,comm,PETSc.DM_BOUNDARY_NONE,20,2,2,PETSc.DMSTAG_STENCIL_BOX,2,[20])

        # Test get size
        @test PETSc.DMStagGetGlobalSizes(dm) == 20
        @test PETSc.DMStagGetLocalSizes(dm) == 20

        # Test
        @test PETSc.gettype(dm) == "stag"
        @test PETSc.getdimension(dm) == 1

        # Info about ranks
        @test PETSc.DMStagGetIsFirstRank(dm) == (true,false,false)
        @test PETSc.DMStagGetIsLastRank(dm) == (true,false,false)

        # Boundary
        @test PETSc.DMStagGetBoundaryTypes(dm)==PETSc.DM_BOUNDARY_NONE

        # Corners
        corners         = PETSc.getcorners(dm)
        ghost_corners   = PETSc.getghostcorners(dm)

        @test corners.lower[1] == 1
        @test corners.upper[1] == 20
        @test corners.size[1]  == 20
        @test corners.extra[1] == 1

        @test ghost_corners.lower[1] == 1
        @test ghost_corners.upper[1] == 21
        @test ghost_corners.size[1]  == 21
        @test ghost_corners.extra[1]  == 0

        # DOF
        @test PETSc.DMStagGetDOF(dm) == (2,2)
        PETSc.destroy(dm)

        # Create new struct and pass keyword arguments
        dm_1D = PETSc.DMStagCreate1d(petsclib,comm,PETSc.DM_BOUNDARY_NONE,200,2,2; stag_grid_x=10);
        @test PETSc.DMStagGetGlobalSizes(dm_1D) == 10
        @test PETSc.DMStagGetEntriesPerElement(dm_1D)==4

        # Stencil width & type
        @test  PETSc.DMStagGetStencilWidth(dm_1D)==2
        @test  PETSc.DMStagGetBoundaryTypes(dm_1D) == PETSc.DM_BOUNDARY_NONE

        PETSc.destroy(dm_1D)

        # test ghosted array set using keywords
        dm_ghosted = PETSc.DMStagCreate1d(petsclib,comm,PETSc.DM_BOUNDARY_GHOSTED,200,2,2; stag_grid_x=10);
        @test  PETSc.DMStagGetStencilWidth(dm_ghosted)==2
        corners         = PETSc.getcorners(dm_ghosted)

        @test corners.size[1]==10       # keyword overrides the specified value
        @test  PETSc.DMStagGetBoundaryTypes(dm_ghosted) == PETSc.DM_BOUNDARY_GHOSTED

        ind = PETSc.DMStagGetIndices(dm_ghosted);
        @test ind.center.x[3] == 5

        # simple test to retrieve the KSP object
        # NOTE: need to implement a similar SNES routine
        ksp = PETSc.KSP(dm_ghosted)
        @test PETSc.gettype(ksp)=="gmres"

        PETSc.destroy(dm_ghosted)

        PETSc.finalize(petsclib)
    end
end

@testset "DMStagCreate2d" begin

    comm = MPI.COMM_WORLD
    mpirank = MPI.Comm_rank(comm)
    mpisize = MPI.Comm_size(comm)
    for petsclib in PETSc.petsclibs
        PETSc.initialize(petsclib)
        PetscScalar = PETSc.scalartype(petsclib)
        PetscInt    = PETSc.inttype(petsclib)

        # Create 2D DMStag
        dm_2D = PETSc.DMStagCreate2d(petsclib, comm,
                PETSc.DM_BOUNDARY_NONE,
                PETSc.DM_BOUNDARY_NONE,
                20,
                21,
                1,
                1,
                1,
                1,
                1,
                PETSc.DMSTAG_STENCIL_BOX,
                2)

        @test PETSc.DMStagGetGlobalSizes(dm_2D) == (20,21)
        corners = PETSc.getcorners(dm_2D)
        @test corners.size  == [20,21,0]
        @test corners.extra == [1, 1, 0]
        @test corners.lower == [1, 1, 1]
        @test corners.upper == [20,21,0]

        PETSc.finalize(petsclib)
    end
end

@testset "DMStagCreate3d" begin

    comm = MPI.COMM_WORLD
    mpirank = MPI.Comm_rank(comm)
    mpisize = MPI.Comm_size(comm)
    for petsclib in PETSc.petsclibs
        PETSc.initialize(petsclib)
        PetscScalar = PETSc.scalartype(petsclib)
        PetscInt    = PETSc.inttype(petsclib)

        # Create 3D DMStag
        dm_3D = PETSc.DMStagCreate3d(petsclib,comm,
                PETSc.DM_BOUNDARY_NONE,
                PETSc.DM_BOUNDARY_NONE,
                PETSc.DM_BOUNDARY_NONE,
                20,
                21,
                22,
                1,
                1,
                1,
                2,
                2,
                2,
                2,
                PETSc.DMSTAG_STENCIL_BOX,
                1,
                [],
                [],
                [])
        @test PETSc.DMStagGetGlobalSizes(dm_3D) == (20, 21, 22)

        # copy struct
        dmnew = PETSc.DMStagCreateCompatibleDMStag(dm_3D,1,1,2,2)
        @test PETSc.DMStagGetGlobalSizes(dmnew) == (20, 21, 22)

        @test PETSc.DMStagGetGlobalSizes(dm_3D) == (20,21,22)
        corners = PETSc.getcorners(dm_3D)
        @test corners.size  == [20,21,22]
        @test corners.extra == [1, 1, 1]
        @test corners.lower == [1, 1, 1]
        @test corners.upper == [20,21,22]

        PETSc.finalize(petsclib)
    end
end

@testset "DMStag Vectors and Coordinates" begin
    comm = MPI.COMM_WORLD
    mpirank = MPI.Comm_rank(comm)
    mpisize = MPI.Comm_size(comm)
    for petsclib in PETSc.petsclibs
        PETSc.initialize(petsclib)
        PetscScalar = PETSc.scalartype(petsclib)
        PetscInt    = PETSc.inttype(petsclib)

        # Create 1D DMStag
        dm_1D = PETSc.DMStagCreate1d(petsclib,comm,PETSc.DM_BOUNDARY_NONE,200,2,2; stag_grid_x=10);
        @test PETSc.DMStagGetGlobalSizes(dm_1D) == 10

        # Set coordinates
        PETSc.setuniformcoordinates!(dm_1D, (0,), (10,))

        DMcoord = PETSc.getcoordinateDM(dm_1D)
        @test PETSc.gettype(DMcoord)=="stag"

        # Retrieve array with staggered coordinates
        coord_vec   = PETSc.getcoordinateslocal(dm_1D)
        X_coord     = PETSc.DMStagVecGetArray(DMcoord, coord_vec);
        @test  X_coord[1,2] == 0.5

        # Set coordinates using product (1D) arrays
        dm_1D = PETSc.DMStagCreate1d(petsclib,comm,PETSc.DM_BOUNDARY_NONE,200,2,2; stag_grid_x=10);
        PETSc.setuniformcoordinatesproduct!(dm_1D, (0,), (10,))

        # retrieve DM with coordinates
        DMcoord = PETSc.getcoordinateDM(dm_1D)
        @test PETSc.gettype(DMcoord)=="product"
        coord_vec   = PETSc.getcoordinateslocal(dm_1D)

        # Note: retrieving 1D coordinate vectors using the "product" type appears broken
        #  This is something to be looked at later
        #x_coord,y_coord,z_coord = PETSc.DMStagGetProductCoordinateArraysRead(dm_1D); # BROKEN

        PETSc.DMStagGetLocationSlot(dm_1D, PETSc.DMSTAG_RIGHT, 0) ==4
        @test PETSc.DMStagGetProductCoordinateLocationSlot(dm_1D, PETSc.DMSTAG_RIGHT) == 2

        global_vec      = PETSc.createglobalvector(dm_1D)
        local_vec       = PETSc.createlocalvector(dm_1D)

        # Fill everything with some data
        fill!(local_vec, mpisize)
        fill!(global_vec, mpisize)
        @test global_vec[3] == 1.0

        # Add the local values to the global values
        PETSc.update!(global_vec, local_vec, PETSc.ADD_VALUES)
        @test global_vec[3] == 2.0

        # PETSc.destroy(DMcoord);

        # Do 2D tests
        dm_2D = PETSc.DMStagCreate2d(petsclib, comm,
            PETSc.DM_BOUNDARY_NONE,
            PETSc.DM_BOUNDARY_NONE,
            3,
            4,
            1,
            1,
            1,
            1,
            1,
            PETSc.DMSTAG_STENCIL_BOX,
            2)

        PETSc.setuniformcoordinates!(dm_2D, (1,3), (10,11))
        coord_vec   = PETSc.getcoordinateslocal(dm_2D)

        # Retrieve array with staggered coordinates
        DMcoord_2D = PETSc.getcoordinateDM(dm_2D)
        X_coord_2D = PETSc.DMStagVecGetArray(DMcoord_2D, coord_vec);

        @test X_coord_2D[3,3,1] ≈ 7.0
        @test X_coord_2D[3,4,2] ≈ 9.0
        @test X_coord_2D[3,3,3] ≈ 8.5
        @test X_coord_2D[3,3,4] ≈ 7.0

        vec_test_2D     = PETSc.createlocalvector(dm_2D)
        X               = PETSc.DMStagVecGetArray(dm_2D,vec_test_2D);
        X[end,end,end] = 111;                   # modify 3D array @ some point and DOF
        @test vec_test_2D[end]==111.0           # verify that this modified the vector as well
        Base.finalize(X)                        # release from memory

        #test stencil locations
        pos1 = PETSc.DMStagStencil{PetscInt}(PETSc.DMSTAG_LEFT,1,0,0,1)
        @test pos1.c == 1
        pos2 = PETSc.DMStagStencil{PetscInt}(PETSc.DMSTAG_RIGHT,4,0,0,0)
        pos  = [pos1, pos2]
        @test pos2.loc == PETSc.DMSTAG_RIGHT
        @test pos2.i == 4

        # Retrieve value from stencil
        vec_test       = PETSc.createlocalvector(dm_1D)
        vec_test      .= 1:length(vec_test)                 # point wise copy of data to PetscVec
        val             = PETSc.DMStagVecGetValuesStencil(dm_1D, vec_test, pos1) # this gets a single value
        @test val ==6
        vals            = PETSc.DMStagVecGetValuesStencil(dm_1D, vec_test, 2, pos)     # this gets an array of values
        @test vals[1] == 6

        X_1D            = PETSc.DMStagVecGetArray(dm_1D,vec_test);
        @test X_1D[2,3] == 7.0

        # Set values using stencils
        vec_test_global = PETSc.createglobalvector(dm_1D)
        val1 = PetscScalar.([2222.2, 3.2]);
        PETSc.DMStagVecSetValuesStencil(dm_1D, vec_test_global,    pos1, val1[1],   PETSc.INSERT_VALUES)
        @test vec_test_global[6] ≈ 2222.2
        PETSc.DMStagVecSetValuesStencil(dm_1D, vec_test_global, 2, pos,  val1,      PETSc.INSERT_VALUES)
        @test vec_test_global[21] ≈ 3.2

        pos3 = PETSc.DMStagStencil{PetscInt}(PETSc.DMSTAG_LEFT,1,0,0,1)
        val = PETSc.DMStagVecGetValuesStencil(dm_1D, vec_test, 2, [pos3; pos3])
        @test val[2] == 6.0
        PETSc.destroy(dm_1D);

        PETSc.finalize(petsclib)
    end
end

@testset "DMStag create matrixes" begin
    comm = MPI.COMM_WORLD
    mpirank = MPI.Comm_rank(comm)
    mpisize = MPI.Comm_size(comm)
    for petsclib in PETSc.petsclibs
        PETSc.initialize(petsclib)
        PetscScalar = PETSc.scalartype(petsclib)
        PetscInt    = PETSc.inttype(petsclib)

        dm_1D = PETSc.DMStagCreate1d(petsclib,comm,PETSc.DM_BOUNDARY_NONE,200,2,2; stag_grid_x=10);
        PETSc.setuniformcoordinatesproduct!(dm_1D, (0,), (10,))

        A = PETSc.creatematrix(dm_1D);  #
        @test size(A) == (42,42)
        PETSc.assembled(A)

        # set some values using normal indices:
        A[1,1]  = 1.0
        A[1,10] = 1.0

        pos1 = PETSc.DMStagStencil{PetscInt}(PETSc.DMSTAG_LEFT,1,0,0,1)
        pos2 = PETSc.DMStagStencil{PetscInt}(PETSc.DMSTAG_RIGHT,4,0,0,0)
        pos  = [pos1, pos2]
        val1 = PetscScalar.([2222.2, 3.2]);
        PETSc.DMStagMatSetValuesStencil(dm_1D, A, pos1, pos1, 11.1, PETSc.INSERT_VALUES)
        PETSc.DMStagMatSetValuesStencil(dm_1D, A, 1, [pos2], 2, pos, val1, PETSc.INSERT_VALUES)

        PETSc.assemble(A)
        @test A[1,10] == 1.0

        # Reads a value from the matrix, using the stencil structure
        @test PETSc.DMStagMatGetValuesStencil(dm_1D, A, pos1, pos1)== PetscScalar(11.1)
        @test PETSc.DMStagMatGetValuesStencil(dm_1D, A, 1, [pos2], 2, pos)==val1

        PETSc.destroy(dm_1D);

        dofCenter       =   1;
        dofEdge         =   1;
        dofVertex       =   0
        stencilWidth    =   1;
        dm_2D = PETSc.DMStagCreate2d(petsclib,comm,
                                        PETSc.DM_BOUNDARY_GHOSTED,
                                        PETSc.DM_BOUNDARY_GHOSTED,
                                        10,11,
                                        PETSc.PETSC_DECIDE,PETSc.PETSC_DECIDE,
                                        dofVertex,dofEdge,dofCenter,
                                        PETSc.DMSTAG_STENCIL_BOX,stencilWidth)

        vec_test_2D_global      =   PETSc.createglobalvector(dm_2D)
        vec_test_2D_local       =   PETSc.createlocalvector(dm_2D)

        corners                 =   PETSc.getcorners(dm_2D)
        ghost_corners           =   PETSc.getghostcorners(dm_2D)

        for ix=corners.lower[1]:corners.upper[1]
            for iy=corners.lower[2]:corners.upper[2]
                local dof
                # DOF at the center point
                dof     = 0;
                posA    = PETSc.DMStagStencil{PetscInt}(PETSc.DMSTAG_DOWN,ix,iy,0,dof)
                value   = PetscScalar(ix+10);
                PETSc.DMStagVecSetValuesStencil(dm_2D, vec_test_2D_global, posA, value, PETSc.INSERT_VALUES)

                dof     = 0;
                posB    = PETSc.DMStagStencil{PetscInt}(PETSc.DMSTAG_LEFT,ix,iy,0,dof)
                value   = PetscScalar(33);
                PETSc.DMStagVecSetValuesStencil(dm_2D, vec_test_2D_global, posB, value, PETSc.INSERT_VALUES)

                dof     = 0;
                posC    = PETSc.DMStagStencil{PetscInt}(PETSc.DMSTAG_ELEMENT,ix,iy,0,dof)
                value   = PetscScalar(44);
                PETSc.DMStagVecSetValuesStencil(dm_2D, vec_test_2D_global, posC, value, PETSc.INSERT_VALUES)

            end
        end
        PETSc.assemble(vec_test_2D_global) # assemble global vector

        # Add the global values to the local values
        PETSc.update!(vec_test_2D_local, vec_test_2D_global,PETSc.INSERT_VALUES)

        # retrieve value back from the local array and check that it agrees with global one
        dof     = 0;
        pos     = PETSc.DMStagStencil{PetscInt}(PETSc.DMSTAG_DOWN,2,2,0,dof)
        @test PETSc.DMStagVecGetValuesStencil(dm_2D, vec_test_2D_local, pos) == 12.0

        # Extract an array that holds all DOF's
        X2D_dofs  = PETSc.DMStagVecGetArray(dm_2D,vec_test_2D_local)           # extract arrays with all DOF (mostly for visualizing)
        @test X2D_dofs[4,4,1] ≈ PetscScalar(12.0)
        @test X2D_dofs[4,4,2] ≈ PetscScalar(33.0)
        @test X2D_dofs[4,4,3] ≈ PetscScalar(44.0)

        # Extract an array of a specific DOF (here a face velocity @ the left)
        Xarray = PETSc.DMStagGetGhostArrayLocationSlot(dm_2D,vec_test_2D_local, PETSc.DMSTAG_LEFT, 0)
        @test sum(X2D_dofs[:,:,2]-Xarray)==0                # check if the local array is identical to the full array

        Xarray .= 111.                                      # Set a value @ a specific location
        @test vec_test_2D_local[2] ≈ PetscScalar(111)       # verify that this is changed in the PETSc Vec

        PETSc.finalize(petsclib)
    end
end

# -----------------
# Example of DMStag & SNES with AD jacobian
@testset "DMStag: 1D SNES AD" begin

    # Tell AD that it can handle Complex as scalars
    ForwardDiff.can_dual(::Type{ComplexF64}) = true
    ForwardDiff.can_dual(::Type{ComplexF32}) = true

    comm = MPI.COMM_WORLD
    mpirank = MPI.Comm_rank(comm)
    mpisize = MPI.Comm_size(comm)

    for petsclib in PETSc.petsclibs
        PETSc.initialize(petsclib)
        PetscScalar = PETSc.scalartype(petsclib)
        PetscInt    = PETSc.inttype(petsclib)

        # Define a struct that holds data we need in the local SNES routines below
        mutable struct Data_1{PetscScalar,PetscInt}
            dm
            x_l
            f_l
        end

        user_ctx = Data_1{PetscScalar,PetscInt}(nothing, nothing, nothing);  # holds data we need in the local

        function FormRes!(ptr_fx_g, ptr_x_g, user_ctx)

            # Note that in PETSc, ptr_x_g and ptr_fx_g are pointers to global vectors.
            # Copy global to local vectors that are stored in user_ctx
            PETSc.update!(user_ctx.x_l, ptr_x_g,   PETSc.INSERT_VALUES)
            PETSc.update!(user_ctx.f_l, ptr_fx_g,  PETSc.INSERT_VALUES)

            # Retrieve arrays from the local vectors
            ArrayLocal_x     =   PETSc.DMStagVecGetArrayRead(user_ctx.dm, user_ctx.x_l);  # array with all local x-data
            ArrayLocal_f     =   PETSc.DMStagVecGetArray(user_ctx.dm, user_ctx.f_l);      # array with all local residual

            # Compute local residual
            ComputeLocalResidual(user_ctx.dm, ArrayLocal_x, ArrayLocal_f, user_ctx)

            # Finalize local arrays
            Base.finalize(ArrayLocal_x)
            Base.finalize(ArrayLocal_f)

            # Copy local into global residual vector
            PETSc.update!(ptr_fx_g, user_ctx.f_l,   PETSc.INSERT_VALUES)

        end

        function ComputeLocalResidual(dm, ArrayLocal_x, ArrayLocal_f, user_ctx)
            # Compute the local residual. The vectors include ghost points

            T              =   PETSc.DMStagGetGhostArrayLocationSlot(dm,ArrayLocal_x, PETSc.DMSTAG_LEFT,    0);
            fT             =   PETSc.DMStagGetGhostArrayLocationSlot(dm,ArrayLocal_f, PETSc.DMSTAG_LEFT,    0);

            P              =   PETSc.DMStagGetGhostArrayLocationSlot(dm,ArrayLocal_x, PETSc.DMSTAG_ELEMENT, 0);
            fP             =   PETSc.DMStagGetGhostArrayLocationSlot(dm,ArrayLocal_f, PETSc.DMSTAG_ELEMENT, 0);

            # compute the FD stencil
            indices         =     PETSc.DMStagGetIndices(dm);      # indices of (center/element) points, not including ghost values.
            gc              =     PETSc.getghostcorners(user_ctx.dm);   # start and end of loop including ghost points
            c               =     PETSc.getcorners(user_ctx.dm);        # start and end of loop including ghost points

            nT             =     length(T);                             # array length
            dx             =     1.0/(c.size[1]-1);
            xp             =     (gc.lower[1]:gc.upper[1]).*dx;         # coordinates including ghost points (to define source term)
            F              =     6.0.*xp .+ (xp .+1.e-12).^6.0;         # define source term function

            # Nonlinear equation @ nodal points
            ind            =     indices.vertex.x;                         #  There is one more "vertex" point
            i              =     ind[2:end-1]
            fT[ind[1]]     =     T[ind[1]  ]-0.5;                       # left BC
            fT[ind[end]]   =     T[ind[end]]-2.0;                       # right BC
            fT[i]          =     (T[i .+ 1] - 2*T[i] + T[i .- 1])/dx^2  + T[i].*T[i] - F[i] # NL diffusion with source term

            # second, non-coupled, equation @ center points
            ind            =     indices.center.x;                             #  There is one more "vertex" point
            i              =     ind[2:end-1];
            fP[ind[1]]     =     P[ind[1]]-30.;                             # left BC
            fP[ind[end]]   =     P[ind[end]]-20.;                           # right BC
            fP[i]          =     (P[i .+ 1] - 2*P[i] + P[i .- 1])/dx^2      # steady state diffusion

        end

        function  ForwardDiff_res(x, user_ctx)

            f   = zero(x)               # vector of zeros, of same type as x (local vector)

            ArrayLocal_x     =   PETSc.DMStagVecGetArray(user_ctx.dm, x);        # array with all local x-data
            ArrayLocal_f     =   PETSc.DMStagVecGetArray(user_ctx.dm, f);        # array with all local residual

            ComputeLocalResidual(user_ctx.dm, ArrayLocal_x, ArrayLocal_f, user_ctx);
            # As the residual vector f is linked with ArrayLocal_f, we don't need to pass ArrayLocal_f back

            return f;
        end

        function FormJacobian!(ptr_x_g, J, P, user_ctx)

            # This requires several steps:
            #
            #   1) Extract local vector from global solution (x) vector
            #   2) Compute local jacobian from the residual routine (note that
            #       this routine requires julia vectors as input)

            # Extract the local vector
            PETSc.update!(user_ctx.x_l, ptr_x_g,  PETSc.INSERT_VALUES)
            x               =   PETSc.unsafe_localarray(PetscScalar, user_ctx.x_l.ptr;  write=false, read=true)
            f_Residual      =   (x -> ForwardDiff_res(x, user_ctx));        # pass additional arguments into the routine
            J_julia         =   ForwardDiff.jacobian(f_Residual,x);

            # Note: since x is the LOCAL vector, J_julia also ends up having the same size.
            ind             =   PETSc.LocalInGlobalIndices(user_ctx.dm);
            if PETSc.assembled(J) == false
                J           =   PETSc.MatSeqAIJ(sparse(J_julia[ind,ind]));
            else
                J           .=   sparse(J_julia[ind,ind]);
            end

           Base.finalize(x_g)
           return sparse(J_julia[ind,ind]), ind
        end

        # Main part

        # Construct a 1D test case for a coupled P-T diffusion solver, with 1 DOF @ the center & 1 DOF @ faces
        nx              =   21;
        user_ctx.dm     =   PETSc.DMStagCreate1d(petsclib,comm,
                                PETSc.DM_BOUNDARY_GHOSTED,
                                nx,
                                1,                              # DOF @ vertex
                                1,                              # DOF @ center
                                PETSc.DMSTAG_STENCIL_BOX,
                                1);                             # Stencil width

        x_g             =   PETSc.createglobalvector(user_ctx.dm)
        f_g             =   PETSc.createglobalvector(user_ctx.dm)
        user_ctx.x_l    =   PETSc.createlocalvector(user_ctx.dm)
        user_ctx.f_l    =   PETSc.createlocalvector(user_ctx.dm)

        PJ           =      PETSc.creatematrix(user_ctx.dm);                  # extract (global) matrix from DMStag
        J_julia, ind =      FormJacobian!(x_g, PJ, PJ, user_ctx)
        PJ           =      PETSc.MatSeqAIJ(J_julia)                # assemble non-zero structure

        S = PETSc.SNES{PetscScalar}(petsclib, comm;
                snes_rtol=1e-12,
                snes_view=false,
                snes_monitor=true,
                ksp_view=true,
                # pc_type="none",
                snes_monitor_true_residual=false,
                snes_converged_reason=false);
        S.user_ctx  =       user_ctx;

        PETSc.setfunction!(S, FormRes!, f_g)
        PETSc.setjacobian!(S, FormJacobian!, PJ, PJ)

        # Solve
        PETSc.solve!(x_g, S);
       # @show x_g

        # check
        @test x_g[4] ≈ 29.5
        @test x_g[11] ≈ 0.63797 rtol=1e-4

        PETSc.finalize(petsclib)

    end
end

@testset "DMStag: 2D SNES AD"  begin

    comm = MPI.COMM_WORLD
    mpirank = MPI.Comm_rank(comm)
    mpisize = MPI.Comm_size(comm)

    # Tell AD that it can handle Complex as scalars
    ForwardDiff.can_dual(::Type{ComplexF64}) = true
    ForwardDiff.can_dual(::Type{ComplexF32}) = true

    for petsclib in PETSc.petsclibs
        PETSc.initialize(petsclib)
        PetscScalar = PETSc.scalartype(petsclib)
        PetscInt    = PETSc.inttype(petsclib)

        mutable struct Data_2D{PetscScalar,PetscInt}
            dm
            x_l
            f_l
        end
        user_ctx = Data_2D{PetscScalar,PetscInt}(nothing, nothing, nothing);  # holds data we need in the local

        function FormRes!(ptr_fx_g, ptr_x_g, user_ctx)
            # Note that in PETSc, ptr_x_g and ptr_fx_g are pointers to global vectors.

            # Copy global to local vectors
            PETSc.update!(user_ctx.x_l, ptr_x_g,  PETSc.INSERT_VALUES)
            PETSc.update!(user_ctx.f_l, ptr_fx_g, PETSc.INSERT_VALUES)

            # Retrieve arrays from the local vectors
            ArrayLocal_x     =   PETSc.DMStagVecGetArrayRead(user_ctx.dm, user_ctx.x_l);  # array with all local x-data
            ArrayLocal_f     =   PETSc.DMStagVecGetArray(user_ctx.dm, user_ctx.f_l);      # array with all local residual

            # Compute local residual
            ComputeLocalResidual(user_ctx.dm, ArrayLocal_x, ArrayLocal_f, user_ctx)

            # Finalize local arrays
            Base.finalize(ArrayLocal_x)
            Base.finalize(ArrayLocal_f)

            # Copy local into global residual vector
            PETSc.update!(ptr_fx_g, user_ctx.f_l, PETSc.INSERT_VALUES)

        end

        function  ForwardDiff_res(x, user_ctx)
            f   = zero(x)               # vector of zeros, of same type as x (local vector)

            ArrayLocal_x     =   PETSc.DMStagVecGetArray(user_ctx.dm, x);        # array with all ocal x-data
            ArrayLocal_f     =   PETSc.DMStagVecGetArray(user_ctx.dm, f);        # array with all ocal residual

            ComputeLocalResidual(user_ctx.dm, ArrayLocal_x, ArrayLocal_f, user_ctx);

            # As the residual vector f is linked with ArrayLocal_f, we don't need to pass ArrayLocal_f back

            return f;
        end

        function ComputeLocalResidual(dm, ArrayLocal_x, ArrayLocal_f, user_ctx)
            # Compute the local residual. The vectors include ghost points

            # Important! Make sure you retrieve the values from the correct locations. In this example we have a
            T              =   PETSc.DMStagGetGhostArrayLocationSlot(dm,ArrayLocal_x, PETSc.DMSTAG_ELEMENT, 0);
            fT             =   PETSc.DMStagGetGhostArrayLocationSlot(dm,ArrayLocal_f, PETSc.DMSTAG_ELEMENT, 0);

            # compute the FD stencil
            indices         =     PETSc.DMStagGetIndices(dm);      # indices of (center/element) points, not including ghost values.

            sz             =     size(user_ctx.dm);                                 # array length
            dx             =     1.0/(sz[1]-1);
            dz             =     1.0/(sz[2]-1);

            # set ghost points for BC'S
            bnd            =    PETSc.DMStagGetBoundaryTypes(user_ctx.dm)
            if bnd[1] == PETSc.DM_BOUNDARY_GHOSTED
                T[1,:]     =    T[2,:];        # zero flux; dT/dx=0
                T[end,:]   =    T[end-1,:];    # zero flux
            end

            # Diffusion @ center points
            indx        = indices.center.x;
            indz        = indices.center.y;

            ix          =     indx[1:end]                             # use ghost points in x  (required GHOSTED x-boundary)
            iz          =     indz[2:end-1]                           # center points

            # upper and lower BC (including corners)
            fT[indx,indz[1]]   =    T[indx,indz[1]] .- 0.5;                             # bottom BC
            fT[indx,indz[end]] =    T[indx,indz[end]] .- 2.0;                             # top BC

            fT[ix,iz]       =    (T[ix .+ 1,iz] - 2*T[ix,iz] + T[ix .- 1,iz])/dx^2   +
                                 (T[ix,iz .+ 1] - 2*T[ix,iz] + T[ix,iz .- 1])/dz^2

        end

        function FormJacobian!(ptr_x_g, J, P, user_ctx)
            # This requires several steps:
            #
            #   1) Extract local vector from global solution (x) vector
            #   2) Compute local jacobian from the residual routine (note that
            #       this routine requires julia vectors as input)

            # Extract the local vector
            PETSc.update!(user_ctx.x_l, ptr_x_g,  PETSc.INSERT_VALUES)
            x               =   PETSc.unsafe_localarray(PetscScalar, user_ctx.x_l.ptr;  write=false, read=true)

            f_Residual      =   (x -> ForwardDiff_res(x, user_ctx));        # pass additional rguments into the routine
            J_julia         =   ForwardDiff.jacobian(f_Residual,x);

            # Note: since x is the LOCAL vector, J_julia also ends up having the same size.
            ind             =   PETSc.LocalInGlobalIndices(user_ctx.dm);
            if PETSc.assembled(J) == false
                J           =   PETSc.MatSeqAIJ(sparse(J_julia[ind,ind]));
            else
                J           .=   sparse(J_julia[ind,ind]);
            end

            return sparse(J_julia[ind,ind]), ind, sparse(J_julia)
        end

        # Main routine starts here ----

        dofVertex   =   0
        dofEdge     =   0
        dofCenter   =   1
        nx,nz       =   6,25
        user_ctx.dm =   PETSc.DMStagCreate2d(petsclib,comm,
                    PETSc.DM_BOUNDARY_GHOSTED,
                    PETSc.DM_BOUNDARY_NONE,
                    nx,
                    nz,
                    1,
                    1,
                    dofVertex,
                    dofEdge,
                    dofCenter,
                    PETSc.DMSTAG_STENCIL_BOX,
                    1)
        PJ           =      PETSc.creatematrix(user_ctx.dm);                  # extract global) matrix from DMStag
        x_g             =   PETSc.createglobalvector(user_ctx.dm)
        f_g             =   PETSc.createglobalvector(user_ctx.dm)
        user_ctx.x_l    =   PETSc.createlocalvector(user_ctx.dm)
        user_ctx.f_l    =   PETSc.createlocalvector(user_ctx.dm)

        S = PETSc.SNES{PetscScalar}(petsclib, comm;
                snes_rtol=1e-12,
                snes_monitor=true,
                pc_type="none",
                snes_monitor_true_residual=true,
                snes_converged_reason=false);
        S.user_ctx  =       user_ctx;

        J_julia, ind, J_full =      FormJacobian!(x_g, PJ, PJ, user_ctx)
        PJ           =      PETSc.MatSeqAIJ(J_julia)                # assemble non-zero structure

        PETSc.setfunction!(S, FormRes!, f_g)
        PETSc.setjacobian!(S, FormJacobian!, PJ, PJ)

        # Solve 2D system
        sol = PETSc.solve!(x_g, S);

        PETSc.update!(user_ctx.x_l,sol, PETSc.INSERT_VALUES);   # copy global solution -> local vector
        T2d =   PETSc.DMStagGetGhostArrayLocationSlot(user_ctx.dm,user_ctx.x_l, PETSc.DMSTAG_ELEMENT,    0);

        @test T2d[5,5] ≈ 0.75 rtol=1e-3
        #
        # -----------------

        PETSc.finalize(petsclib)

    end
end


text:
<?xml version="1.0" encoding="UTF-8"?>
<!--

    Copyright © 2019 Smoke Turner, LLC (github@smoketurner.com)

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.smoketurner.pipeline</groupId>
        <artifactId>pipeline-parent</artifactId>
        <version>1.0.3-SNAPSHOT</version>
    </parent>

    <artifactId>pipeline-application</artifactId>
    <name>Pipeline Application</name>

    <properties>
        <maven.compiler.release>11</maven.compiler.release>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.amazonaws</groupId>
                <artifactId>aws-java-sdk-bom</artifactId>
                <version>1.11.552</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-sse</artifactId>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-sts</artifactId>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-s3</artifactId>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-sqs</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.1</version>
                <configuration>
                    <createDependencyReducedPom>true</createDependencyReducedPom>
                    <filters>
                        <filter>
                            <artifact>*:*</artifact>
                            <excludes>
                                <exclude>META-INF/*.SF</exclude>
                                <exclude>META-INF/*.DSA</exclude>
                                <exclude>META-INF/*.RSA</exclude>
                            </excludes>
                        </filter>
                    </filters>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>com.smoketurner.pipeline.application.PipelineApplication</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>


text:
/*
 * interrupt-simulate-posix.c
 *
 *  Created on: Aug 14, 2016
 *      Author: Dan
 */

#include <semaphore.h>
#include <pthread.h>
#include "Log.h"
#include "interrupt-simulate-posix.h"
#include <stdatomic.h>
#include <errno.h>
#include "board.h"

#define MAX_INTERRUPT_FUNCTIONS 6

struct func_ptr_int_entry
{
	func_ptr_void function_ptr;
};
enum interrupt_request
{
	INT_REQUEST_NONE,
	INT_REQUEST_ENABLE,
	INT_REQUEST_DISABLE
};
struct func_ptr_int_simulate
{
	/**
	 * An array of function pointers used for interrupt assignment
	 */
	struct func_ptr_int_entry func_ptr_int_entry[MAX_INTERRUPT_FUNCTIONS];
	/**
	 * The next available entry in func_ptr_int_entry for assignment to an interrupt function
	 */
	int int_entry_offset;
	/**
	 * Semaphore used to kick the interrupt thread for processing of interrupt flags or requests
	 */
	sem_t int_waiting_sem;
	/**
	 * Mutex used to protect int_flags and request
	 */
	pthread_mutex_t int_flags_mutex;
	/**
	 * Flags indicating which interrupts are waiting to be serviced
	 */
	uint32_t int_flags;
	/**
	 * The request for handling interrupts goign forward. Enable or disable requests will be set here
	 */
	enum interrupt_request request;

	pthread_t interrupt_thread_id;
	/**
	 * True if interrupts are currently enabled
	 */
	bool ints_enabled;

};

struct func_ptr_int_simulate g_func_ptr_int_simulate;
/**
 * Global initializer, ensures we initialize g_func_ptr_int_simulate exactly once
 */
bool int_simulate_initialized=false;

static void *int_simulate_thread(void *arg)
{
	do
	{
		if( sem_wait(&g_func_ptr_int_simulate.int_waiting_sem) == 0 )
		{

			unsigned int i=0;
			uint32_t int_flags;
			enum interrupt_request request;
			struct func_ptr_int_simulate *int_sim=&g_func_ptr_int_simulate;
			pthread_mutex_lock(&g_func_ptr_int_simulate.int_flags_mutex);
			int_flags = int_sim->int_flags;
			int_sim->int_flags=0;
			request=int_sim->request;
			int_sim->request=INT_REQUEST_NONE;
			pthread_mutex_unlock(&g_func_ptr_int_simulate.int_flags_mutex);

			if( int_sim->ints_enabled )
			{
				for( i=0; i< MAX_INTERRUPT_FUNCTIONS; i++ )
				{
					if( (0x01 << i) & int_flags )
					{
						(int_sim->func_ptr_int_entry[i].function_ptr)();
					}
				}
			}
			if( request == INT_REQUEST_ENABLE )
			{
				int_sim->ints_enabled=true;
			}
			else if( request == INT_REQUEST_DISABLE )
			{
				int_sim->ints_enabled=false;
			}
		}
	}while(1);
	return arg;
}

void __enable_irq()
{
	struct func_ptr_int_simulate *int_sim=&g_func_ptr_int_simulate;
	pthread_mutex_lock(&int_sim->int_flags_mutex);
	int_sim->request=INT_REQUEST_ENABLE;
	pthread_mutex_unlock(&int_sim->int_flags_mutex);
	int rc=sem_post(&int_sim->int_waiting_sem);
	if( rc != 0 )
	{
		LOG(Error,"sem_post for int_enable_semfailed in __enable_irq");
	}
}

/**
 * @return true if we are currently in the interrupt thread context
 */
static bool in_interrupt_thread()
{
	return pthread_equal(g_func_ptr_int_simulate.interrupt_thread_id,pthread_self()) != 0;
}

void __disable_irq()
{
	struct func_ptr_int_simulate *int_sim=&g_func_ptr_int_simulate;
	pthread_mutex_lock(&int_sim->int_flags_mutex);
	int_sim->request=INT_REQUEST_DISABLE;
	pthread_mutex_unlock(&int_sim->int_flags_mutex);
	int rc=sem_post(&g_func_ptr_int_simulate.int_waiting_sem);
	if( rc != 0 )
	{
		LOG(Error,"sem_post for int_enable_semfailed in __enable_irq");
	}
}

static void interrupt_simulate_init(void)
{
	if( int_simulate_initialized == false )
	{
		int_simulate_initialized=true;
		pthread_attr_t attr;

		memset(&g_func_ptr_int_simulate,0,sizeof(struct func_ptr_int_simulate));
		sem_init(&g_func_ptr_int_simulate.int_waiting_sem,0,0);
		pthread_mutex_init(&g_func_ptr_int_simulate.int_flags_mutex,0);
		int thread_num=0;
		int result=pthread_attr_init(&attr);
		if( result != 0 )
		{
			LOG(Error,"pthread_attr_init returned %d in interrupt_simulate_init",result);
		}
		result = pthread_create(&g_func_ptr_int_simulate.interrupt_thread_id, &attr,
										  int_simulate_thread, &thread_num);
		if( result != 0 )
		{
			LOG(Error,"pthread_create returned %d in interrupt_simulate_init",result);
		}
	}
}

static void func_ptr_interrupt_callback(unsigned char int_number)
{
	pthread_mutex_lock(&g_func_ptr_int_simulate.int_flags_mutex);
	g_func_ptr_int_simulate.int_flags |= (0x01 << int_number);
	pthread_mutex_unlock(&g_func_ptr_int_simulate.int_flags_mutex);
	sem_post(&g_func_ptr_int_simulate.int_waiting_sem);
}

void FuncPtrInterruptCallback0(void)
{
	func_ptr_interrupt_callback(0);
}

void FuncPtrInterruptCallback1(void)
{
	func_ptr_interrupt_callback(1);
}
void FuncPtrInterruptCallback2(void)
{
	func_ptr_interrupt_callback(2);
}
void FuncPtrInterruptCallback3(void)
{
	func_ptr_interrupt_callback(3);
}
void FuncPtrInterruptCallback4(void)
{
	func_ptr_interrupt_callback(4);
}
void FuncPtrInterruptCallback5(void)
{
	func_ptr_interrupt_callback(5);
}

int interrupt_simulate_alloc_next()
{
	int next=g_func_ptr_int_simulate.int_entry_offset;
	g_func_ptr_int_simulate.int_entry_offset++;
	return next;
}

func_ptr_void interrupt_simulate_set_func_ptr_for_int_number(int offset,func_ptr_void new_ptr)
{
	func_ptr_void rtnval=0;
	switch( offset )
	{
		case 0:
			rtnval=FuncPtrInterruptCallback0;
			break;
		case 1:
			rtnval=FuncPtrInterruptCallback1;
			break;
		case 2:
			rtnval=FuncPtrInterruptCallback2;
			break;
		case 3:
			rtnval=FuncPtrInterruptCallback3;
			break;
		case 4:
			rtnval=FuncPtrInterruptCallback4;
			break;
		case 5:
			rtnval=FuncPtrInterruptCallback5;
			break;
		default:
			LOG(Error,"Too many interrupts defined, only %d supported but %d defined",
					MAX_INTERRUPT_FUNCTIONS,offset+1);
			break;
	}
	if( rtnval != NULL )
	{
		g_func_ptr_int_simulate.func_ptr_int_entry[offset].function_ptr=new_ptr;
	}
	return rtnval;
}

/**
 * Simulate an IRQ callback for @param interrupt_callback.
 * @return a function pointer which can be used to trigger callback @param interrupt_callback
 * only when interrupts are enabled.
 */
func_ptr_void interrupt_simulate_map_next_irq( func_ptr_void interrupt_callback )
{
	interrupt_simulate_init();
	int offset=interrupt_simulate_alloc_next();
	func_ptr_void rtnvalue=interrupt_simulate_set_func_ptr_for_int_number(offset,interrupt_callback);
	return rtnvalue;
}


text:
package com.mixpanel.android.mpmetrics;

import org.json.JSONException;
import org.json.JSONObject;

public class ExceptionHandler implements Thread.UncaughtExceptionHandler {

    private static final int SLEEP_TIMEOUT_MS = 400;

    private static ExceptionHandler sInstance;
    private final Thread.UncaughtExceptionHandler mDefaultExceptionHandler;

    public ExceptionHandler() {
        mDefaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    public static void init() {
        if (sInstance == null) {
            synchronized (ExceptionHandler.class) {
                if (sInstance == null) {
                    sInstance = new ExceptionHandler();
                }
            }
        }
    }

    @Override
    public void uncaughtException(final Thread t, final Throwable e) {
        // Only one worker thread - giving priority to storing the event first and then flush
        MixpanelAPI.allInstances(new MixpanelAPI.InstanceProcessor() {
            @Override
            public void process(MixpanelAPI mixpanel) {
                if (mixpanel.getTrackAutomaticEvents()) {
                    try {
                        final JSONObject messageProp = new JSONObject();
                        messageProp.put(AutomaticEvents.APP_CRASHED_REASON, e.toString());
                        mixpanel.track(AutomaticEvents.APP_CRASHED, messageProp, true);
                    } catch (JSONException e) {}
                }
            }
        });

        if (mDefaultExceptionHandler != null) {
            mDefaultExceptionHandler.uncaughtException(t, e);
        } else {
            killProcessAndExit();
        }
    }

    private void killProcessAndExit() {
        try {
            Thread.sleep(SLEEP_TIMEOUT_MS);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        android.os.Process.killProcess(android.os.Process.myPid());
        System.exit(10);
    }
}


text:
package org.jetbrains.sbt.project.data.service

import java.io.File
import java.util

import com.intellij.facet.ModifiableFacetModel
import com.intellij.openapi.externalSystem.model.project.{ModuleData, ProjectData}
import com.intellij.openapi.externalSystem.model.{DataNode, Key, ProjectKeys}
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider
import com.intellij.openapi.externalSystem.service.project.manage.AbstractProjectDataService
import com.intellij.openapi.externalSystem.util.{DisposeAwareProjectChange, ExternalSystemApiUtil}
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ModifiableRootModel
import com.intellij.openapi.roots.impl.libraries.LibraryEx
import com.intellij.openapi.roots.libraries.Library
import com.intellij.util.CommonProcessors.CollectProcessor
import org.jetbrains.plugins.scala.project.Platform.{Dotty, Scala}
import org.jetbrains.plugins.scala.project.{DottyLibraryName, Platform, ScalaLanguageLevel, ScalaLibraryName, ScalaLibraryProperties, ScalaLibraryType, ScalaSdk}

import scala.collection.JavaConversions._

/**
 * @author Pavel Fatin
 */
abstract class AbstractDataService[E, I](key: Key[E]) extends AbstractProjectDataService[E, I] {

  def createImporter(toImport: Seq[DataNode[E]],
                     projectData: ProjectData,
                     project: Project,
                     modelsProvider: IdeModifiableModelsProvider): Importer[E]

  def getTargetDataKey: Key[E] = key

  override final def importData(toImport: util.Collection[DataNode[E]],
                                projectData: ProjectData,
                                project: Project,
                                modelsProvider: IdeModifiableModelsProvider): Unit =
    createImporter(toImport.toSeq, projectData, project, modelsProvider).importData()
}

/**
 * The purposes of this trait are the following:
 *    - Incapsulate logic necessary for importing specified data
 *    - Wrap "unsafe" methods from IdeModifiableModelsProvider
 *    - Collect import parameters as class fields to eliminate necessity of
 *      dragging them into each and every method of ProjectDataService
 *    - Abstract from External System's API which is rather unstable
 */
trait Importer[E] {
  val dataToImport: Seq[DataNode[E]]
  val projectData: ProjectData
  val project: Project
  val modelsProvider: IdeModifiableModelsProvider

  def importData(): Unit

  // IdeModifiableModelsProvider wrappers

  def findIdeModule(name: String): Option[Module] =
    Option(modelsProvider.findIdeModule(name))

  def findIdeModule(data: ModuleData): Option[Module] =
    Option(modelsProvider.findIdeModule(data))

  def getModifiableFacetModel(module: Module): ModifiableFacetModel =
    modelsProvider.getModifiableFacetModel(module)

  def getModifiableLibraryModel(library: Library): Library.ModifiableModel =
    modelsProvider.getModifiableLibraryModel(library)

  def getModifiableRootModel(module: Module): ModifiableRootModel =
    modelsProvider.getModifiableRootModel(module)

  def getModules: Array[Module] =
    modelsProvider.getModules

  // FIXME: should be implemented in External System
  def getModifiableLibraryModelEx(library: Library): LibraryEx.ModifiableModelEx =
    modelsProvider.getModifiableLibraryModel(library).asInstanceOf[LibraryEx.ModifiableModelEx]

  // Utility methods

  def getIdeModuleByNode(node: DataNode[_]): Option[Module] =
    for {
      moduleData <- Option(node.getData(ProjectKeys.MODULE))
      module <- findIdeModule(moduleData)
    } yield module

  def getScalaLibraries: Set[Library] =
    modelsProvider.getAllLibraries.filter(l => Option(l.getName).exists(_.contains(ScalaLibraryName))).toSet

  def getScalaLibraries(module: Module, platform: Platform): Set[Library] = {
    val libraryName = platform match {
      case Scala => ScalaLibraryName
      case Dotty => DottyLibraryName
    }
    val collector = new CollectProcessor[Library]()
    getModifiableRootModel(module).orderEntries().librariesOnly().forEachLibrary(collector)
    collector.getResults.toSet.filter(l => Option(l.getName).exists(_.contains(libraryName)))
  }

  def executeProjectChangeAction(action: => Unit): Unit =
    ExternalSystemApiUtil.executeProjectChangeAction(new DisposeAwareProjectChange(project) {
      override def execute(): Unit = action
    })

  def convertToScalaSdk(library: Library,
                        platform: Platform,
                        languageLevel: ScalaLanguageLevel,
                        compilerClasspath: Seq[File]): ScalaSdk = {

    val properties = new ScalaLibraryProperties()
    properties.platform = platform
    properties.languageLevel = languageLevel
    properties.compilerClasspath = compilerClasspath

    val model = getModifiableLibraryModelEx(library)
    model.setKind(ScalaLibraryType.instance.getKind)
    model.setProperties(properties)

    new ScalaSdk(library)
  }
}

abstract class AbstractImporter[E](val dataToImport: Seq[DataNode[E]],
                                   val projectData: ProjectData,
                                   val project: Project,
                                   val modelsProvider: IdeModifiableModelsProvider) extends Importer[E]


text:
package com.ibm.streamsx.topology.test.consistent;

import static com.ibm.streamsx.topology.consistent.ConsistentRegionConfig.operatorDriven;
import static com.ibm.streamsx.topology.consistent.ConsistentRegionConfig.periodic;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.util.concurrent.TimeUnit;

import org.junit.Test;

import com.ibm.streamsx.topology.consistent.ConsistentRegionConfig;
import com.ibm.streamsx.topology.consistent.ConsistentRegionConfig.Trigger;
import com.ibm.streamsx.topology.test.TestTopology;

public class ConsistentRegionConfigTest extends TestTopology {

    @Test
    public void testDefaultOpDriven() {
        ConsistentRegionConfig config = operatorDriven();
        checkCRC(config, Trigger.OPERATOR_DRIVEN, -1, 180, 180, 5);
    }
    @Test
    public void testDefaultOpDrivenNew() {
        ConsistentRegionConfig config = new ConsistentRegionConfig();
        checkCRC(config, Trigger.OPERATOR_DRIVEN, -1, 180, 180, 5);
    }

    @Test
    public void testDefaultPeriod() {
        ConsistentRegionConfig config = periodic(37);
        checkCRC(config, Trigger.PERIODIC, 37, 180, 180, 5);
    }
    @Test
    public void testDefaultPeriodNew() {
        ConsistentRegionConfig config = new ConsistentRegionConfig(39);
        checkCRC(config, Trigger.PERIODIC, 39, 180, 180, 5);
    }

    @Test
    public void testChangeDrain() {
        ConsistentRegionConfig config = operatorDriven().drainTimeout(27);
        checkCRC(config, Trigger.OPERATOR_DRIVEN, -1, 27, 180, 5);
    }
    @Test
    public void testChangeReset() {
        ConsistentRegionConfig config = periodic(4).resetTimeout(99);
        checkCRC(config, Trigger.PERIODIC, 4, 180, 99, 5);
    }
    @Test
    public void testChangeAttempts() {
        ConsistentRegionConfig config = periodic(9).maxConsecutiveResetAttempts(10);
        checkCRC(config, Trigger.PERIODIC, 9, 180, 180, 10);
    }

    @Test
    public void testChangeAll() {
        ConsistentRegionConfig config = operatorDriven().maxConsecutiveResetAttempts(11).drainTimeout(32).resetTimeout(200);
        checkCRC(config, Trigger.OPERATOR_DRIVEN, -1, 32, 200, 11);
    }

    @Test(expected=IllegalArgumentException.class)
    public void testInvalidDrain0() {
        operatorDriven().drainTimeout(0);
    }
    @Test(expected=IllegalArgumentException.class)
    public void testInvalidDrainNeg() {
        operatorDriven().drainTimeout(-214);
    }
    @Test(expected=IllegalArgumentException.class)
    public void testInvalidReset0() {
        operatorDriven().resetTimeout(0);
    }
    @Test(expected=IllegalArgumentException.class)
    public void testInvalidResetNeg() {
        operatorDriven().resetTimeout(-2124);
    }
    @Test(expected=IllegalArgumentException.class)
    public void testInvalidAttempts0() {
        operatorDriven().maxConsecutiveResetAttempts(0);
    }
    @Test(expected=IllegalArgumentException.class)
    public void testInvalidAttemptsNeg() {
        operatorDriven().maxConsecutiveResetAttempts(-2);
    }

    @Test
    public void testEquals() {

        assertFalse(operatorDriven().equals(periodic(2)));

        assertEquals(operatorDriven(), new ConsistentRegionConfig());
        assertEquals(periodic(7), new ConsistentRegionConfig(7));

        assertEquals(operatorDriven(), operatorDriven());
        assertEquals(periodic(9), periodic(9));

        assertFalse(operatorDriven().equals(operatorDriven().drainTimeout(15)));
        assertFalse(operatorDriven().equals(operatorDriven().resetTimeout(16)));
        assertFalse(operatorDriven().equals(operatorDriven().maxConsecutiveResetAttempts(17)));

        assertFalse(periodic(9).equals(periodic(11)));
    }

    private static void checkCRC(ConsistentRegionConfig config,
            Trigger trigger, int period, long drain, long reset, int attempts) {

        assertNotNull(config.getTrigger());
        assertTrue(config.getDrainTimeout() > 0);
        assertTrue(config.getResetTimeout() > 0);
        assertTrue(config.getMaxConsecutiveResetAttempts() > 0);

        assertEquals(TimeUnit.SECONDS, config.getTimeUnit());

        assertEquals(trigger, config.getTrigger());
        assertEquals(((long) period), config.getPeriod());

        assertEquals(drain, config.getDrainTimeout());
        assertEquals(reset, config.getResetTimeout());
        assertEquals(attempts, config.getMaxConsecutiveResetAttempts());

        assertEquals(config, config);

        ConsistentRegionConfig dup;
        if (config.getTrigger() == Trigger.OPERATOR_DRIVEN)
            dup = operatorDriven();
        else
            dup = periodic(period);

        dup = dup.drainTimeout(drain).resetTimeout(reset).maxConsecutiveResetAttempts(attempts);
        assertEquals(config, dup);
        assertEquals(config.hashCode(), dup.hashCode());
    }
}


text:
namespace browser_watcher {

// Watches for the exit code of a process and records it in a given registry
// location.
class ExitCodeWatcher {
 public:
  // Initialize the watcher with a registry path.
  explicit ExitCodeWatcher(base::StringPiece16 registry_path);
  ~ExitCodeWatcher();

  // Initializes from arguments on |cmd_line|, returns true on success.
  // This function expects |process| to be open with sufficient privilege to
  // wait and retrieve the process exit code.
  // It checks the handle for validity and takes ownership of it.
  // The intent is for this handle to be inherited into the watcher process
  // hosting the instance of this class.
  bool Initialize(base::Process process);

  // Waits for the process to exit and records its exit code in registry.
  // This is a blocking call.
  void WaitForExit();

  const base::Process& process() const { return process_; }
  int exit_code() const { return exit_code_; }

 private:
  // Writes |exit_code| to registry, returns true on success.
  bool WriteProcessExitCode(int exit_code);

  // The registry path the exit codes are written to.
  const base::string16 registry_path_;

  // Watched process and its creation time.
  base::Process process_;
  base::Time process_creation_time_;

  // The exit code of the watched process. Valid after WaitForExit.
  int exit_code_;

  DISALLOW_COPY_AND_ASSIGN(ExitCodeWatcher);
};

}  // namespace browser_watcher

#endif  // COMPONENTS_BROWSER_WATCHER_EXIT_CODE_WATCHER_WIN_H_


text:
package org.elasticsearch.action.admin.cluster.allocation;

import org.elasticsearch.action.ActionType;

/**
 * ActionType for explaining shard allocation for a shard in the cluster
 */
public class ClusterAllocationExplainAction extends ActionType<ClusterAllocationExplainResponse> {

    public static final ClusterAllocationExplainAction INSTANCE = new ClusterAllocationExplainAction();
    public static final String NAME = "cluster:monitor/allocation/explain";

    private ClusterAllocationExplainAction() {
        super(NAME, ClusterAllocationExplainResponse::new);
    }
}


text: This project is licensed under the [MIT license](http://opensource.org/licenses/MIT).