text:
<!DOCTYPE html>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width" />

<link rel="shortcut icon" type="image/x-icon" href="../../../../favicon.ico" />
<title>GeofenceHardware - Android SDK | Android Developers</title>

<link rel="stylesheet"
href="http://fonts.googleapis.com/css?family=Roboto:regular,medium,thin,italic,mediumitalic,bold" title="roboto">
<link href="../../../../assets/css/default.css" rel="stylesheet" type="text/css">

<link href="../../../../assets/css/fullscreen.css" rel="stylesheet" class="fullscreen"
type="text/css">

          	Quicknav
			      Quicknav

                  Design

Develop

Distribute

Links

Google Play Developer Console

Android Developers Blog

About Android

Android Sites

Android.com

Android Developers

Android Open Source Project

      <form onsubmit="return submit_search()">
        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
onkeydown="return search_changed(event, true, '../../../../')"
onkeyup="return search_changed(event, false, '../../../../')" />
      </form>

        close

Get Started

Style

Patterns

Building Blocks

Downloads

Videos

Training

API Guides

Reference

Tools

Get the SDK

Google Services

Google Play

Publishing

Promoting

App Quality

Spotlight

Open Distribution

Results

Loading...

Training

API Guides

Reference

Tools

Google Services

to top

          API level:

            <select id="apiLevelSelector">

            </select>

Android APIs

  android

  android.accessibilityservice

  android.accounts

  android.animation

  android.app

  android.app.admin

  android.app.backup

  android.appwidget

  android.bluetooth

  android.content

  android.content.pm

  android.content.res

  android.database

  android.database.sqlite

  android.drm

  android.gesture

  android.graphics

  android.graphics.drawable

  android.graphics.drawable.shapes

  android.graphics.pdf

  android.hardware

  android.hardware.display

  android.hardware.input

  android.hardware.location

  android.hardware.usb

  android.inputmethodservice

  android.location

  android.media

  android.media.audiofx

  android.media.effect

  android.mtp

  android.net

  android.net.http

  android.net.nsd

  android.net.rtp

  android.net.sip

  android.net.wifi

  android.net.wifi.p2p

  android.net.wifi.p2p.nsd

  android.nfc

  android.nfc.cardemulation

  android.nfc.tech

  android.opengl

  android.os

  android.os.storage

  android.preference

  android.print

  android.print.pdf

  android.printservice

  android.provider

  android.renderscript

  android.sax

  android.security

  android.service.dreams

  android.service.notification

  android.service.textservice

  android.service.wallpaper

  android.speech

  android.speech.tts

  android.support.v13.app

  android.support.v4.accessibilityservice

  android.support.v4.app

  android.support.v4.content

  android.support.v4.content.pm

  android.support.v4.database

  android.support.v4.graphics.drawable

  android.support.v4.hardware.display

  android.support.v4.media

  android.support.v4.net

  android.support.v4.os

  android.support.v4.print

  android.support.v4.text

  android.support.v4.util

  android.support.v4.view

  android.support.v4.view.accessibility

  android.support.v4.widget

  android.support.v7.app

  android.support.v7.appcompat

  android.support.v7.gridlayout

  android.support.v7.media

  android.support.v7.mediarouter

  android.support.v7.view

  android.support.v7.widget

  android.support.v8.renderscript

  android.telephony

  android.telephony.cdma

  android.telephony.gsm

  android.test

  android.test.mock

  android.test.suitebuilder

  android.text

  android.text.format

  android.text.method

  android.text.style

  android.text.util

  android.transition

  android.util

  android.view

  android.view.accessibility

  android.view.animation

  android.view.inputmethod

  android.view.textservice

  android.webkit

  android.widget

  dalvik.bytecode

  dalvik.system

  java.awt.font

  java.beans

  java.io

  java.lang

  java.lang.annotation

  java.lang.ref

  java.lang.reflect

  java.math

  java.net

  java.nio

  java.nio.channels

  java.nio.channels.spi

  java.nio.charset

  java.nio.charset.spi

  java.security

  java.security.acl

  java.security.cert

  java.security.interfaces

  java.security.spec

  java.sql

  java.text

  java.util

  java.util.concurrent

  java.util.concurrent.atomic

  java.util.concurrent.locks

  java.util.jar

  java.util.logging

  java.util.prefs

  java.util.regex

  java.util.zip

  javax.crypto

  javax.crypto.interfaces

  javax.crypto.spec

  javax.microedition.khronos.egl

  javax.microedition.khronos.opengles

  javax.net

  javax.net.ssl

  javax.security.auth

  javax.security.auth.callback

  javax.security.auth.login

  javax.security.auth.x500

  javax.security.cert

  javax.sql

  javax.xml

  javax.xml.datatype

  javax.xml.namespace

  javax.xml.parsers

  javax.xml.transform

  javax.xml.transform.dom

  javax.xml.transform.sax

  javax.xml.transform.stream

  javax.xml.validation

  javax.xml.xpath

  junit.framework

  junit.runner

  org.apache.http

  org.apache.http.auth

  org.apache.http.auth.params

  org.apache.http.client

  org.apache.http.client.entity

  org.apache.http.client.methods

  org.apache.http.client.params

  org.apache.http.client.protocol

  org.apache.http.client.utils

  org.apache.http.conn

  org.apache.http.conn.params

  org.apache.http.conn.routing

  org.apache.http.conn.scheme

  org.apache.http.conn.ssl

  org.apache.http.conn.util

  org.apache.http.cookie

  org.apache.http.cookie.params

  org.apache.http.entity

  org.apache.http.impl

  org.apache.http.impl.auth

  org.apache.http.impl.client

  org.apache.http.impl.conn

  org.apache.http.impl.conn.tsccm

  org.apache.http.impl.cookie

  org.apache.http.impl.entity

  org.apache.http.impl.io

  org.apache.http.io

  org.apache.http.message

  org.apache.http.params

  org.apache.http.protocol

  org.apache.http.util

  org.json

  org.w3c.dom

  org.w3c.dom.ls

  org.xml.sax

  org.xml.sax.ext

  org.xml.sax.helpers

  org.xmlpull.v1

  org.xmlpull.v1.sax2

Classes

GeofenceHardware

GeofenceHardwareCallback

GeofenceHardwareMonitorCallback

GeofenceHardwareRequest

      fullscreen
      Use Tree NavigationUse Panel Navigation

Summary:

  Constants

  | Methods

  | Inherited Methods

| [Expand All]

  Added in API level 18

    public

    final

    class

GeofenceHardware

    extends Object

        java.lang.Object

               ↳

        android.hardware.location.GeofenceHardware

Class Overview

This class handles geofences managed by various hardware subsystems. It contains
 the public APIs that is needed to accomplish the task.

The APIs should not be called directly by the app developers. A higher level api
 which abstracts the hardware should be used instead. All the checks are done by the higher
 level public API. Any needed locking should be handled by the higher level API.

 There are 3 states associated with a Geofence: Inside, Outside, Unknown.
 There are 3 transitions: GEOFENCE_ENTERED, GEOFENCE_EXITED,
 GEOFENCE_UNCERTAIN. The APIs only expose the transitions.

 Inside state: The hardware subsystem is reasonably confident that the user is inside
 the geofence. Outside state: The hardware subsystem is reasonably confident that the user
 is outside the geofence Unknown state: Unknown state can be interpreted as a state in which the
 monitoring subsystem isn't confident enough that the user is either inside or
 outside the Geofence. If the accuracy does not improve for a sufficient period of time,
 the GEOFENCE_UNCERTAIN transition would be triggered. If the accuracy improves later,
 an appropriate transition would be triggered. The "reasonably confident" parameter
 depends on the hardware system and the positioning algorithms used.
 For instance, MONITORING_TYPE_GPS_HARDWARE uses 95% as a confidence level.

Summary

Constants

        int
        GEOFENCE_ENTERED
        The constant to indicate that the user has entered the geofence.

        int
        GEOFENCE_ERROR_ID_EXISTS
        The constant used to indicate that the geofence id already exists.

        int
        GEOFENCE_ERROR_ID_UNKNOWN
        The constant used to indicate that the geofence id is unknown.

        int
        GEOFENCE_ERROR_INVALID_TRANSITION
        The constant used to indicate that the transition requested for the geofence is invalid.

        int
        GEOFENCE_ERROR_TOO_MANY_GEOFENCES
        The constant used to indicate that too many geofences have been registered.

        int
        GEOFENCE_EXITED
        The constant to indicate that the user has exited the geofence.

        int
        GEOFENCE_FAILURE
        The constant used to indicate that the geofence operation has failed.

        int
        GEOFENCE_SUCCESS
        The constant used to indicate success of the particular geofence call

        int
        GEOFENCE_UNCERTAIN
        The constant to indicate that the user is uncertain with respect to a
 geofence.

        int
        MONITORING_TYPE_GPS_HARDWARE
        Constant for geofence monitoring done by the GPS hardware.

        int
        MONITOR_CURRENTLY_AVAILABLE
        Constant to indiciate that the monitoring system is currently
 available for monitoring geofences.

        int
        MONITOR_CURRENTLY_UNAVAILABLE
        Constant to indiciate that the monitoring system is currently
 unavailable for monitoring geofences.

        int
        MONITOR_UNSUPPORTED
        Constant to indiciate that the monitoring system is unsupported
 for hardware geofence monitoring.

Public Methods

        <nobr>

            boolean</nobr>

        <nobr>
        addGeofence(int geofenceId, int monitoringType, GeofenceHardwareRequest geofenceRequest, GeofenceHardwareCallback callback)</nobr>

Creates a circular geofence which is monitored by subsystems in the hardware.

        <nobr>

            int[]</nobr>

        <nobr>
        getMonitoringTypes()</nobr>

Returns all the hardware geofence monitoring systems which are supported

 Call getStatusOfMonitoringType(int) to know the current state
 of a monitoring system.

        <nobr>

            int</nobr>

        <nobr>
        getStatusOfMonitoringType(int monitoringType)</nobr>

Returns current status of a hardware geofence monitoring system.

        <nobr>

            boolean</nobr>

        <nobr>
        pauseGeofence(int geofenceId, int monitoringType)</nobr>

Pauses the monitoring of a geofence added by addGeofence(int, int, GeofenceHardwareRequest, GeofenceHardwareCallback) call.

        <nobr>

            boolean</nobr>

        <nobr>
        registerForMonitorStateChangeCallback(int monitoringType, GeofenceHardwareMonitorCallback callback)</nobr>

Register the callback to be notified when the state of a hardware geofence
 monitoring system changes.

        <nobr>

            boolean</nobr>

        <nobr>
        removeGeofence(int geofenceId, int monitoringType)</nobr>

Removes a geofence added by addGeofence(int, int, GeofenceHardwareRequest, GeofenceHardwareCallback) call.

        <nobr>

            boolean</nobr>

        <nobr>
        resumeGeofence(int geofenceId, int monitoringType, int monitorTransition)</nobr>

Resumes the monitoring of a geofence added by pauseGeofence(int, int) call.

        <nobr>

            boolean</nobr>

        <nobr>
        unregisterForMonitorStateChangeCallback(int monitoringType, GeofenceHardwareMonitorCallback callback)</nobr>

Unregister the callback that was used with registerForMonitorStateChangeCallback(int, GeofenceHardwareMonitorCallback)
 to notify when the state of the hardware geofence monitoring system changes.

  [Expand]

Inherited Methods

From class

  java.lang.Object

        <nobr>

            Object</nobr>

        <nobr>
        clone()</nobr>

Creates and returns a copy of this Object.

        <nobr>

            boolean</nobr>

        <nobr>
        equals(Object o)</nobr>

Compares this instance with the specified object and indicates if they
 are equal.

        <nobr>

            void</nobr>

        <nobr>
        finalize()</nobr>

Invoked when the garbage collector has detected that this instance is no longer reachable.

        <nobr>

            final

            Class<?></nobr>

        <nobr>
        getClass()</nobr>

Returns the unique instance of Class that represents this
 object's class.

        <nobr>

            int</nobr>

        <nobr>
        hashCode()</nobr>

Returns an integer hash code for this object.

        <nobr>

            final

            void</nobr>

        <nobr>
        notify()</nobr>

Causes a thread which is waiting on this object's monitor (by means of
 calling one of the wait() methods) to be woken up.

        <nobr>

            final

            void</nobr>

        <nobr>
        notifyAll()</nobr>

Causes all threads which are waiting on this object's monitor (by means
 of calling one of the wait() methods) to be woken up.

        <nobr>

            String</nobr>

        <nobr>
        toString()</nobr>

Returns a string containing a concise, human-readable description of this
 object.

        <nobr>

            final

            void</nobr>

        <nobr>
        wait()</nobr>

Causes the calling thread to wait until another thread calls the notify() or notifyAll() method of this object.

        <nobr>

            final

            void</nobr>

        <nobr>
        wait(long millis, int nanos)</nobr>

Causes the calling thread to wait until another thread calls the notify() or notifyAll() method of this object or until the
 specified timeout expires.

        <nobr>

            final

            void</nobr>

        <nobr>
        wait(long millis)</nobr>

Causes the calling thread to wait until another thread calls the notify() or notifyAll() method of this object or until the
 specified timeout expires.

Constants

        public
        static
        final
        int

        GEOFENCE_ENTERED

  Added in API level 18

The constant to indicate that the user has entered the geofence.

        Constant Value:

                1
                (0x00000001)

        public
        static
        final
        int

        GEOFENCE_ERROR_ID_EXISTS

  Added in API level 18

The constant used to indicate that the geofence id already exists.

        Constant Value:

                2
                (0x00000002)

        public
        static
        final
        int

        GEOFENCE_ERROR_ID_UNKNOWN

  Added in API level 18

The constant used to indicate that the geofence id is unknown.

        Constant Value:

                3
                (0x00000003)

        public
        static
        final
        int

        GEOFENCE_ERROR_INVALID_TRANSITION

  Added in API level 18

The constant used to indicate that the transition requested for the geofence is invalid.

        Constant Value:

                4
                (0x00000004)

        public
        static
        final
        int

        GEOFENCE_ERROR_TOO_MANY_GEOFENCES

  Added in API level 18

The constant used to indicate that too many geofences have been registered.

        Constant Value:

                1
                (0x00000001)

        public
        static
        final
        int

        GEOFENCE_EXITED

  Added in API level 18

The constant to indicate that the user has exited the geofence.

        Constant Value:

                2
                (0x00000002)

        public
        static
        final
        int

        GEOFENCE_FAILURE

  Added in API level 18

The constant used to indicate that the geofence operation has failed.

        Constant Value:

                5
                (0x00000005)

        public
        static
        final
        int

        GEOFENCE_SUCCESS

  Added in API level 18

The constant used to indicate success of the particular geofence call

        Constant Value:

                0
                (0x00000000)

        public
        static
        final
        int

        GEOFENCE_UNCERTAIN

  Added in API level 18

The constant to indicate that the user is uncertain with respect to a
 geofence.                                                  nn

        Constant Value:

                4
                (0x00000004)

        public
        static
        final
        int

        MONITORING_TYPE_GPS_HARDWARE

  Added in API level 18

Constant for geofence monitoring done by the GPS hardware.

        Constant Value:

                0
                (0x00000000)

        public
        static
        final
        int

        MONITOR_CURRENTLY_AVAILABLE

  Added in API level 18

Constant to indiciate that the monitoring system is currently
 available for monitoring geofences.

        Constant Value:

                0
                (0x00000000)

        public
        static
        final
        int

        MONITOR_CURRENTLY_UNAVAILABLE

  Added in API level 18

Constant to indiciate that the monitoring system is currently
 unavailable for monitoring geofences.

        Constant Value:

                1
                (0x00000001)

        public
        static
        final
        int

        MONITOR_UNSUPPORTED

  Added in API level 18

Constant to indiciate that the monitoring system is unsupported
 for hardware geofence monitoring.

        Constant Value:

                2
                (0x00000002)

Public Methods

        public

        boolean

      addGeofence
      (int geofenceId, int monitoringType, GeofenceHardwareRequest geofenceRequest, GeofenceHardwareCallback callback)

  Added in API level 18

Creates a circular geofence which is monitored by subsystems in the hardware.

 When the device detects that is has entered, exited or is uncertain
 about the area specified by the geofence, the given callback will be called.

 If this call returns true, it means that the geofence has been sent to the hardware.
 onGeofenceAdd(int, int) will be called with the result of the
 add call from the hardware. The onGeofenceAdd(int, int) will be
 called with the following parameters when a transition event occurs.

 The geofence Id

 The location object indicating the last known location.

 The transition associated with the geofence. One of
      GEOFENCE_ENTERED, GEOFENCE_EXITED, GEOFENCE_UNCERTAIN

 The timestamp when the geofence transition occured.

 The monitoring type (MONITORING_TYPE_GPS_HARDWARE is one such example)
      that was used.

 The geofence will be monitored by the subsystem specified by monitoring_type parameter.
 The application does not need to hold a wakelock when the monitoring
 is being done by the underlying hardware subsystem. If the same geofence Id is being
 monitored by two different monitoring systems, the same id can be used for both calls, as
 long as the same callback object is used.

 Requires ACCESS_FINE_LOCATION permission when
 MONITORING_TYPE_GPS_HARDWARE is used.

 Requires LOCATION_HARDWARE permission to access
 geofencing in hardware.

This API should not be called directly by the app developers. A higher level api
 which abstracts the hardware should be used instead. All the checks are done by the higher
 level public API. Any needed locking should be handled by the higher level API.

 Create a geofence request object using the methods in GeofenceHardwareRequest to
 set all the characteristics of the geofence. Use the created GeofenceHardwareRequest object
 in this call.

Parameters

          geofenceId
          The id associated with the geofence.

          monitoringType
          The type of the hardware subsystem that should be used
        to monitor the geofence.

          geofenceRequest
          The GeofenceHardwareRequest object associated with the
        geofence.

          callback
          GeofenceHardwareCallback that will be use to notify the
        transition.

Returns

true when the geofence is successfully sent to the hardware for addition.

Throws

            IllegalArgumentException
            when the geofence request type is not supported.

        public

        int[]

      getMonitoringTypes
      ()

  Added in API level 18

Returns all the hardware geofence monitoring systems which are supported

 Call getStatusOfMonitoringType(int) to know the current state
 of a monitoring system.

 Requires LOCATION_HARDWARE permission to access
 geofencing in hardware.

Returns

An array of all the monitoring types.
         An array of length 0 is returned in case of errors.

        public

        int

      getStatusOfMonitoringType
      (int monitoringType)

  Added in API level 18

Returns current status of a hardware geofence monitoring system.

Status can be one of MONITOR_CURRENTLY_AVAILABLE,
 MONITOR_CURRENTLY_UNAVAILABLE or MONITOR_UNSUPPORTED

 Some supported hardware monitoring systems might not be available
 for monitoring geofences in certain scenarios. For example, when a user
 enters a building, the GPS hardware subsystem might not be able monitor
 geofences and will change from MONITOR_CURRENTLY_AVAILABLE to
 MONITOR_CURRENTLY_UNAVAILABLE.

Returns

Current status of the monitoring type.

        public

        boolean

      pauseGeofence
      (int geofenceId, int monitoringType)

  Added in API level 18

Pauses the monitoring of a geofence added by addGeofence(int, int, GeofenceHardwareRequest, GeofenceHardwareCallback) call.

 If this call returns true, it means that the geofence has been sent to the hardware.
 onGeofencePause(int, int) will be called with the result of the
 pause call from the hardware.

 Requires ACCESS_FINE_LOCATION permission when
 MONITORING_TYPE_GPS_HARDWARE is used.

 Requires LOCATION_HARDWARE permission to access
 geofencing in hardware.

This API should not be called directly by the app developers. A higher level api
 which abstracts the hardware should be used instead. All the checks are done by the higher
 level public API. Any needed locking should be handled by the higher level API.

Parameters

          geofenceId
          The id of the geofence.

          monitoringType
          The type of the hardware subsystem that should be used
        to monitor the geofence.

Returns

true when the geofence is successfully sent to the hardware for pausing.

        public

        boolean

      registerForMonitorStateChangeCallback
      (int monitoringType, GeofenceHardwareMonitorCallback callback)

  Added in API level 18

Register the callback to be notified when the state of a hardware geofence
 monitoring system changes. For instance, it can change from
 MONITOR_CURRENTLY_AVAILABLE to MONITOR_CURRENTLY_UNAVAILABLE

 Requires ACCESS_FINE_LOCATION permission when
 MONITORING_TYPE_GPS_HARDWARE is used.

 Requires LOCATION_HARDWARE permission to access
 geofencing in hardware.

This API should not be called directly by the app developers. A higher level api
 which abstracts the hardware should be used instead. All the checks are done by the higher
 level public API. Any needed locking should be handled by the higher level API.

 The same callback object can be used to be informed of geofence transitions
 and state changes of the underlying hardware subsystem.

Parameters

          monitoringType
          Type of the monitor

          callback
          Callback that will be called.

Returns

true on success

        public

        boolean

      removeGeofence
      (int geofenceId, int monitoringType)

  Added in API level 18

Removes a geofence added by addGeofence(int, int, GeofenceHardwareRequest, GeofenceHardwareCallback) call.

 If this call returns true, it means that the geofence has been sent to the hardware.
 onGeofenceRemove(int, int) will be called with the result of the
 remove call from the hardware.

 Requires ACCESS_FINE_LOCATION permission when
 MONITORING_TYPE_GPS_HARDWARE is used.

 Requires LOCATION_HARDWARE permission to access
 geofencing in hardware.

This API should not be called directly by the app developers. A higher level api
 which abstracts the hardware should be used instead. All the checks are done by the higher
 level public API. Any needed locking should be handled by the higher level API.

Parameters

          geofenceId
          The id of the geofence.

          monitoringType
          The type of the hardware subsystem that should be used
        to monitor the geofence.

Returns

true when the geofence is successfully sent to the hardware for removal.                     .

        public

        boolean

      resumeGeofence
      (int geofenceId, int monitoringType, int monitorTransition)

  Added in API level 18

Resumes the monitoring of a geofence added by pauseGeofence(int, int) call.

 If this call returns true, it means that the geofence has been sent to the hardware.
 onGeofenceResume(int, int) will be called with the result of the
 resume call from the hardware.

 Requires ACCESS_FINE_LOCATION permission when
 MONITORING_TYPE_GPS_HARDWARE is used.

 Requires LOCATION_HARDWARE permission to access
 geofencing in hardware.

This API should not be called directly by the app developers. A higher level api
 which abstracts the hardware should be used instead. All the checks are done by the higher
 level public API. Any needed locking should be handled by the higher level API.

Parameters

          geofenceId
          The id of the geofence.

          monitoringType
          The type of the hardware subsystem that should be used
        to monitor the geofence.

          monitorTransition
          Bitwise OR of GEOFENCE_ENTERED,
        GEOFENCE_EXITED, GEOFENCE_UNCERTAIN

Returns

true when the geofence is successfully sent to the hardware for resumption.

        public

        boolean

      unregisterForMonitorStateChangeCallback
      (int monitoringType, GeofenceHardwareMonitorCallback callback)

  Added in API level 18

Unregister the callback that was used with registerForMonitorStateChangeCallback(int, GeofenceHardwareMonitorCallback)
 to notify when the state of the hardware geofence monitoring system changes.

 Requires ACCESS_FINE_LOCATION permission when
 MONITORING_TYPE_GPS_HARDWARE is used.

 Requires LOCATION_HARDWARE permission to access
 geofencing in hardware.

This API should not be called directly by the app developers. A higher level api
 which abstracts the hardware should be used instead. All the checks are done by the higher
 level public API. Any needed locking should be handled by the higher level API.

Parameters

          monitoringType
          Type of the monitor

          callback
          Callback that will be called.

Returns

true on success

  Except as noted, this content is licensed under Apache 2.0.
  For details and restrictions, see the
  Content License.

    Android 4.4 r1 —

    About Android  |
    Legal  |
    Support


text:
var _ = require('lodash');
var traverse = require('traverse');

function nullifyUndefinedFilterItems(filter) {
    return traverse(filter).map(function(x) {
        return x || null;
    });
}

var PermissionsManager = function(resource) {
    this.resource = resource;
    if ( !resource.options.permissions ) {
        this.defaults = this.anonymous_permissions = ['create','read','update','delete'];
    }
    else {
        this.defaults =
        resource.options.permissions.defaults || ['create','read','update','delete'];
        this.anonymous_permissions = resource.options.permissions.anonymous || [];
    }
};

PermissionsManager.prototype.apply = function(action, req, res, next) {
    var anonymous = !req.rem.identity;
    var permissions = ( anonymous )? this.anonymous_permissions : this.defaults;
    if ( _.isArray(permissions) && _.contains( permissions, action ) ) {
        return next();
    } else if ( _.isObject(permissions) && _.has( permissions, action ) ) {
        var permission = ( _.isArray(permissions[action]) ? permissions[action] : [ permissions[action] ] );
        if ( _.any( permission, function( condition ) {
            var result = this.testCondition( req.rem.identity, condition );
            if ( _.isObject( result ) ) {
                req.rem.permission_filter = nullifyUndefinedFilterItems( result );
                result = true;
            }

            return result? true : false;
        }.bind(this) ) ) {
            return next();
        }
    }

    if ( anonymous ) {
        return res.status(401).set('WWW-Authenticate','Bearer').send("Unauthorized.");
    }
    else {
        return res.status(403).send("Insufficient permissions.");
    }
};

PermissionsManager.prototype.testCondition = function( identity, condition ) {
    if ( _.isFunction( condition ) ) {
        condition = condition(identity);
    }

    if ( _.isObject( condition ) ) {
        return condition;
    }
    if ( _.isString( condition ) ) {
        var filter = {};
        filter[condition] = true;
        return filter;
    }
    else if ( condition ) { //test truthiness
        return true;
    }
    return false;
};

module.exports = PermissionsManager;

redpajama_set_name: RedPajamaGithub


text:
.navicon-content {
background-image:url(images/menu.content.png) !important;
}
.navicon-content:hover {
background-position:0 -30px !important;
}
.section-new .menuItems a {
background-image:url(images/menu.content.png);
}
/* subnav */
#menu .menu-admin .section-new .menuItems a {
background-position:0 4px;
}
#menu .menu-admin .section-new .menuItems a:hover, #menu .menu-admin .section-new .menuItems .selected a {
background-position:0 -28px;
}


text:
<?php
	#
	# $Id: announcements.php,v 1.1.2.8 2006-11-28 21:13:07 dan Exp $
	#
	# Copyright (c) 1998-2003 DVL Software Limited
	#

	require_once($_SERVER['DOCUMENT_ROOT'] . '/../include/common.php');
	require_once($_SERVER['DOCUMENT_ROOT'] . '/../include/freshports.php');
	require_once($_SERVER['DOCUMENT_ROOT'] . '/../include/databaselogin.php');
	require_once($_SERVER['DOCUMENT_ROOT'] . '/../include/getvalues.php');

	require_once($_SERVER['DOCUMENT_ROOT'] . '/../classes/user_tasks.php');
	require_once($_SERVER['DOCUMENT_ROOT'] . '/../classes/announcements.php');

	GLOBAL $User;

$origin		= $_REQUEST['origin'];
$submit 	= $_REQUEST['submit'];
$visitor	= $_COOKIE['visitor'];

if ($origin == '/index.php' || $origin == '') {
	$origin = '/';
}

// if we don't know who they are, we'll make sure they login first
if (!$User->id) {
	header('Location: /login.php?origin=' . $_SERVER['PHP_SELF']);  /* Redirect browser to PHP web site */
	exit;  /* Make sure that code below does not get executed when we redirect. */
}

if (!$User->IsTaskAllowed(FRESHPORTS_TASKS_ANNOUNCEMENTS_MAINTAIN)) {
	die("I'm sorry, but you're not allowed to be here.  The police have been notified.  Please leave now.");
}

if (IsSet($_REQUEST['add'])) {
	$Announcement = new Announcement($db);

	$Announcement->TextSet     ($_REQUEST['announcement']);
	$Announcement->StartDateSet($_REQUEST['start_date']);
	$Announcement->EndDateSet  ($_REQUEST['end_date']);

	$Announcement->Insert();
	Unset($Announcement);
}

if (IsSet($_REQUEST['update'])) {
	$Announcement = new Announcement($db);

	$Announcement->TextSet     ($_REQUEST['announcement']);
	$Announcement->StartDateSet($_REQUEST['start_date']);
	$Announcement->EndDateSet  ($_REQUEST['end_date']);
	$Announcement->IDSet       ($_REQUEST['id']);

	$Announcement->Update();
	Unset($Announcement);
}

if (IsSet($_REQUEST['delete'])) {
	$Announcement = new Announcement($db);

	$Announcement->IDSet($_REQUEST['delete']);

	$Announcement->Delete();
	Unset($Announcement);
}

# create another new one
$Announcement = new Announcement($db);

if (IsSet($_REQUEST['edit'])) {
	$Announcement->Fetch($_REQUEST['edit']);
}

	#echo '
the page size is ' . $page_size . ' : ' . $email;
	$Title = 'Announcements';
   freshports_Start($Title,
               'freshports - new ports, applications',
               'FreeBSD, index, applications, ports');
?>

<TABLE WIDTH="<? echo $TableWidth; ?>" BORDER="0" ALIGN="center">

<?php

if ($errors) {
echo '

Some errors have occurred which must be corrected before your login can be created.
';

echo $errors;

echo '
If you need help, please post a message on the forum.

';
}

echo '

<BIG><BIG>' . $Title . '</BIG></BIG>

';

echo 'Current annoucements
';

$HTML .= '<form action="' . $_SERVER["PHP_SELF"] . '" method="POST">' . "\n";

$HTML .= '
' . "\n";

$HTML .= '
Announcement Text (can be HTML)	Start Date	End Date
' . "\n";

$HTML .= '
'  . "\n";

$HTML .= ''  . "\n";
$HTML .= '<TEXTAREA NAME="announcement" ROWS="10" COLS="60">'          . "\n";
$HTML .= htmlspecialchars($Announcement->TextGet());
$HTML .= '</TEXTAREA>';
$HTML .= '	'  . "\n";

$HTML .= ''  . "\n";
$HTML .= '<INPUT id="start_date" name="start_date" value="' . $Announcement->StartDateGet() . '" size=25>' . "\n";
$HTML .= '	'  . "\n";

$HTML .= ''  . "\n";
$HTML .= '<INPUT id="end_date"   name="end_date"   value="' . $Announcement->EndDateGet()   . '" size=25>' . "\n";
$HTML .= '	'  . "\n";

$HTML .= '
'  . "\n";

$ControlName  = IsSet($_REQUEST['edit']) ? 'update' : 'add';
$ControlValue = IsSet($_REQUEST['edit']) ? 'Update' : 'Add';

$HTML .= '
'  . "\n";
$HTML .= '
<INPUT id="' . $ControlName . '" style="WIDTH: 85px; HEIGHT: 24px" type="submit" size="29" value="' . $ControlValue . '"';
$HTML .= ' name="' . $ControlName . '">
' . "\n";
$HTML .= '
'  . "\n";

$HTML .= '
' . "\n";

$HTML .= '<INPUT NAME="id" TYPE="hidden" value="' . $Announcement->IDGet(). '">' . "\n";

$HTML .= '</form>';

echo $HTML;

echo "

";

function MyDisplayAnnouncements($Announcement) {
	$HTML .= '
' . "\n";
	$HTML .= '
Announcement Text	Start Date	End Date	Edit	DeleteNumRows();

	for ($i = 0; $i < $NumRows; $i++) {
		$Announcement->FetchNth($i);
		$HTML .= '
' . "\n";
		$HTML .= '' . $Announcement->TextGet()      . '	';
		$HTML .= '' . ($Announcement->StartDateGet() != '' ? $Announcement->StartDateGet() : '&nbsp') . '	';
		$HTML .= '' . ($Announcement->EndDateGet()   != '' ? $Announcement->EndDateGet()   : '&nbsp') . '	';
		$HTML .= 'IDGet() . '">Edit	';
		$HTML .= 'IDGet() . '">Delete	';
      $HTML .= '
' . "\n";
	}
	$HTML .= '
' . "\n";

	return $HTML;
}

$NumRows = $Announcement->FetchAll();

echo DisplayAnnouncements($Announcement);

if ($NumRows > 0) {
	echo '
'  . "\n";
	echo '
Existing Announcements
' . "\n";
	echo MyDisplayAnnouncements($Announcement);
	echo '
' . "\n";

	$NumRows = $Announcement->FetchAllActive();
	if ($NumRows > 0) {
		echo '
'  . "\n";
		echo '
Active Announcements
' . "\n";
		echo MyDisplayAnnouncements($Announcement);
		echo '
' . "\n";

	} else {
		echo '
There are no active announcements.
';
	}

} else {
	echo '
There are no announcements.
';
}

?>

	<?
	echo freshports_SideBar();
	?>

<?
echo freshports_ShowFooter();
?>


text:
ACCEPTED

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
Bull. Brit. Mus. (Nat. Hist. ), Bot. 3:164. 1964

#### Original name
null

### Remarks
null


text:
const assert = require('assert');
const sinon = require('sinon');
const VersionNotificationsDataService = require('..');

describe('Version Notification Data Service', function () {
    afterEach(function () {
        sinon.restore();
    });

    describe('fetchNotification', function () {
        it('parses and filters out version notifications', async function () {
            const settingsService = {
                read: sinon.stub().resolves({
                    version_notifications: {
                        value: JSON.stringify([
                            'v3.4',
                            'v4.1',
                            'v5.0',
                            'v0.99'
                        ])
                    }
                })
            };

            const versionNotificationsDataService = new VersionNotificationsDataService({
                UserModel: {},
                ApiKeyModel: {},
                settingsService
            });

            assert.equal(await versionNotificationsDataService.fetchNotification('v4.1'), 'v4.1');
            assert.equal(await versionNotificationsDataService.fetchNotification('v9999.1'), undefined);
            assert.equal(await versionNotificationsDataService.fetchNotification('v5'), undefined);
            assert.equal(await versionNotificationsDataService.fetchNotification(), undefined);
        });
    });

    describe('saveNotification', function () {
        it('parses and filters out version notifications', async function () {
            const settingsService = {
                read: sinon.stub().resolves({
                    version_notifications: {
                        value: JSON.stringify([
                            'v3.4',
                            'v4.1',
                            'v5.0',
                            'v0.99'
                        ])
                    }
                }),
                edit: sinon.stub().resolves()
            };

            const versionNotificationsDataService = new VersionNotificationsDataService({
                UserModel: {},
                ApiKeyModel: {},
                settingsService
            });

            await versionNotificationsDataService.saveNotification('v5.0');
            assert.equal(settingsService.edit.called, false);

            await versionNotificationsDataService.saveNotification('v4.0');
            assert.equal(settingsService.edit.called, true);
            assert.deepEqual(settingsService.edit.firstCall.args, [[{
                key: 'version_notifications',
                value: JSON.stringify([
                    'v3.4',
                    'v4.1',
                    'v5.0',
                    'v0.99',
                    'v4.0'
                ])
            }], {
                context: {
                    internal: true
                }
            }]);
        });
    });

    describe('getNotificationEmails', function () {
        it('parses and filters out version notifications', async function () {
            const UserModel = {
                findAll: sinon
                    .stub()
                    .withArgs({
                        withRelated: ['roles'],
                        filter: 'status:active'
                    }, {
                        internal: true
                    })
                    .resolves({
                        toJSON: () => [{
                            email: 'simon@example.com',
                            roles: [{
                                name: 'Administrator'
                            }]
                        }, {
                            email: 'bob@example.com',
                            roles: [{
                                name: 'Owner'
                            }]
                        }, {
                            email: 'joe@example.com',
                            roles: [{
                                name: 'Publisher'
                            }]
                        }]
                    })
            };

            const versionNotificationsDataService = new VersionNotificationsDataService({
                UserModel,
                ApiKeyModel: {},
                settingsService: {}
            });

            const emails = await versionNotificationsDataService.getNotificationEmails();

            assert.equal(UserModel.findAll.called, true);
            assert.deepEqual(emails, ['simon@example.com', 'bob@example.com']);
        });
    });

    describe('getIntegrationName', function () {
        it('Queries for Content API key when such is provided', async function () {
            const ApiKeyModel = {
                findOne: sinon
                    .stub()
                    .withArgs({
                        secret: 'super_secret'
                    }, {
                        withRelated: ['integration']
                    })
                    .resolves({
                        relations: {
                            integration: {
                                get: () => 'live fast die young'
                            }
                        }
                    })
            };

            const versionNotificationsDataService = new VersionNotificationsDataService({
                UserModel: {},
                ApiKeyModel,
                settingsService: {}
            });

            const integrationName = await versionNotificationsDataService.getIntegrationName('super_secret', 'content');

            assert.equal(integrationName, 'live fast die young');
        });

        it('Queries for Admin API key when such is provided', async function () {
            const ApiKeyModel = {
                findOne: sinon
                    .stub()
                    .withArgs({
                        id: 'key_id'
                    }, {
                        withRelated: ['integration']
                    })
                    .resolves({
                        relations: {
                            integration: {
                                get: () => 'Tri Hita Karana'
                            }
                        }
                    })
            };

            const versionNotificationsDataService = new VersionNotificationsDataService({
                UserModel: {},
                ApiKeyModel,
                settingsService: {}
            });

            const integrationName = await versionNotificationsDataService.getIntegrationName('key_id', 'admin');

            assert.equal(integrationName, 'Tri Hita Karana');
        });
    });
});


text:
package docker

import (
	"fmt"
	"regexp"
	"testing"

	dc "github.com/fsouza/go-dockerclient"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

var contentDigestRegexp = regexp.MustCompile(`\A[A-Za-z0-9_\+\.-]+:[A-Fa-f0-9]+\z`)

func TestAccDockerImage_basic(t *testing.T) {
	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccDockerImageDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccDockerImageConfig,
				Check: resource.ComposeTestCheckFunc(
					resource.TestMatchResourceAttr("docker_image.foo", "latest", contentDigestRegexp),
				),
			},
		},
	})
}

func TestAccDockerImage_private(t *testing.T) {
	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccDockerImageDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAddDockerPrivateImageConfig,
				Check: resource.ComposeTestCheckFunc(
					resource.TestMatchResourceAttr("docker_image.foobar", "latest", contentDigestRegexp),
				),
			},
		},
	})
}

func TestAccDockerImage_destroy(t *testing.T) {
	resource.Test(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t) },
		Providers: testAccProviders,
		CheckDestroy: func(s *terraform.State) error {
			for _, rs := range s.RootModule().Resources {
				if rs.Type != "docker_image" {
					continue
				}

				client := testAccProvider.Meta().(*dc.Client)
				_, err := client.InspectImage(rs.Primary.Attributes["latest"])
				if err != nil {
					return err
				}
			}
			return nil
		},
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccDockerImageKeepLocallyConfig,
				Check: resource.ComposeTestCheckFunc(
					resource.TestMatchResourceAttr("docker_image.foobarzoo", "latest", contentDigestRegexp),
				),
			},
		},
	})
}

func TestAccDockerImage_data(t *testing.T) {
	resource.Test(t, resource.TestCase{
		PreCheck:                  func() { testAccPreCheck(t) },
		Providers:                 testAccProviders,
		PreventPostDestroyRefresh: true,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccDockerImageFromDataConfig,
				Check: resource.ComposeTestCheckFunc(
					resource.TestMatchResourceAttr("docker_image.foobarbaz", "latest", contentDigestRegexp),
				),
			},
		},
	})
}

func TestAccDockerImage_data_pull_trigger(t *testing.T) {
	resource.Test(t, resource.TestCase{
		PreCheck:                  func() { testAccPreCheck(t) },
		Providers:                 testAccProviders,
		PreventPostDestroyRefresh: true,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccDockerImageFromDataConfigWithPullTrigger,
				Check: resource.ComposeTestCheckFunc(
					resource.TestMatchResourceAttr("docker_image.foobarbazoo", "latest", contentDigestRegexp),
				),
			},
		},
	})
}

func testAccDockerImageDestroy(s *terraform.State) error {
	for _, rs := range s.RootModule().Resources {
		if rs.Type != "docker_image" {
			continue
		}

		client := testAccProvider.Meta().(*dc.Client)
		_, err := client.InspectImage(rs.Primary.Attributes["latest"])
		if err == nil {
			return fmt.Errorf("Image still exists")
		} else if err != dc.ErrNoSuchImage {
			return err
		}
	}
	return nil
}

const testAccDockerImageConfig = `
resource "docker_image" "foo" {
	name = "alpine:3.1"
}
`

const testAddDockerPrivateImageConfig = `
resource "docker_image" "foobar" {
	name = "gcr.io:443/google_containers/pause:0.8.0"
}
`

const testAccDockerImageKeepLocallyConfig = `
resource "docker_image" "foobarzoo" {
	name = "crux:3.1"
	keep_locally = true
}
`

const testAccDockerImageFromDataConfig = `
data "docker_registry_image" "foobarbaz" {
	name = "alpine:3.1"
}
resource "docker_image" "foobarbaz" {
	name = "${data.docker_registry_image.foobarbaz.name}"
	pull_triggers = ["${data.docker_registry_image.foobarbaz.sha256_digest}"]
}
`

const testAccDockerImageFromDataConfigWithPullTrigger = `
data "docker_registry_image" "foobarbazoo" {
	name = "alpine:3.1"
}
resource "docker_image" "foobarbazoo" {
	name = "${data.docker_registry_image.foobarbazoo.name}"
	pull_trigger = "${data.docker_registry_image.foobarbazoo.sha256_digest}"
}
`


text:
/* execute using mysql -u root < dbschema.sql */

DROP DATABASE IF EXISTS senecatest;
CREATE DATABASE senecatest;

USE senecatest;

CREATE TABLE foo (
  id VARCHAR(36),
  p1 VARCHAR(255),
  p2 VARCHAR(255),
  p3 VARCHAR(255),
  x INT,
  y INT,
  int_arr JSON,
  seneca VARCHAR(125),

  PRIMARY KEY(id),
  UNIQUE(x)
);

CREATE TABLE moon_bar (
  id VARCHAR(36),
  str VARCHAR(255),
  `int` INT,
  bol BOOLEAN,
  wen TIMESTAMP,
  mark VARCHAR(255),
  `dec` REAL,
  arr JSON,
  obj JSON,
  seneca VARCHAR(125),

  PRIMARY KEY(id)
);

CREATE TABLE players (
  id VARCHAR(36) NOT NULL,
  username VARCHAR(255) NOT NULL,
  points INT DEFAULT NULL,
  points_history JSON DEFAULT NULL,

  PRIMARY KEY (id),
  UNIQUE(username)
);

CREATE TABLE racers (
  id VARCHAR(36) NOT NULL,
  points INT NOT NULL DEFAULT 0,
  username VARCHAR(255) NOT NULL,
  favorite_car VARCHAR(255) NOT NULL,

  PRIMARY KEY (id),
  UNIQUE(username)
);

CREATE TABLE users (
  id VARCHAR(36) NOT NULL,
  username VARCHAR(255) NOT NULL,
  email VARCHAR(255) NOT NULL,

  PRIMARY KEY (id),
  UNIQUE(email)
);

CREATE TABLE customers (
  id VARCHAR(36) NOT NULL,
  first_name VARCHAR(255) NOT NULL,
  last_name VARCHAR(255) NOT NULL,
  credits INT NOT NULL,

  PRIMARY KEY (id),
  UNIQUE(first_name, last_name)
);

CREATE TABLE products (
  id VARCHAR(36) NOT NULL,
  price VARCHAR(255) NOT NULL,
  label VARCHAR(255) DEFAULT NULL,
  coolness_factor INT DEFAULT NULL,

  PRIMARY KEY (id),
  UNIQUE(label),
  UNIQUE(label, price)
);

CREATE TABLE incremental (
  id INT AUTO_INCREMENT,
  p1 VARCHAR(255),
  uniq INT,

  PRIMARY KEY (id),
  UNIQUE(uniq)
);


text:
<component name="libraryTable">
  <library name="Maven: mysql:mysql-connector-java:5.1.6">
    <CLASSES>
      <root url="jar://F:/maven_repositories/mysql/mysql-connector-java/5.1.6/mysql-connector-java-5.1.6.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://F:/maven_repositories/mysql/mysql-connector-java/5.1.6/mysql-connector-java-5.1.6-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://F:/maven_repositories/mysql/mysql-connector-java/5.1.6/mysql-connector-java-5.1.6-sources.jar!/" />
    </SOURCES>
  </library>
</component>


text:
<?php

namespace OpisColibri\User;

use Opis\Colibri\ItemCollectors\RouteCollector;
use Opis\Colibri\Collector as AbstractCollector;
use function Opis\Colibri\Functions\make;

class Collector extends AbstractCollector
{
    /**
     * @param RouteCollector $route
     */
    public function routes(RouteCollector $route)
    {
        $route->bind('user', function(){
            return make(IUserSession::class)->currentUser();
        });
    }
}


text:
package com.github.fritaly.dualcommander;

import java.io.File;
import java.util.Comparator;

import org.apache.commons.lang.Validate;

public final class ConfigurableFileComparator implements Comparator<File> {

	private final HasParentDirectory delegate;

	private SortCriteria criteria = SortCriteria.NAME;

	private boolean ascending = true;

	public ConfigurableFileComparator(HasParentDirectory delegate) {
		Validate.notNull(delegate, "The given delegate is null");

		this.delegate = delegate;
	}

	public ConfigurableFileComparator(HasParentDirectory delegate, SortCriteria criteria) {
		Validate.notNull(delegate, "The given delegate is null");
		Validate.notNull(criteria, "The given sort criteria is null");

		this.delegate = delegate;
		this.criteria = criteria;
	}

	public boolean isAscending() {
		return ascending;
	}

	public void setAscending(boolean ascending) {
		this.ascending = ascending;
	}

	public SortCriteria getCriteria() {
		return criteria;
	}

	public void setCriteria(SortCriteria criteria) {
		Validate.notNull(criteria, "The given sort criteria is null");

		this.criteria = criteria;
	}

	@Override
	public int compare(File f1, File f2) {
		// The parent directory always comes first
		if (f1.isDirectory() && f1.equals(this.delegate.getParentDirectory())) {
			return -1;
		}
		if (f2.isDirectory() && f2.equals(this.delegate.getParentDirectory())) {
			return +1;
		}

		// Compare the 2 files according to the current sort criteria
		final int result = criteria.compare(f1, f2);

		return ascending ? result : -1 * result;
	}
}


text:
const fs = require('fs')
const path = require('path')

module.exports = function save(name, obj) {
  const file = path.join(__dirname, '..', 'tmp', name + '.json')
  fs.writeFileSync(file, JSON.stringify(obj, null, 2), 'utf8')
  console.log('saved to ' + file)
}


text:
package com.googlecode.aluminumproject.libraries.functions;

import com.googlecode.aluminumproject.AluminumException;
import com.googlecode.aluminumproject.context.Context;
import com.googlecode.aluminumproject.context.DefaultContext;

import java.lang.reflect.Method;

import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

@SuppressWarnings("javadoc")
@Test(groups = {"core", "fast"})
public class StaticMethodInvokingFunctionTest {
	private Context context;

	@BeforeMethod
	public void createContext() {
		context = new DefaultContext();
	}

	@Test(expectedExceptions = AluminumException.class)
	public void callingInaccessibleFunctionShouldCauseException() throws NoSuchMethodException {
		new StaticMethodInvokingFunction(TestFunctions.class.getDeclaredMethod("inaccessible")).call(context);
	}

	@Test(expectedExceptions = AluminumException.class)
	public void callingFunctionThatThrowsExceptionShouldCauseException() throws NoSuchMethodException {
		Method divide = TestFunctions.class.getMethod("divide", Integer.TYPE, Integer.TYPE);

		new StaticMethodInvokingFunction(divide, 1, 0).call(context);
	}

	public void callingFunctionShouldInvokeMethod() throws NoSuchMethodException {
		Method divide = TestFunctions.class.getMethod("divide", Integer.TYPE, Integer.TYPE);

		Object result = new StaticMethodInvokingFunction(divide, 10, 5).call(context);
		assert result != null;
		assert result instanceof Integer;
		assert ((Integer) result).intValue() == 2;
	}
}


text:
package org.hibernate.test.annotations.identifiercollection;

import org.junit.Test;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;

import static org.junit.Assert.assertEquals;

/**
 * @author Emmanuel Bernard
 */
public class IdentifierCollectionTest extends BaseCoreFunctionalTestCase {
	@Test
	public void testIdBag() throws Exception {
		Passport passport = new Passport();
		passport.setName( "Emmanuel Bernard" );
		Stamp canada = new Stamp();
		canada.setCountry( "Canada" );
		passport.getStamps().add( canada );
		passport.getVisaStamp().add( canada );
		Stamp norway = new Stamp();
		norway.setCountry( "Norway" );
		passport.getStamps().add( norway );
		passport.getStamps().add(canada);
		Session s = openSession();
		Transaction tx = s.beginTransaction();
		s.persist( passport );
		s.flush();
		//s.clear();
		passport = (Passport) s.get( Passport.class, passport.getId() );
		int canadaCount = 0;
		for ( Stamp stamp : passport.getStamps() ) {
			if ( "Canada".equals( stamp.getCountry() ) ) canadaCount++;
		}
		assertEquals( 2, canadaCount );
		assertEquals( 1, passport.getVisaStamp().size() );
		tx.rollback();
		s.close();
	}

	@Override
	protected Class[] getAnnotatedClasses() {
		return new Class[] {
				Passport.class,
				Stamp.class
		};
	}
}


text:
struct CSTypeRef {
  uintptr_t a, b;
};

struct Range {
  uintptr_t location, length;
};

uintptr_t GetPtrauthMask(void) {
#if __has_feature(ptrauth_calls)
  return (uintptr_t)ptrauth_strip((void*)0x0007ffffffffffff, 0);
#else
  return (uintptr_t)~0ull;
#endif
}


text:
const credentials = { username: 'foo', password: 'bar' };

try {
  const jwt = await kuzzle.auth.login('local', credentials);

  // Prints the encrypted authentication token
  console.log(jwt);

  // Note: to get a different token, you actually need to wait at least
  // 1 second. Otherwise you do receive a refreshed token, but with the exact
  // same caracteristics, as the key depends on the timestamp in Epoch format
  await new Promise(resolve => setTimeout(resolve, 1000));

  // Prints:
  // { _id: '<user kuid>',
  //   jwt: '<a different encrypted authentication token>'
  //   expiresAt: 1553185334220,
  //   ttl: 3600000 }
  console.log(await kuzzle.auth.refreshToken());
} catch (error) {
  console.error(error.message);
}


text:
import { browser, by, element } from 'protractor';

export class WebappsRecipeappPage {
  navigateTo() {
    return browser.get('/recipe/list');
  }

  getParagraphText() {
    // console.log(element(by.css('app-root h1')).getText());
    return element.all(by.id('recipe-list'));
  }

  getRecipeComponents() {
    return element.all(by.id('recipe-component'));
  }
}


text:
package com.vaadin.tests.tickets;

import com.vaadin.server.ExternalResource;
import com.vaadin.server.LegacyApplication;
import com.vaadin.shared.ui.BorderStyle;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.LegacyWindow;
import com.vaadin.ui.Link;

public class Ticket2043 extends LegacyApplication {

    @Override
    public void init() {
        LegacyWindow w = new LegacyWindow(getClass().getSimpleName());
        setMainWindow(w);
        // setTheme("tests-tickets");
        GridLayout layout = new GridLayout(10, 10);
        w.setContent(layout);
        createUI(layout);
    }

    private void createUI(GridLayout layout) {
        Link l = new Link("Vaadin home (new 200x200 window, no decor, icon)",
                new ExternalResource("http://www.vaadin.com"), "_blank", 200,
                200, BorderStyle.NONE);

        layout.addComponent(l);
    }
}


text:
import React, { PropTypes, Component } from 'react';
import { connect } from 'react-redux';
import { fromJS } from 'immutable';
import {StyleSheet, css} from 'aphrodite';
import { selectProduct } from '~/reducers/products';
import { fetchReviews } from '~/reducers/reviews';
import { deleteHistoryItem } from '~/reducers/history';
import colors from '~/utils/colors';
import FontIcon from 'material-ui/FontIcon';
import classNames from 'classNames';
import { DisplayHistory, HistoryFooter } from '~/components/History';

export class HistoryView extends Component {
  static propTypes = {
    history: PropTypes.object,
    selectProduct: PropTypes.func,
    fetchReviews: PropTypes.func,
    deleteHistoryItem: PropTypes.func,
    firstName: PropTypes.string
  };

  render() {
    const { history, selectProduct, fetchReviews, deleteHistoryItem, firstName } = this.props;

    return (

            History
            <FontIcon
              className={classNames("material-icons", css(styles.iconStyle))}
              color={colors.primary1Color}>history
              </FontIcon>

{firstName}, here is your history.

          <DisplayHistory
            history={history}
            selectProduct={selectProduct}
            fetchReviews={fetchReviews}
            deleteHistoryItem={deleteHistoryItem} />
          <HistoryFooter />

    );
  }
}

const styles = StyleSheet.create({
  intro: {
    color: colors.primary1Color,
    textAlign: 'center',
    fontSize: '1.5em',
  },
  heading: {
    textAlign: 'center',
    fontSize: '2em',
    color: colors.primary2Color
  },
  iconStyle: {
    margin: '0 15px',
    verticalAlign: 'middle'
  }
});

const actions = {
  selectProduct,
  fetchReviews,
  deleteHistoryItem
};

const mapStateToProps = (state) => {
  const history = fromJS(state).getIn(['history', 'entities'], fromJS([]));
  const user = fromJS(state).getIn(['user', 'entities'], fromJS([]));
  const firstName = user.get('first_name');
  return {
    history: history,
    firstName: firstName
  };
};

export default connect(mapStateToProps, actions)(HistoryView);


text:
{% extends "admin/base.html" %}
{% import "_forms.html" as forms %}

{% block content %}

    {% if create %}
      Add new Role
    {% else %}
      Edit Role
    {% endif %}

        Warning! Editing the name of a role may break this application.
        Adding a new role will not give you new capabilities. To work with roles, you
        must change some of the application code.

  <form action="?{{ request.query_string }}" method="post">
    {{ forms.render(form) }}

      <input type="submit" class="btn btn-primary" value="save">
      Cancel

  </form>
{% endblock %}


text:
package org.wso2.carbon.registry.jcr;

import javax.jcr.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class RegistryNamespace implements NamespaceRegistry {

    List<String> prefix = new ArrayList();
    List<String> uris = new ArrayList();
    Map uri_nameSpace = new HashMap();
    Map prefix_nameSpace = new HashMap();

    public void registerNamespace(String s, String s1) throws NamespaceException, UnsupportedRepositoryOperationException, AccessDeniedException, RepositoryException {

        if ((s == null) || ((s.equals("jcr")) || (s.equals("nt")) || (s.contains("xml")) || (s.equals("mix")) || (s.equals("sv")))) {

            throw new NamespaceException();
        } else if ((s != null)) {
            prefix.add(s);
            uris.add(s1);
            uri_nameSpace.put(s1, s);
            prefix_nameSpace.put(s, s1);

        }

    }

    public void unregisterNamespace(String s) throws NamespaceException, UnsupportedRepositoryOperationException, AccessDeniedException, RepositoryException {

        if ((s == null) || ((s.equals("jcr")) || (s.equals("nt")) || (s.equals("xml")) || (s.equals("mix")) || (s.equals("sv")))) {

            throw new NamespaceException();
        } else if (uri_nameSpace.containsKey(s)) {
            uri_nameSpace.remove(s);
            prefix_nameSpace.remove(s);
        } else if(!uri_nameSpace.containsKey(s)) {
          throw  new NamespaceException("Cannot remove unregistered ");
        }

    }

    public String[] getPrefixes() throws RepositoryException {
        String temp = "";
        for (String s : prefix) {
            temp = ":" + s;

        }

        return temp.split(":");
    }

    public String[] getURIs() throws RepositoryException {
        String temp = "";
        for (String s : uris) {
            temp = ":" + s;

        }

        return temp.split(":");
    }

    public String getURI(String s) throws NamespaceException, RepositoryException {

        return prefix_nameSpace.get(s).toString();
    }

    public String getPrefix(String s) throws NamespaceException, RepositoryException {

        String pref = "";
        if (uri_nameSpace == null || uri_nameSpace.size() == 0) {
            throw new NamespaceException();

        } else if (uri_nameSpace.get(s) != null) {
            pref = uri_nameSpace.get(s).toString();

        }
        return pref;
    }
}


text:
void CModel::DoExportMesh(BOOL bInWorldSpcae)
{
	//
	// 1. µ¼³öλÓÚ¸ù½ÚµãµÄËùÓÐÍø¸ñ
	//
	m_pSkinMesh = new CMesh;
	_ASSERT(m_pSkinMesh);

	//
	// 2. µ¼³öÍø¸ñÍø¸ñ
	//    ×¢Òâ: ÒÔµÚ0ÕêµÄ״̬×÷ΪÃÉƤÍø¸ñ
	//
	m_pGameScene->SetStaticFrame(0);

	for (int indexNode = 0; indexNode < m_pGameScene->GetTopLevelNodeCount(); indexNode++) {
		IGameNode *pNode = m_pGameScene->GetTopLevelNode(indexNode);
		_ASSERT(pNode);

		DoExportMesh(pNode, m_pSkinMesh, bInWorldSpcae);
	}
}

//
// µ¼³ö¶¥µã¶¯»
//
void CModel::DoExportAnimVertex(void)
{
	//
	// 1. µ¼³öÿ¸ö¶¯»
	//
	for (vector<CAnimVertex*>::const_iterator itAnim = m_animVertexs.begin(); itAnim != m_animVertexs.end(); ++itAnim) {
		CAnimVertex *pAnim = *itAnim;
		_ASSERT(pAnim);

		//
		// 2. µ¼³ö¶¯»Ã¿Ò»Õê
		//
		for (int indexFrame = pAnim->pAnimInfo->startFrame; indexFrame <= pAnim->pAnimInfo->endFrame; indexFrame++) {
			CMesh *pMeshFrame = new CMesh;
			_ASSERT(pMeshFrame);

			m_pGameScene->SetStaticFrame(indexFrame);

			for (int indexNode = 0; indexNode < m_pGameScene->GetTopLevelNodeCount(); indexNode++) {
				IGameNode *pNode = m_pGameScene->GetTopLevelNode(indexNode);
				_ASSERT(pNode);

				DoExportMesh(pNode, pMeshFrame, FALSE);
			}

			pAnim->frames.push_back(pMeshFrame);
		}
	}
}

//
// µ¼³öÍø¸ñ
//
void CModel::DoExportMesh(IGameNode *pNode, CMesh *pMesh, BOOL bInWorldSpcae)
{
	_ASSERT(pNode);
	_ASSERT(pMesh);

	//
	// 1. µ¼³ö¸Ã½ÚµãÍø¸ñ
	//
	if (CSubMesh *pSubMesh = DoExportSubMesh(pNode, bInWorldSpcae)) {
		pMesh->subMeshs.push_back(pSubMesh);
	}

	//
	// 2. µ¼³ö×Ó½ÚµãÍø¸ñ
	//
	for (int indexChildNode = 0; indexChildNode < pNode->GetChildCount(); indexChildNode++) {
		IGameNode *pChildNode = pNode->GetNodeChild(indexChildNode);
		_ASSERT(pChildNode);

		DoExportMesh(pChildNode, pMesh, bInWorldSpcae);
	}
}

//
// µ¼³ö×ÓÍø¸ñ
//
CSubMesh* CModel::DoExportSubMesh(IGameNode *pNode, BOOL bInWorldSpcae)
{
	_ASSERT(pNode);

	//
	// 1. ¼ì²é½ÚµãÀàÐÍ, ²»´¦ÀíÒþ²ØÍø¸ñ
	//
	if (pNode->IsNodeHidden() ||
		pNode->GetIGameObject()->GetIGameType() != IGameObject::IGAME_MESH) {
		return NULL;
	}

	//
	// 2. ³õ'»¯
	//
	IGameMesh *pMesh = (IGameMesh *)pNode->GetIGameObject();
	IGameMaterial *pParentMaterial = pNode->GetNodeMaterial();
	_ASSERT(pMesh);

	pMesh->SetCreateOptimizedNormalList();
	pMesh->InitializeData();
	pMesh->InitializeBinormalData();

	if (pMesh->GetNumberOfFaces() <= 0 || pMesh->GetNumberOfVerts() <= 0) {
		return NULL;
	}

	//
	// 3. µ¼³öÍø¸ñÊý¾Ý
	//
	CSubMesh *pSubMesh = new CSubMesh(pMesh);
	_ASSERT(pSubMesh);

	Tab<int> mapChannels = pMesh->GetActiveMapChannelNum();
	pSubMesh->nNumTexChannel = mapChannels.Count();

	sprintf(pSubMesh->szName, "%s", pNode->GetName());

	if (pParentMaterial) {
		strcpy(pSubMesh->szMaterialName, pParentMaterial->GetMaterialName());
	}
	else {
		strcpy(pSubMesh->szMaterialName, "Null");
	}

	ReplaceInvalidChar(pSubMesh->szName);
	ReplaceInvalidChar(pSubMesh->szMaterialName);

	if (CMaterial *pMaterial = QueryMaterial(pSubMesh->szMaterialName)) {
		if (pMaterial->texUnits.find(ID_LM) != pMaterial->texUnits.end()) {
			strcpy(pSubMesh->szLightMapName, pMaterial->texUnits[ID_LM].c_str());
		}
	}

	pSubMesh->matrix = bInWorldSpcae ? pNode->GetWorldTM() : pNode->GetObjectTM();

	//
	// 3.1. µ¼³öÍø¸ñÊý¾Ý
	//
	for (int indexFace = 0; indexFace < pMesh->GetNumberOfFaces(); indexFace++) {
		FaceEx *pFaceEx = pMesh->GetFace(indexFace);
		_ASSERT(pFaceEx);

		CFace *pFace = new CFace(pFaceEx);
		_ASSERT(pFace);

		//
		// 3.1.1. ¶¥µãÊý¾Ý, ÌÞ³ýÖظ´¶¥µãÖؽ¨Èý½ÇÃæË÷Òý
		//
		for (int indexVertex = 0; indexVertex < 3; indexVertex++) {
			CVertex vertex;

			vertex.indexPosition = pFaceEx->vert[indexVertex];
			vertex.indexNormal = pFaceEx->norm[indexVertex];
			vertex.indexBinormal = pMesh->GetFaceVertexTangentBinormal(indexFace, indexVertex);

			vertex.position = pMesh->GetVertex(vertex.indexPosition, bInWorldSpcae ? false : true);
			vertex.normal = pMesh->GetNormal(vertex.indexNormal, bInWorldSpcae ? false : true);
			vertex.binormal = pMesh->GetBinormal(vertex.indexBinormal);

			if (pFaceEx->color[indexVertex] >= 0 && pFaceEx->color[indexVertex] < (DWORD)pMesh->GetNumberOfColorVerts() &&
				pFaceEx->alpha[indexVertex] >= 0 && pFaceEx->alpha[indexVertex] < (DWORD)pMesh->GetNumberOfAlphaVerts()) {
				float alpha;
				Point3 color;

				vertex.indexColor = pFaceEx->color[indexVertex];
				vertex.indexAlpha = pFaceEx->alpha[indexVertex];

				color = pMesh->GetColorVertex(vertex.indexColor);
				alpha = pMesh->GetAlphaVertex(vertex.indexAlpha);

				vertex.color.x = color.x;
				vertex.color.y = color.y;
				vertex.color.z = color.z;
				vertex.color.w = alpha;
			}

			for (int indexChannel = 0; indexChannel < mapChannels.Count(); indexChannel++) {
				Point3 texCoord;
				DWORD texMapping[3];

				if (pMesh->GetMapFaceIndex(mapChannels[indexChannel], indexFace, texMapping)) {
					if (pMesh->GetMapVertex(mapChannels[indexChannel], texMapping[indexVertex], texCoord)) {
						if (fabs(texCoord.z) < 0.001f) { // ×¢Òâ: ¹ýÂ˵ô·ÇÎÆÀí×ø±ê!!!
							vertex.indexTexCoords.push_back(texMapping[indexVertex]);
							vertex.texCoords.push_back(texCoord);
						}
					}
				}
			}

			pFace->indexVertices[indexVertex] = pSubMesh->QueryVertexID(vertex);

			if (pFace->indexVertices[indexVertex] < 0) {
				pFace->indexVertices[indexVertex] = (int)pSubMesh->vertices.size();

				CVertex *pVertex = new CVertex(vertex);
				_ASSERT(pVertex);

				pSubMesh->vertices.push_back(pVertex);
			}
		}

		//
		// 3.1.2. Èý½ÇÃæ²ÄÖÊ
		//      ×¢Òâ: ÔÚ.XÎļþ¸ñʽÖÐÈý½ÇÃæ²ÄÖÊË÷ÒýÖ¸µÄ²¢²»ÊÇÕû¸ömaxÎļþµÄ²ÄÖÊ
		//            Ë÷Òý, ¶øÊÇÈý½ÇÃæËùÔÚÍø¸ñʹÓõIJÄÖ'¯ºÏµÄË÷Òý
		//
		if (IGameMaterial *pSubMaterial = pMesh->GetMaterialFromFace(pFaceEx)) {
			char szMaterialName[_MAX_PATH];

			if (pParentMaterial == pSubMaterial) {
				sprintf(szMaterialName, "%s", pSubMaterial->GetMaterialName());
			}
			else {
				_ASSERT(pParentMaterial);
				sprintf(szMaterialName, "%s%s", pParentMaterial->GetMaterialName(), pSubMaterial->GetMaterialName());
			}

			ReplaceInvalidChar(szMaterialName);

			if (CMaterial *pMaterial = QueryMaterial(szMaterialName)) {
				pMaterial->isValid = TRUE;
			}

			// ÔÚµ±Ç°Íø¸ñ²ÄÖ'¯ºÏÖвéÕÒÈý½ÇÃæʹÓõIJÄÖÊ, ÈôÈý½ÇÃæʹÓõÄÊÇвÄÖÊ
			// ÔòÌí¼Ó¸Ã²ÄÖʵ½Íø¸ñ²ÄÖ'¯ºÏ
			if ((pFace->indexMaterial = pSubMesh->QueryMaterialID(szMaterialName)) < 0) {
				pFace->indexMaterial = (int)pSubMesh->materials.size();
				pSubMesh->materials.push_back(QueryMaterial(szMaterialName));
			}
		}

		// 3.1.4. Ìí¼ÓÈý½ÇÃæ
		pSubMesh->faces.push_back(pFace);
	}

	//
	// 4. µ¼³öÍø¸ñÊý¾Ý
	//
	if (IGameSkin* pSkin = (IGameSkin *)pMesh->GetIGameSkin()) {
		pSubMesh->isSkinMesh = TRUE;

		for (int indexVertex = 0; indexVertex < (int)pSubMesh->vertices.size(); indexVertex++) {
			CVertex *pVertex = pSubMesh->vertices[indexVertex];
			_ASSERT(pVertex);

			// 4.1. ¼Í¼¶¥µãÃÉƤÐÅÏ¢
			int numBones = 0;

			switch (pSkin->GetVertexType(pVertex->indexPosition)) {
			case IGameSkin::IGAME_RIGID:
				numBones = 1;
				break;
			case IGameSkin::IGAME_RIGID_BLENDED:
				numBones = pSkin->GetNumberOfBones(pVertex->indexPosition);
				break;
			}

			for (int indexBone = 0; indexBone < numBones; indexBone++) {
				CSkinInfo skinInfo;
				IGameNode *pBoneNode = pSkin->GetIGameBone(pVertex->indexPosition, indexBone);

				char szBoneName[_MAX_PATH];

				sprintf(szBoneName, "%s", pBoneNode->GetName());
				ReplaceInvalidChar(szBoneName);

				skinInfo.boneID = m_pBoneHierarchy->QueryBoneID(szBoneName);
				skinInfo.weight = pSkin->GetWeight(pVertex->indexPosition, indexBone);

				if (skinInfo.boneID >= 0) {
					pVertex->skinInfos.push_back(skinInfo);
				}
			}

			pVertex->NormalizeSkins();
			pSubMesh->nMaxSkinWeightsPerVertex = max(pSubMesh->nMaxSkinWeightsPerVertex, (int)pVertex->skinInfos.size());

			// 4.2. ¼Ç¼ӰÏìÍø¸ñ¶¥µãµÄ¹Ç÷À, ÒÔ¼°±»¹Ç÷ÀÓ°ÏìµÄ¶¥µãÁбí
			//      ×¢Òâ: ÔÚNormalizeSkinsºó×î¶àÖ»±£ÁôȨÖØ×î´óµÄ4¸ù¹Ç÷À, Òò´Ë±ØÐë
			//            ÔÚNormalizeSkinsÖ®ºóͳ¼Æ¹Ç÷ÀÓ°ÏìµÄÍø¸ñ¶¥µãÁбí
			for (vector<CSkinInfo>::const_iterator itSkin = pVertex->skinInfos.begin(); itSkin != pVertex->skinInfos.end(); ++itSkin) {
				CBone *pBone = m_pBoneHierarchy->bones[itSkin->boneID];
				_ASSERT(pBone);

				pBone->SetUsed();

				vector<int>* pBoneVertices = NULL;
				map<CBone*,vector<int>*>::const_iterator itBone = pSubMesh->bones.find(pBone);

				if (itBone == pSubMesh->bones.end()) {
					pBoneVertices = new vector<int>;
					_ASSERT(pBoneVertices);

					pSubMesh->bones[pBone] = pBoneVertices;
				}
				else {
					pBoneVertices = itBone->second;
				}

				pBoneVertices->push_back(indexVertex);
			}
		}
	}

	return pSubMesh;
}


text:
#import "ABI10_0_0RNSVGBrush.h"

@interface ABI10_0_0RNSVGBaseBrush : ABI10_0_0RNSVGBrush

- (instancetype)initWithArray:(NSArray *)array;

- (void)paint:(CGContextRef)context opacity:(CGFloat)opacity brushConverter:(ABI10_0_0RNSVGBrushConverter *)brushConverter;

@end


text:
module Capistrano
  class Error < RuntimeError; end

  class CaptureError < Error; end
  class NoSuchTaskError < Error; end
  class NoMatchingServersError < Error; end

  class RemoteError < Error
    attr_accessor :hosts
  end

  class ConnectionError < RemoteError; end
  class UploadError < RemoteError; end
  class CommandError < RemoteError; end
end


text:
module App {

    export class Main {

        title:string = 'Star Musics';

        constructor(public context:Context){

        }
    }

	angular.module('app')
            .controller('AppMain', ['Context',Main]);

}


text:
package org.switchyard.component.camel.file.model;

import org.switchyard.component.camel.common.model.file.GenericFileProducerBindingModel;

/**
 * Represents the configuration settings for a File Producer binding in Camel.
 *
 * @author Mario Antollini
 */
public interface CamelFileProducerBindingModel extends GenericFileProducerBindingModel {

}


text:
namespace cdc_ft {
namespace {

// Terminates a process by name.
// Returns true if the process was terminated.
// Returns false if the process was not found or if it failed to be terminated.
bool TerminateProcessByName(const char* name) {
  PROCESSENTRY32 entry;
  entry.dwSize = sizeof(PROCESSENTRY32);

  ScopedHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL));

  std::wstring wide_name = Util::Utf8ToWideStr(name);
  if (Process32First(snapshot.Get(), &entry)) {
    do {
      if (_wcsicmp(entry.szExeFile, wide_name.c_str()) != 0) continue;
      ScopedHandle hProcess(
          OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID));
      if (!TerminateProcess(hProcess.Get(), 0)) {
        LOG_ERROR("Failed to terminate process '%s'", name)
        return false;
      }
      return true;
    } while (Process32Next(snapshot.Get(), &entry));
  }

  LOG_ERROR("Failed to find process '%s'", name)
  return false;
}

// Filters for "echos" and puts all messages and levels into a vector.
class EchosTestLog : public Log {
 public:
  explicit EchosTestLog(LogLevel log_level) : Log(log_level) {}

  void WriteLogMessage(LogLevel level, const char* file, int line,
                       const char* func, const char* message) override {
    if (strncmp(message, "echos", strlen("echos")) == 0) {
      levels.push_back(level);
      messages.push_back(message);
    }
  }

  std::vector<LogLevel> levels;
  std::vector<std::string> messages;
};

class ProcessTest : public ::testing::Test {
 public:
  void SetUp() override {
    Log::Initialize(std::make_unique<ConsoleLog>(LogLevel::kInfo));
  }

  void TearDown() override { Log::Shutdown(); }

 protected:
  WinProcessFactory process_factory_;
};

TEST_F(ProcessTest, ProcessNotStarted) {
  ProcessStartInfo start_info;
  std::unique_ptr<Process> process = process_factory_.Create(start_info);
  EXPECT_NOT_OK(process->RunUntilExit());
  EXPECT_EQ(process->ExitCode(), Process::kExitCodeNotStarted);
}

TEST_F(ProcessTest, RunSimpleCommandSucceeds) {
  ProcessStartInfo start_info;
  start_info.command = "cmd /C \"echo\"";

  std::unique_ptr<Process> process = process_factory_.Create(start_info);
  EXPECT_OK(process->Start());
  EXPECT_OK(process->RunUntilExit());
  EXPECT_TRUE(process->HasExited());
  EXPECT_EQ(process->ExitCode(), 0u);
}

TEST_F(ProcessTest, RunSimpleCommandFails) {
  ProcessStartInfo start_info;
  start_info.command = "cmd /C \"dir /INVALID\"";

  std::unique_ptr<Process> process = process_factory_.Create(start_info);
  EXPECT_OK(process->Start());
  EXPECT_OK(process->RunUntilExit());
  EXPECT_TRUE(process->HasExited());
  EXPECT_EQ(process->ExitCode(), 1u);
}

TEST_F(ProcessTest, RunAndReadStdOut) {
  std::string std_out;
  std::string message = "hello world";

  ProcessStartInfo start_info;
  start_info.command = "cmd /C \"echo " + message + "\"";
  start_info.stdout_handler = [&std_out](const char* data, size_t) {
    std_out += data;
    return absl::OkStatus();
  };

  std::unique_ptr<Process> process = process_factory_.Create(start_info);
  EXPECT_OK(process->Start());
  EXPECT_OK(process->RunUntilExit());
  EXPECT_TRUE(process->HasExited());
  EXPECT_EQ(process->ExitCode(), 0u);
  EXPECT_EQ(std_out, message + "\r\n");
}

TEST_F(ProcessTest, RunAndReadStdOutAndStdErr) {
  std::string std_out;
  std::string std_err;
  std::string stdout_message = "stdout message";
  std::string stderr_message = "stderr message";

  ProcessStartInfo start_info;
  start_info.command = "cmd /C \"echo " + stdout_message + " & echo " +
                       stderr_message + " 1>&2\"";
  start_info.stdout_handler = [&std_out](const char* data, size_t) {
    std_out += data;
    return absl::OkStatus();
  };
  start_info.stderr_handler = [&std_err](const char* data, size_t) {
    std_err += data;
    return absl::OkStatus();
  };

  std::unique_ptr<Process> process = process_factory_.Create(start_info);
  EXPECT_OK(process->Start());
  EXPECT_OK(process->RunUntilExit());
  EXPECT_TRUE(process->HasExited());
  EXPECT_EQ(process->ExitCode(), 0u);
  EXPECT_EQ(std_out, stdout_message + " \r\n");
  EXPECT_EQ(std_err, stderr_message + " \r\n");
}

TEST_F(ProcessTest, RunWriteStdInAndReadStdOut) {
  std::string std_out;
  std::string message = "Foo\nBar\nfoo\nbar\nFar\nBoo";

  // Find all lines containing "F".
  ProcessStartInfo start_info;
  start_info.command = "findstr F";
  start_info.redirect_stdin = true;
  start_info.stdout_handler = [&std_out](const char* data, size_t) {
    std_out += data;
    return absl::OkStatus();
  };

  std::unique_ptr<Process> process = process_factory_.Create(start_info);
  EXPECT_OK(process->Start());
  EXPECT_OK(process->WriteToStdIn(message.data(), message.size()));
  process->CloseStdIn();
  EXPECT_OK(process->RunUntilExit());
  EXPECT_TRUE(process->HasExited());
  EXPECT_EQ(process->ExitCode(), 0u);
  EXPECT_EQ(std_out, "Foo\nFar\n");
}

TEST_F(ProcessTest, RunIoStressTest) {
  std::string std_out;
  std::string expected_stdout;

  // Find all lines containing "1".
  ProcessStartInfo start_info;
  start_info.command = "findstr 1";
  start_info.redirect_stdin = true;
  start_info.stdout_handler = [&std_out](const char* data, size_t) {
    std_out += data;
    return absl::OkStatus();
  };

  std::unique_ptr<Process> process = process_factory_.Create(start_info);
  EXPECT_OK(process->Start());

  // Write lots of lines to stdin.
  // Every other line starts with '1' and should be picked up by findstr.
  std::string message(2048, 'x');
  message.back() = '\n';
  const int num_lines = 1000;
  for (int n = 0; n < num_lines; ++n) {
    message[0] = n & 1 ? '1' : '2';
    if (n & 1) {
      expected_stdout += message;
    }
    EXPECT_OK(process->WriteToStdIn(message.data(), message.size()));
  }
  process->CloseStdIn();
  EXPECT_OK(process->RunUntilExit());
  EXPECT_TRUE(process->HasExited());
  EXPECT_EQ(process->ExitCode(), 0u);
  EXPECT_EQ(std_out, expected_stdout);
}

TEST_F(ProcessTest, RunUntil) {
  std::string std_out;

  // Find all lines containing "msg". "findstr" is a convenient command that
  // echoes stdin to stdout for matching lines. "echo" doesn't work with stdin.
  ProcessStartInfo start_info;
  start_info.command = "findstr stop";
  start_info.redirect_stdin = true;
  std::atomic_bool stop{false};
  start_info.stdout_handler = [&std_out, &stop](const char* data, size_t) {
    // Check whether someone sent the "stop" command.
    // Note: This runs in a background thread.
    std_out += data;
    stop = std_out.find("stop") != std::string::npos;
    return absl::OkStatus();
  };

  std::unique_ptr<Process> process = process_factory_.Create(start_info);
  EXPECT_OK(process->Start());

  // Send "msg stop" and check that it stops.
  std::string message = " stop\n";
  EXPECT_OK(process->WriteToStdIn(message.data(), message.size()));
  process->CloseStdIn();
  EXPECT_OK(process->RunUntil([&stop]() { return stop.load(); }));
  EXPECT_TRUE(stop);

  EXPECT_OK(process->RunUntilExit());
  EXPECT_TRUE(process->HasExited());
  EXPECT_EQ(process->ExitCode(), 0u);
}

TEST_F(ProcessTest, ForwardOutputToLogging) {
  Log::Shutdown();
  auto log_ptr = std::make_unique<EchosTestLog>(LogLevel::kInfo);
  EchosTestLog* log = log_ptr.get();
  Log::Initialize(std::move(log_ptr));

  const std::string stdout_message = "stdout message";
  const std::string stderr_message = "stderr message";

  ProcessStartInfo start_info;
  start_info.command = "cmd /C \"echo " + stdout_message + " & echo " +
                       stderr_message + " 1>&2\"";
  start_info.forward_output_to_log = true;
  start_info.name = "echos";

  EXPECT_OK(process_factory_.Run(start_info));

  ASSERT_EQ(log->messages.size(), 2);
  EXPECT_EQ(log->messages[0], "echos_stdout: " + stdout_message + " ");
  EXPECT_EQ(log->messages[1], "echos_stderr: " + stderr_message + " ");
}

TEST_F(ProcessTest, LogOutputLevelDetection) {
  Log::Shutdown();
  auto log_ptr = std::make_unique<EchosTestLog>(LogLevel::kVerbose);
  EchosTestLog* log = log_ptr.get();
  Log::Initialize(std::move(log_ptr));

  ProcessStartInfo start_info;
  start_info.command = "cmd /C \"echo VERBOSE msg1 && ";
  start_info.command += "echo DEBUG msg2 && ";
  start_info.command += "echo INFO msg3 && ";
  start_info.command += "echo WARNING msg4 && ";
  start_info.command += "echo ERROR msg5 && ";
  start_info.command += "echo msg6\"";
  start_info.forward_output_to_log = true;
  start_info.name = "echos";

  EXPECT_OK(process_factory_.Run(start_info));

  ASSERT_EQ(log->messages.size(), 6);
  ASSERT_EQ(log->levels.size(), 6);

  EXPECT_EQ(log->messages[0], "echos_stdout: VERBOSE msg1 ");
  EXPECT_EQ(log->messages[1], "echos_stdout: DEBUG msg2 ");
  EXPECT_EQ(log->messages[2], "echos_stdout: INFO msg3 ");
  EXPECT_EQ(log->messages[3], "echos_stdout: WARNING msg4 ");
  EXPECT_EQ(log->messages[4], "echos_stdout: ERROR msg5 ");
  EXPECT_EQ(log->messages[5], "echos_stdout: msg6");

  EXPECT_EQ(log->levels[0], LogLevel::kVerbose);
  EXPECT_EQ(log->levels[1], LogLevel::kDebug);
  EXPECT_EQ(log->levels[2], LogLevel::kInfo);
  EXPECT_EQ(log->levels[3], LogLevel::kWarning);
  EXPECT_EQ(log->levels[4], LogLevel::kError);
  EXPECT_EQ(log->levels[5], LogLevel::kInfo);
}

TEST_F(ProcessTest, Terminate) {
  ProcessStartInfo start_info;
  start_info.command = "timeout /T 30";
  // Prevents the process from shutting down immediately when run in background.
  // https://www.ibm.com/support/pages/timeout-command-run-batch-job-exits-immediately-and-returns-error-input-redirection-not-supported-exiting-process-immediately
  start_info.redirect_stdin = true;
  std::unique_ptr<Process> process = process_factory_.Create(start_info);
  EXPECT_OK(process->Start());
  EXPECT_EQ(process->ExitCode(), Process::kExitCodeStillRunning);
  EXPECT_OK(process->Terminate());
  EXPECT_EQ(process->ExitCode(), Process::kExitCodeNotStarted);
}

TEST_F(ProcessTest, TerminateAlreadyExited) {
  ProcessStartInfo start_info;
  start_info.command = "timeout /T 30";
  // Prevents the process from shutting down immediately when run in background.
  // https://www.ibm.com/support/pages/timeout-command-run-batch-job-exits-immediately-and-returns-error-input-redirection-not-supported-exiting-process-immediately
  start_info.redirect_stdin = true;
  std::unique_ptr<Process> process = process_factory_.Create(start_info);
  EXPECT_OK(process->Start());
  EXPECT_FALSE(process->HasExited());
  bool terminated = false;
  Stopwatch sw;
  while (sw.ElapsedSeconds() < 5 && !terminated) {
    terminated = TerminateProcessByName("timeout.exe");
    if (!terminated) Util::Sleep(1);
  }
  EXPECT_TRUE(terminated);
  EXPECT_OK(process->Terminate());
}

}  // namespace
}  // namespace cdc_ft