text:
<!DOCTYPE html>

    <title>Leaflet Draw Documentation</title>
    <meta charset="utf-8">

    <link rel="stylesheet" href="./css/normalize.css"/>
    <link rel="stylesheet" href="./css/main.css"/>

    <link rel="stylesheet" href="./highlight/styles/github-gist.css"/>

    <link rel="stylesheet" href="./examples/libs/leaflet.css"/>

    <link rel="stylesheet" href="../dist/leaflet.draw.css"/>

Leaflet Draw API reference

Draw

Usage example

Local Options

Options

Events

Controls

Draw.Toolbar

Examples

Leaflet 1.0.x

Leaflet 0.7.x

Draw Handlers

Draw.Feature

Draw.SimpleShape

Draw.Marker

Draw.Circle

Draw.Polyline

Draw.Rectangle

Draw.Polygon

Edit Handler

Edit.SimpleShape

Edit.Marker

Edit.Circle

Edit.Poly

Edit.Rectangle

EditToolbar.Edit

EditToolbar.Delete

Utility

GeometryUtil

LatLngUtil

LineUtil

Polygon

Polyline

TouchExtend

 This documentation is has been transcribed from the original README.MD to jsdoc's or natural docs style for
            use with Leafdoc. If you identify a typo or have a
            suggestion for this documentation, please feel free toedit the js comment blocks in the src directory,
            build with 'jake docs' and submit a pull request.

Leaflet 1.0+ Examples

Full Demo

Popup

Snapping

Edit Handlers

Leaflet 0.7+ Examples

Full Demo

Popup

Snapping

Edit Handlers

L.Draw

To add the draw toolbar set the option drawControl: true in the map options.

Usage example

     var map = L.map('map', {drawControl: true}).setView([51.505, -0.09], 13);
     L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
         attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
     }).addTo(map);

Adding the edit toolbar

To use the edit toolbar you must initialise the Leaflet.draw control and manually add it to the map.

     var map = L.map('map').setView([51.505, -0.09], 13);
     L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
         attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
     }).addTo(map);
     // FeatureGroup is to store editable layers
     var drawnItems = new L.FeatureGroup();
     map.addLayer(drawnItems);
     var drawControl = new L.Control.Draw({
         edit: {
             featureGroup: drawnItems
         }
     });
     map.addControl(drawControl);

The key here is the featureGroup option. This tells the plugin which FeatureGroup contains the layers that
should be editable. The featureGroup can contain 0 or more features with geometry types Point, LineString, and Polygon.
Leaflet.draw does not work with multigeometry features such as MultiPoint, MultiLineString, MultiPolygon,
or GeometryCollection. If you need to add multigeometry features to the draw plugin, convert them to a
FeatureCollection of non-multigeometries (Points, LineStrings, or Polygons).

L.drawLocal

The core toolbar class of the API — it is used to create the toolbar ui

Usage example

     var modifiedDraw = L.drawLocal.extend({
         draw: {
             toolbar: {
                 buttons: {
                     polygon: 'Draw an awesome polygon'
                 }
             }
         }
     });

The default state for the control is the draw toolbar just below the zoom control.
 This will allow map users to draw vectors and markers.
 Please note the edit toolbar is not enabled by default.

L.Draw.Toolbar

The toolbar class of the API — it is used to create the ui
This will be depreciated

Usage example

   var toolbar = L.Toolbar();
   toolbar.addToolbar(map);

Disabling a toolbar

If you do not want a particular toolbar in your app you can turn it off by setting the toolbar to false.

     var drawControl = new L.Control.Draw({
         draw: false,
         edit: {
             featureGroup: editableLayers
         }
     });

Disabling a toolbar item

If you want to turn off a particular toolbar item, set it to false. The following disables drawing polygons and
markers. It also turns off the ability to edit layers.

     var drawControl = new L.Control.Draw({
         draw: {
             polygon: false,
             marker: false
         },
         edit: {
             featureGroup: editableLayers,
             edit: false
         }
     });

Methods

Methods for modifying the toolbar

		Method
		Returns
		Description

		initialize(options)</nobr>
		void

Toolbar constructor

		enabled()</nobr>
		boolean

Gets a true/false of whether the toolbar is enabled

		disable()</nobr>
		void

Disables the toolbar

		addToolbar(map)</nobr>
		L.DomUtil

Adds the toolbar to the map and returns the toolbar dom element

		removeToolbar()</nobr>
		void

Removes the toolbar and drops the handler event listeners

L.Draw.Event

Use L.Draw.Event.EVENTNAME constants to ensure events are correct.

Usage example

map.on(L.Draw.Event.CREATED; function (e) {
   var type = e.layerType;
       layer = e.layer;
   if (type === 'marker') {
       // Do marker specific actions
   }
   // Do whatever else you need to. (save to db; add to map etc)
   map.addLayer(layer);
});

     map.on('draw:edited'; function (e) {
         var layers = e.layers;
         layers.eachLayer(function (layer) {
             //do whatever you want; most likely save back to db
         });
     });

Events

		Event
		Data
		Description

		draw:created
		PolyLine
		Polygon; Rectangle; Circle; Marker | String
Layer that was just created.
The type of layer this is. One of: polyline; polygon; rectangle; circle; marker
Triggered when a new vector or marker has been created.

		draw:edited
		LayerGroup
		List of all layers just edited on the map.
Triggered when layers in the FeatureGroup; initialised with the plugin; have been edited and saved.

		draw:deleted
		LayerGroup
		List of all layers just removed from the map.
Triggered when layers have been removed (and saved) from the FeatureGroup.

		draw:drawstart
		String
		The type of layer this is. One of:polyline; polygon; rectangle; circle; marker
Triggered when the user has chosen to draw a particular vector or marker.

		draw:drawstop
		String
		The type of layer this is. One of: polyline; polygon; rectangle; circle; marker
Triggered when the user has finished a particular vector or marker.

		draw:drawvertex
		LayerGroup
		List of all layers just being added from the map.
Triggered when a vertex is created on a polyline or polygon.

		draw:editstart
		String
		The type of edit this is. One of: edit
Triggered when the user starts edit mode by clicking the edit tool button.

		draw:editmove
		ILayer
		Layer that was just moved.
Triggered as the user moves a rectangle; circle or marker.

		draw:editresize
		ILayer
		Layer that was just moved.
Triggered as the user resizes a rectangle or circle.

		draw:editvertex
		LayerGroup
		List of all layers just being edited from the map.
Triggered when a vertex is edited on a polyline or polygon.

		draw:editstop
		String
		The type of edit this is. One of: edit
Triggered when the user has finshed editing (edit mode) and saves edits.

		draw:deletestart
		String
		The type of edit this is. One of: remove
Triggered when the user starts remove mode by clicking the remove tool button.

		draw:deletestop
		String
		The type of edit this is. One of: remove
Triggered when the user has finished removing shapes (remove mode) and saves.

L.Draw.Feature

Methods

		Method
		Returns
		Description

		initialize()</nobr>
		void

		enable()</nobr>
		void

Enables this handler

		addHooks()</nobr>
		void

Add's event listeners to this handler

		removeHooks()</nobr>
		void

Removes event listeners from this handler

		setOptions(object)</nobr>
		void

Sets new options to this handler

L.Draw.SimpleShape

Methods

		Method
		Returns
		Description

		initialize()</nobr>
		void

		addHooks()</nobr>
		void

		removeHooks()</nobr>
		void

	▶ Methods inherited from L.Draw.Feature

		Method
		Returns
		Description

		enable()</nobr>
		void

Enables this handler

		setOptions(object)</nobr>
		void

Sets new options to this handler

L.Draw.Marker

Methods

		Method
		Returns
		Description

		initialize()</nobr>
		void

		addHooks()</nobr>
		void

		removeHooks()</nobr>
		void

	▶ Methods inherited from L.Draw.Feature

		Method
		Returns
		Description

		enable()</nobr>
		void

Enables this handler

		setOptions(object)</nobr>
		void

Sets new options to this handler

L.Draw.Circle

Methods

		Method
		Returns
		Description

		initialize()</nobr>
		void

	▶ Methods inherited from L.Draw.SimpleShape

		Method
		Returns
		Description

		addHooks()</nobr>
		void

		removeHooks()</nobr>
		void

	▶ Methods inherited from L.Draw.Feature

		Method
		Returns
		Description

		enable()</nobr>
		void

Enables this handler

		setOptions(object)</nobr>
		void

Sets new options to this handler

L.Draw.Polyline

Methods

		Method
		Returns
		Description

		initialize()</nobr>
		void

		addHooks()</nobr>
		void

		removeHooks()</nobr>
		void

		deleteLastVertex()</nobr>
		void

		addVertex()</nobr>
		void

		completeShape()</nobr>
		void

	▶ Methods inherited from L.Draw.Feature

		Method
		Returns
		Description

		enable()</nobr>
		void

Enables this handler

		setOptions(object)</nobr>
		void

Sets new options to this handler

L.Draw.Rectangle

Methods

		Method
		Returns
		Description

		initialize()</nobr>
		void

	▶ Methods inherited from L.Draw.SimpleShape

		Method
		Returns
		Description

		addHooks()</nobr>
		void

		removeHooks()</nobr>
		void

	▶ Methods inherited from L.Draw.Feature

		Method
		Returns
		Description

		enable()</nobr>
		void

Enables this handler

		setOptions(object)</nobr>
		void

Sets new options to this handler

L.Draw.Polygon

Methods

		Method
		Returns
		Description

		initialize()</nobr>
		void

	▶ Methods inherited from L.Draw.Polyline

		Method
		Returns
		Description

		addHooks()</nobr>
		void

		removeHooks()</nobr>
		void

		deleteLastVertex()</nobr>
		void

		addVertex()</nobr>
		void

		completeShape()</nobr>
		void

	▶ Methods inherited from L.Draw.Feature

		Method
		Returns
		Description

		enable()</nobr>
		void

Enables this handler

		setOptions(object)</nobr>
		void

Sets new options to this handler

L.Edit.SimpleShape

Methods

		Method
		Returns
		Description

		intialize()</nobr>
		void

		addHooks()</nobr>
		void

		removeHooks()</nobr>
		void

		updateMarkers()</nobr>
		void

L.Edit.Marker

Methods

		Method
		Returns
		Description

		initialize()</nobr>
		void

		addHooks()</nobr>
		void

		removeHooks()</nobr>
		void

L.Edit.Circle

Methods

	▶ Methods inherited from L.Edit.SimpleShape

		Method
		Returns
		Description

		intialize()</nobr>
		void

		addHooks()</nobr>
		void

		removeHooks()</nobr>
		void

		updateMarkers()</nobr>
		void

L.Edit.Polyline

Methods

		Method
		Returns
		Description

		initialize()</nobr>
		void

		addHooks()</nobr>
		void

		removeHooks()</nobr>
		void

		updateMarkers()</nobr>
		void

L.Edit.Rectangle

Methods

	▶ Methods inherited from L.Edit.SimpleShape

		Method
		Returns
		Description

		intialize()</nobr>
		void

		addHooks()</nobr>
		void

		removeHooks()</nobr>
		void

		updateMarkers()</nobr>
		void

L.EditToolbar.Edit

Methods

		Method
		Returns
		Description

		intialize()</nobr>
		void

		enable()</nobr>
		void

		disable()</nobr>
		void

		addHooks()</nobr>
		void

		removeHooks()</nobr>
		void

		revertLayers()</nobr>
		void

		save()</nobr>
		void

L.EditToolbar.Delete

Methods

		Method
		Returns
		Description

		intialize()</nobr>
		void

		enable()</nobr>
		void

		disable()</nobr>
		void

		addHooks()</nobr>
		void

		removeHooks()</nobr>
		void

		revertLayers()</nobr>
		void

		save()</nobr>
		void

L.GeometryUtil

Methods

		Method
		Returns
		Description

		geodesicArea()</nobr>
		void

		readableArea()</nobr>
		void

		readableDistance()</nobr>
		void

L.LatLngUtil

Methods

		Method
		Returns
		Description

		cloneLatLngs()</nobr>
		void

		cloneLatLng()</nobr>
		void

L.LineUtil

Methods

		Method
		Returns
		Description

		segmentsIntersect()</nobr>
		void

Checks to see if two line segments intersect. Does not handle degenerate cases.
http://compgeom.cs.uiuc.edu/~jeffe/teaching/373/notes/x06-sweepline.pdf

L.Polygon

Methods

		Method
		Returns
		Description

		intersects()</nobr>
		boolean

Checks a polygon for any intersecting line segments. Ignores holes.

L.Polyline

Methods

		Method
		Returns
		Description

		intersects()</nobr>
		void

Check to see if this polyline has any linesegments that intersect.
NOTE: does not support detecting intersection for degenerate cases.

		newLatLngIntersects()</nobr>
		void

Check for intersection if new latlng was added to this polyline.
NOTE: does not support detecting intersection for degenerate cases.

		newPointIntersects()</nobr>
		void

Check for intersection if new point was added to this polyline.
newPoint must be a layer point.
NOTE: does not support detecting intersection for degenerate cases.

L.Map.TouchExtend

Methods

		Method
		Returns
		Description

		initialize()</nobr>
		void

Sets TouchExtend private accessor variables

		addHooks()</nobr>
		void

Adds dom listener events to the map container

		removeHooks()</nobr>
		void

Removes dom listener events from the map container

L.Control.Draw

Methods

		Method
		Returns
		Description

		initialize()</nobr>
		void

Initializes draw control, toolbars from the options

		onAdd()</nobr>
		container

Adds the toolbar container to the map

		onRemove()</nobr>
		void

Removes the toolbars from the map toolbar container

		setDrawingOptions(options)</nobr>
		void

Sets options to all toolbar instances

L.Draw.Tooltip

The tooltip class — it is used to display the tooltip while drawing
This will be depreciated

Usage example

    var tooltip = L.Draw.Tooltip();

Methods

Methods for modifying draw state

		Method
		Returns
		Description

		initialize(map)</nobr>
		void

Tooltip constructor

		dispose()</nobr>
		void

Remove Tooltip DOM and unbind events

		updateContent(labelText)</nobr>
		this

Changes the tooltip text to string in function call

		updatePosition(latlng)</nobr>
		this

Changes the location of the tooltip

		showAsError()</nobr>
		this

Applies error class to tooltip

		removeError()</nobr>
		this

Removes the error class from the tooltip

L.DrawToolbar

Methods

		Method
		Returns
		Description

		initialize()</nobr>
		void

		getModeHandlers()</nobr>
		void

		getActions()</nobr>
		void

		setOptions()</nobr>
		void

L.EditToolbar

Methods

		Method
		Returns
		Description

		intialize()</nobr>
		void

		getModeHandlers()</nobr>
		void

		getActions()</nobr>
		void

		addToolbar()</nobr>
		void

		removeToolbar()</nobr>
		void

		disable()</nobr>
		void

L.Edit.PolyVerticesEdit

Methods

		Method
		Returns
		Description

		intialize()</nobr>
		void

		addHooks()</nobr>
		void

		removeHooks()</nobr>
		void

		updateMarkers()</nobr>
		void

L.Marker.Touch

This isn't full Touch support. This is just to get makers to also support dom touch events after creation

#TODO: find a better way of getting markers to support touch.

Install

You have four methods of installing Leaflet.Draw, copy the leaflet.draw.js, css, and images from dist and embed directly
into your application.

npm

To install the plugin run npm install leaflet-draw via command line in your project.
You must also require this in your project like so: var leafletDraw = require('leaflet-draw');

bower

To install the plugin run bower install leaflet-draw.

Builder

There is a custom builder at ../build/build.html to help make a custom package of Leaflet.Draw
with the command line.

CDN's

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.2/leaflet.draw.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.2/leaflet.draw.js"></script>

Options

You can configure the plugin by using the different options listed here. If you identify a typo or have a suggestion
for this section of the documentation, please edit docs-misc.leafdoc in the build directory.

Control.Draw

Option
Type
Default
Description

position
String
'topleft'
The initial position of the control (one of the map corners). See control positions.

draw
DrawOptions
{}
The options used to configure the draw toolbar.

edit
EditPolyOptions
false
The options used to configure the edit toolbar.

DrawOptions

Option
Type
Default
Description

polyline
PolylineOptions
{ }
Polyline draw handler options. Set to false to disable handler.

polygon
PolygonOptions
{ }
Polygon draw handler options. Set to false to disable handler.

rectangle
RectangleOptions
{ }
Rectangle draw handler options. Set to false to disable handler.

circle
CircleOptions
{ }
Circle draw handler options. Set to false to disable handler.

marker
MarkerOptions
{ }
Marker draw handler options. Set to false to disable handler.

PolylineOptions

Option
Type
Default
Description

allowIntersection
Bool
true
Determines if line segments can cross.

drawError
Object
See code
Configuration options for the error that displays if an intersection is detected.

guidelineDistance
Number
20
Distance in pixels between each guide dash.

shapeOptions
Leaflet Polyline options
See code
The options used when drawing the polyline/polygon on the map.

metric
Bool
true
Determines which measurement system (metric or imperial) is used.

zIndexOffset
Number
2000
This should be a high number to ensure that you can draw over all other layers on the map.

repeatMode
Bool
false
Determines if the draw tool remains enabled after drawing a shape.

PolygonOptions

Option
Type
Default
Description

showArea
Bool
false
Show the area of the drawn polygon in m², ha or km². The area is only approximate and become less accurate the larger the polygon is.

RectangleOptions

Option
Type
Default
Description

shapeOptions
Leaflet Path options
See code
The options used when drawing the rectangle on the map.

repeatMode
Bool
false
Determines if the draw tool remains enabled after drawing a shape.

showRadius
Bool
true
Show the area of the drawn circle in m², ha or km². The area is only approximate and become less accurate the larger the circle is.

CircleOptions

Option
Type
Default
Description

shapeOptions
Leaflet Path options
See code
The options used when drawing the circle on the map.

repeatMode
Bool
false
Determines if the draw tool remains enabled after drawing a shape.

MarkerOptions

Option
Type
Default
Description

icon
Leaflet Icon
L.Icon.Default()
The icon displayed when drawing a marker.

zIndexOffset
Number
2000
This should be a high number to ensure that you can draw over all other layers on the map.

repeatMode
Bool
false
Determines if the draw tool remains enabled after drawing a shape.

EditPolyOptions

Option
Type
Default
Description

featureGroup
Leaflet FeatureGroup
null
This is the FeatureGroup that stores all editable shapes. THIS IS REQUIRED FOR THE EDIT TOOLBAR TO WORK

edit
EditHandlerOptions
{ }
Edit handler options. Set to false to disable handler.

remove
DeleteHandlerOptions
{ }
Delete handler options. Set to false to disable handler.

poly
EditPolyOptions
{ }
Set polygon editing options

allowIntersection
Bool
true
Determines if line segments can cross.

EditHandlerOptions

Option
Type
Default
Description

selectedPathOptions
Leaflet Path options
See code
The path options for how the layers will look while in edit mode. If this is set to null the editable path options will not be set.

Note: To maintain the original layer color of the layer use maintainColor: true within selectedPathOptions.
E.g. The edit options below will maintain the layer color and set the edit opacity to 0.3.

{
    selectedPathOptions: {
        maintainColor: true,
        opacity: 0.3
    }
}

version

A constant that represents the Leaflet.Draw version in use.

    L.drawVersion; // contains "0.4.2" (or whatever version is currently in use)

© 2012 - 2017 Leaflet and Leaflet
            Organization

            Thanks to all our Contributors

            Documentation generated with Leafdoc


text:
package org.apache.ibatis.mapping;

import java.util.Collections;
import java.util.Map;

import org.apache.ibatis.session.Configuration;

/**
 * @author Clinton Begin
 */
/**
 * 鉴别器
 * 有时一个查询也许返回很多不同数据类型的结果集。
 * 鉴别器的表现很像 Java 语言中的 switch 语句。
 */
public class Discriminator {

  private ResultMapping resultMapping;
  private Map<String, String> discriminatorMap;

  Discriminator() {
  }

  public static class Builder {
    private Discriminator discriminator = new Discriminator();

    public Builder(Configuration configuration, ResultMapping resultMapping, Map<String, String> discriminatorMap) {
      discriminator.resultMapping = resultMapping;
      discriminator.discriminatorMap = discriminatorMap;
    }

    public Discriminator build() {
      assert discriminator.resultMapping != null;
      assert discriminator.discriminatorMap != null;
      assert !discriminator.discriminatorMap.isEmpty();
      //lock down map
      discriminator.discriminatorMap = Collections.unmodifiableMap(discriminator.discriminatorMap);
      return discriminator;
    }
  }

  public ResultMapping getResultMapping() {
    return resultMapping;
  }

  public Map<String, String> getDiscriminatorMap() {
    return discriminatorMap;
  }

  public String getMapIdFor(String s) {
    return discriminatorMap.get(s);
  }

}

redpajama_set_name: RedPajamaGithub


text:
// MIT © 2016 azu
"use strict";
/* eslint-disable */
export default class AbstractBacker {
    /**
     * @param {string} filePath
     * @returns {boolean}
     */
    shouldExecute({filePath}) {
        return true;
    }

    /**
     * @param {TextLintResult} result
     * @returns {boolean}
     */
    didExecute({result}) {
        return true;
    }

    /**
     * call when after all execution is completed
     */
    afterAll(){

    }
}


text:
import _ from 'lodash';
import React, { Component, PropTypes } from 'react';
import './LineItemGroup.scss';

class LineItemGroup extends Component {

  static propTypes = {
    groupSpendingData: PropTypes.object,
    totalSpending: PropTypes.number,
  };

  static defaultProps = {
    incomeTax: 0,
    payrollTax: 0,
    totalSpending: 0,
  };

  render() {
    const taxIsNan = isNaN(this.props.incomeTax) && isNaN(this.props.payrollTax);
    let taxPaid = 0;
    if (!taxIsNan) {
      taxPaid = (this.props.incomeTax || 0) + (this.props.payrollTax || 0);
    }

    return (

          {
            _.map(this.props.groupSpendingData.activities, (lineItem, i) => {
              // Get the percentage of overall spending that this lineItem represents, and
              // then convert that into a fraction of the user's tax bill.
              let displayedAmount = '–';
              if (!taxIsNan) {
                const amountPaid = (lineItem.spending / this.props.totalSpending) * taxPaid;
                if (amountPaid < 10) {
                  displayedAmount = `$${amountPaid.toFixed(2)}`;
                }
                else {
                  displayedAmount = `$${Math.round(amountPaid)}`;
                }
              }

              return (
                <div key={`line-item-${i}`} className='c-line-item-group__item'>

              );
            })
          }

    );
  }

}

export default LineItemGroup;


text:
package com.smbtec.xo.tinkerpop.blueprints.test.relation.implicit.composite;

import java.lang.annotation.Retention;

import com.smbtec.xo.tinkerpop.blueprints.api.annotation.Edge;

import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Edge
@Retention(RUNTIME)
public @interface ImplicitOneToOne {
}


text:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';
import { AppActions } from './app.actions';
import { AppDispatcher } from './app.dispatcher';
import { AppStore } from './app.store';

@NgModule({
  imports: [
    BrowserModule
  ],
  declarations: [
    AppComponent
  ],
  providers:  [
    AppActions,
    AppDispatcher,
    AppStore
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}


text:
package eu.scape_project.planning.model.tree;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Transient;
import javax.validation.Valid;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import eu.scape_project.planning.model.Alternative;
import eu.scape_project.planning.model.EvaluationStatus;
import eu.scape_project.planning.model.IChangesHandler;
import eu.scape_project.planning.model.ITouchable;
import eu.scape_project.planning.model.SampleAggregationMode;
import eu.scape_project.planning.model.TargetValueObject;
import eu.scape_project.planning.model.Values;
import eu.scape_project.planning.model.measurement.EvaluationScope;
import eu.scape_project.planning.model.measurement.Measure;
import eu.scape_project.planning.model.scales.FloatRangeScale;
import eu.scape_project.planning.model.scales.FreeStringScale;
import eu.scape_project.planning.model.scales.IntRangeScale;
import eu.scape_project.planning.model.scales.OrdinalScale;
import eu.scape_project.planning.model.scales.PositiveFloatScale;
import eu.scape_project.planning.model.scales.PositiveIntegerScale;
import eu.scape_project.planning.model.scales.Scale;
import eu.scape_project.planning.model.scales.ScaleType;
import eu.scape_project.planning.model.scales.YanScale;
import eu.scape_project.planning.model.transform.NumericTransformer;
import eu.scape_project.planning.model.transform.OrdinalTransformer;
import eu.scape_project.planning.model.transform.Transformer;
import eu.scape_project.planning.model.values.FreeStringValue;
import eu.scape_project.planning.model.values.INumericValue;
import eu.scape_project.planning.model.values.IOrdinalValue;
import eu.scape_project.planning.model.values.TargetValue;
import eu.scape_project.planning.model.values.TargetValues;
import eu.scape_project.planning.model.values.Value;
import eu.scape_project.planning.validation.ValidationError;

/**
 * A leaf node in the objective tree does not contain any children, but instead
 * defines the actual measurement scale to be used and points to conforming
 * valueMap. Part of the implementation of the Composite design pattern, cf.
 * TreeNode, Node - Leaf corresponds to the Leaf, surprise!
 *
 * @author Christoph Becker
 */
@Entity
@NamedQuery(name = "getLaevesById", query = "SELECT l from Leaf l WHERE id IN (:leafList)")
@DiscriminatorValue("L")
public class Leaf extends TreeNode {

    private static final long serialVersionUID = -6561945098296876384L;

    private static final Logger log = LoggerFactory.getLogger(Leaf.class);

    /**
     * The {@link Transformer} stores the user-set transformation rules. There
     * are two types:
     *

     *
numeric transformation (thresholds)

     *
ordinal transformation: direct mapping from values to numeric values.
     * This also applies to boolean scales.

     */
    @OneToOne(cascade = CascadeType.ALL)
    private Transformer transformer;

    /**
     * determines the aggregation mode for the values of the sample records(!)
     * WITHIN one alternative. The overall aggregation method over the tree is a
     * different beer! Is initialised with {@link SampleAggregationMode#WORST},
     * but later initialised according to the {@link Scale} in
     * {@link #setDefaultAggregation()}
     */
    @Enumerated
    private SampleAggregationMode aggregationMode = SampleAggregationMode.WORST;

    /**
     * specifies the {@link Scale} to be used for evaluating experiment outcomes
     */
    @Valid
    @OneToOne(cascade = CascadeType.ALL)
    private Scale scale;

    /**
     * We have values actually per
     *

     *
preservation strategy ({@link Alternative}),

     *
decision criteria (leaf node), AND

     *
sample record.

     *

     * So we have another encapsulation: {@link Values}
     *
     * Note: For some databases it might be necessary to rename the key member
     * of Map, as it might be a reserved keyword, e.g.: Derby
     */
    // @IndexColumn(name = "key_name")
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    private Map<String, Values> valueMap = new HashMap<String, Values>();

    /**
     * The measure this decision criterion is mapped to.
     *
     * Note that orphanRemoval does not work on OneToOne relationships if the
     * orphan is replaced by a new entity ({@link https
     * ://hibernate.onjira.com/browse/HHH-6484} If you want to do so, you have
     * to take care of deleting the orphan yourself
     *
     */
    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
    private Measure measure;

    public Map<String, Values> getValueMap() {
        return valueMap;
    }

    public void setValueMap(Map<String, Values> v) {
        this.valueMap = v;
    }

    /**
     * @return the unweighted result value for an Alternative. This is
     *         the aggregation of all transformed evaluation values
     * @see #aggregateValues(TargetValues)
     * @see #transformValues(Alternative)
     */
    public double getResult(Alternative a) {
        return aggregateValues(transformValues(a));
    }

    /**
     * Aggregates values of one Alternative, depending on the
     * {@link #aggregationMode}
     *
     * @param values
     *            the TargetValue element over which aggregation shall be
     *            performed according to the {@link #aggregationMode}
     * @return a single number denoting the aggregated, transformed, unweighted
     *         result value of this Leaf.
     */
    private double aggregateValues(TargetValues values) {
        if (aggregationMode == SampleAggregationMode.WORST) {
            return values.worst();
        } else {
            return values.average();
        }
    }

    /**
     * Returns the {@link TargetValues evaluation values} for each SampleObject
     * for one {@link Alternative} already transformed from the measurement
     * scale to the final scale used for ranking.
     *
     * @see #getResult(Alternative)
     * @param a
     *            the {@link Alternative} for which evaluation values shall be
     *            returned
     * @return {@link TargetValues}
     */
    public TargetValues transformValues(Alternative a) {
        Values v = valueMap.get(a.getName());
        if (transformer == null) {
            log.error("transformer is null!");
        }
        return transformer.transformValues(v);
    }

    public Leaf() {
    }

    public Transformer getTransformer() {
        return transformer;
    }

    public void setTransformer(Transformer transformer) {
        this.transformer = transformer;
    }

    public void setValues(String alternative, Values values) {
        valueMap.put(alternative, values);
    }

    public Values getValues(String alternative) {
        return valueMap.get(alternative);
    }

    public Scale getScale() {
        return scale;
    }

    /**
     * The standard setter sets the scale of the leaf to the given instance
     * scale, but leaves {@link #transformer} and
     * {@link #aggregationMode} unchanged.
     *
     * Important: If you want to change the type of the scale, e.g. from
     * Boolean to Numeric, you have to take transformation settings and
     * aggregation mode into account. Thus you need to use
     * {@link #changeScale(Scale)} instead, which also takes care of the
     * transformer and aggregationMode.
     *
     * @param scale
     */
    public void setScale(Scale scale) {
        this.scale = scale;
    }

    /**
     * When a scale is changed e.g. from Boolean to a number, all evaluation
     * values that have already been associated become invalid and need to be
     * removed.
     *
     * This function resets all evaluation {@link Values} associated with this
     * Leaf, which depend on the {@link Scale} that is set. This means that if
     * the scale is not set, all Values are removed. If the scale is set, we
     * iterate into all values for all alternatives and samplerecords and check
     * if the scale in there differs from the scale that has been set. If yes,
     * we remove the values. Furthermore, if this Leaf has been changed from an
     * Object criterion to an Action criterion, all excess values are removed.
     */
    public void resetValues(List<Alternative> list) {
        if (scale == null) {
            /*
             * there is no scaletype set, so we remove existing values
             */
            valueMap.clear();
            return;
        }
        // Get the Values for each Alternative
        for (Alternative a : list) {
            Values values = valueMap.get(a.getName());
            if (values == null) {
                log.debug("values is null for alternative " + a.getName() + " in Leaf " + name);
                continue;
            }
            // Check value of each sample object for conformance with Scale -
            // if we find a changed scale, we reset everything.
            // It might be faster not to check ALL values, but this is safer.
            for (Value value : values.getList()) {
                // If the scale has changed, we reset all evaluation values of
                // this Alternative:
                // this may look strange, but it is OK that the scale of a value
                // is null.
                // If there have been values before, you change the scale and
                // then save - the linkage is lost
                // if (value.getScale() == null) {
                // LogFactory.getLog(Leaf.class).error("WHAT THE...?? no scale for value"+getName());
                // } else {
                if ((value.getScale() == null) || (!value.getScale().getClass().equals(scale.getClass()))) {
                    if (!a.isDiscarded()) { // for discarded alternatives,
                                            // that's ok.
                        log.debug("Leaf " + this.getName() + " Class: " + value.getClass() + " not like "
                            + scale.getClass() + ". RESETTING the valuemap now!");
                        valueMap.clear(); // reset all values
                        return;
                    }
                }
                // }
                // PLEASE NOTE- WRT ORDINAL RESTRICTIONS:
                // we do NOT reset values when the restriction has changed, such
                // as
                // the ordinal values or the boundaries.
                // Instead, those values that are still valid remain, the others
                // will be checked
                // and need to be corrected anyway in the evaluate step.
                // Should be nicer for the user. If we find out this leads to
                // validation problems
                // (which shouldnt be the case because the data types are valid
                // as long as the scale
                // doesnt change) then we will reset the values even if just the
                // restriction changes.
            }
            /*
             * maybe this leaf was set to single, reset all values
             */
            if (isSingle() && values.size() > 1) {
                valueMap.clear();
                return;
            }
        }
    }

    /**
     * Sets a default transformer corresponding to the current scale of this
     * leaf. The transformer is initialized with default-values.
     *
     * If no scale is set, the current transformer will be set to null!
     */
    public void setDefaultTransformer() {
        if (scale == null) {
            log.warn("Can't set DefaultTransformer, no scale set!");
            this.setTransformer(null);
            return;
        }
        if (ScaleType.ordinal.equals(scale.getType())) {
            OrdinalTransformer t = new OrdinalTransformer();
            this.setTransformer(t);
            if (!(scale instanceof FreeStringScale)) {
                Map<String, TargetValueObject> map = t.getMapping();
                OrdinalScale o = (OrdinalScale) scale;
                for (String s : o.getList()) {
                    map.put(s, new TargetValueObject());
                }
            }
        } else {
            NumericTransformer t = new NumericTransformer();
            this.setTransformer(t);
        }
    }

    /**
     * Returns the fully qualified class-name ("canonical name") of the current
     * scale
     *
     * @return the canonical classname of the scale, or null if no scale is set
     */
    public String getScaleByClassName() {
        if (scale == null)
            return null;
        else
            return scale.getClass().getCanonicalName();
    }

    /**
     * Sets the Scale according to the provided name, IF the name differs from
     * the classname of the currently set {@link #scale}
     *
     * resets property mappings, if present.
     *
     * @param className
     *            canonical class name of the new scale
     */
    public void setScaleByClassName(String className) {
        Scale scaleType = null;
        try {
            if (className != null && !"".equals(className)) {
                scaleType = (Scale) Class.forName(className).newInstance();
            }
        } catch (InstantiationException e) {
        } catch (IllegalAccessException e) {
        } catch (ClassNotFoundException e) {
        }
        changeScale(scaleType);
    }

    /**
     * Changes the {@link Scale} to the provided one. if the new scale differs
     * from the type of the current scale, it also:
     *

     *
sets: default aggregators and transformers.

     *

     * It does not set a reference to the provided scale, but clones it instead!
     *
     * @param newScale
     *            the new Scale to be set
     */
    public void changeScale(Scale newScale) {
        if (newScale == null) {
            log.debug("CHECK THIS: setting scale to null.");
            scale = null;
            // remove mapping
            setMeasure(null);
        } else {
            // If
            if ((this.scale == null) // we don't have a scale yet
                || (!scale.getClass().getName().equals(newScale.getClass().getName())))
            // the new scale is not the same as ours
            {
                // a new scale was chosen, remove mapping
                setMeasure(null);// new Criterion());

                setScale(newScale.clone());
                setDefaultAggregation();

                if (scale != null) {
                    setDefaultTransformer();
                }
            }
        }
    }

    /**
     * Applies the given measure to this leaf, and adjusts scale and single
     * properly
     *
     * @param m
     */
    public void applyMeasure(final Measure m) {
        adjustScale(m.getScale());
        setMeasure(new Measure(m));
        setSingle(m.getAttribute().getCategory().getScope() == EvaluationScope.ALTERNATIVE_ACTION);
        if (StringUtils.isEmpty(name)) {
            setName(m.getName());
        }
        touchIncludingScale();

    }

    /**
     * is used to adjust the scale of this leaf to its mapping - the type of the
     * new scale has already been checked, mapping information is not discarded.
     * - a new scale is created, even the types of the current and the new Scale
     * match (to get clean aggregation and transformer values)
     *
     * @param newScale
     */
    public void adjustScale(Scale newScale) {
        if (newScale == null) {
            log.debug("CHECK THIS: try to setg scale to null due to measurement info: this should NOT happen at all.");
        } else {
            if ((this.scale == null) // we don't have a scale yet
                || (!scale.getClass().getName().equals(newScale.getClass().getName())))
            // the new scale is not the same as ours
            {
                setScale(newScale.clone());
                setDefaultAggregation();
                if (scale != null) {
                    setDefaultTransformer();
                }
            }
        }
    }

    /**
     * sets the {@link #aggregationMode} depending on {@link #scale}. For all
     * ordinal scales we set it to using the worst result, and for numeric
     * scales we use the average result
     *
     * @see SampleAggregationMode
     */
    private void setDefaultAggregation() {
        if (scale instanceof OrdinalScale) {
            setAggregationMode(SampleAggregationMode.WORST);
        } else { // numeric
            setAggregationMode(SampleAggregationMode.AVERAGE);
        }
    }

    @Override
    /**
     * This is a leaf, so: YES, I am.
     * @return true
     */
    public boolean isLeaf() {
        return true;
    }

    public SampleAggregationMode getAggregationMode() {
        return aggregationMode;
    }

    public void setAggregationMode(SampleAggregationMode aggregationMode) {
        this.aggregationMode = aggregationMode;
    }

    /**
     * unused at the moment. TODO checking the size of the valuemap is not
     * enough.
     */
    public EvaluationStatus getEvaluationStatus() {
        return (valueMap.size() > 0) ? EvaluationStatus.COMPLETE : EvaluationStatus.NONE;
    }

    /**
     * Unused at the moment.
     *
     * @return the transformation status. TODO checking transformer for null
     *         state is NOT enough
     */
    public EvaluationStatus getTransformationStatus() {
        return (transformer != null) ? EvaluationStatus.COMPLETE : EvaluationStatus.NONE;
    }

    /**
     * removes associated evaluation {@link Values} for a given list of
     * alternatives and a give record index.
     *
     * @param list
     *            list of Alternatives for which values shall be removed
     * @param record
     *            index of the record for which values shall be removed
     */
    public void removeValues(List<Alternative> list, int record) {
        for (Alternative a : list) {
            Values v = getValues(a.getName());
            // maybe this alternative has no values at all - e.g. because it was
            // just created
            if ((v != null) // there is a Values object
                && (v.getList().size() > record) // there can be a value for
                                                 // this sample record
                && (v.getList().get(record) != null)) { // there is a value
                log.debug("removing values:: " + getName() + " ," + record + ", " + a.getName());
                v.getList().remove(record);
            }
        }
    }

    /**
     * The value map is properly initialized if its size equals the number of
     * alternatives and the number of values equals the number of records.
     *
     * @return true if value map is properly initialized
     */
    @Override
    public boolean isValueMapProperlyInitialized(List<Alternative> alternatives, int numberRecords) {
        if (valueMap.size() != alternatives.size()) {
            return false;
        }

        for (Alternative a : alternatives) {
            if (!valueMap.keySet().contains(a.getName())) {
                return false;
            }
        }

        for (String a : valueMap.keySet()) {
            if (!isSingle() && valueMap.get(a).size() != numberRecords) {
                return false;
            } else if (isSingle() && valueMap.get(a).size() != 1) {
                return false;
            }
        }

        return true;
    }

    /**
     * Creates empty Values for all Alternatives and SampleRecords as provided
     * in the parameters, PLUS ensures that values are linked to scales if the
     * parameter addLinkage is true
     *
     * An assumption here is that other methods take care of removing values
     * when removing records ({@link #removeValues(List, int)}), and of
     * resetting values when changing scales and from object to action
     * criterion. ({@link #resetValues()}) These methods need to be called when
     * manipulating the object model.
     *
     * @param list
     *            of Alternatives
     * @param records
     *            The number of records determines how many {@link Values} are
     *            created and associated for every {@link Alternative}
     * @param addLinkage
     *            If true, ensure that values are linked to scales by calling
     *            {@link #initScaleValueLinkage(List, int)}
     */
    public void initValues(List<Alternative> list, int records, boolean addLinkage) {
        /**
         * maybe we have not completed the step identify requirements yet - so
         * there might be no scales!
         **/
        if (scale == null)
            return;
        for (Alternative a : list) {
            // for every Alternative we get the container of the values of each
            // sample object
            // from the map
            Values v = valueMap.get(a.getName());

            // If it doesnt exist, we create it and link it in the map
            if (v == null) {
                v = new Values();
                valueMap.put(a.getName(), v);
                // it the valueMap has just been created and the leaf is single,
                // we need to add one value.
                if (isSingle()) {
                    v.add(scale.createValue());
                }
            }

            // 20090217, hotfix CB: if a Leaf is set to SINGLE *after*
            // initValues has been called,
            // the Value object at position 0 of the ValueS object might not be
            // properly initialised.
            // Check and initialise if needed:
            if (isSingle()) {
                if (v.size() == 0) {
                    log.warn("adding value to a SINGLE LEAF WITH A VALUES OBJECT WITHOUT A PROPER VALUE:" + getName());
                    v.getList().add(scale.createValue());
                } else {
                    if (v.getValue(0) == null) {
                        log.warn("adding value to a SINGLE LEAF WITH A VALUES OBJECT WITHOUT A PROPER VALUE:"
                            + getName());
                        v.setValue(0, scale.createValue());
                    }
                }
            }
            // end hotfix 20090217

            // So we can be sure now that we have a value container and
            // that it is linked and that for Action criteria, i.e. single
            // values, we have the one value.
            // For Object criteria we have to be sure that the number of values
            // corresponds to the number of sample objects, so we fill the list
            // up
            if (!isSingle()) {
                // this is to add MISSING values for records.
                // it doesnt make a difference for this condition
                // whether we just created a new valuemap or are
                // refilling an existing one

                // Note that the index here starts at the size of the values
                // array
                // and runs to the total number of records.
                // so if we have enough - nothing happens; if some are missing,
                // they are
                // added at the end
                for (int i = v.size(); i < records; i++) {
                    v.add(scale.createValue());
                }
            }
        }
        if (addLinkage) {
            initScaleValueLinkage(list, records);
        }
    }

    /**
     * ensures that values are linked to scales by setting all of them
     * explicitly. We need that especially for export/import
     *
     * @param list
     *            List of Alternatives over which to iterate
     * @param records
     *            denotes the number of records for the iteration
     */
    public void initScaleValueLinkage(List<Alternative> list, int records) {
        for (Alternative a : list) {
            Values v = valueMap.get(a.getName());
            if (v == null) {
                throw new IllegalStateException("initScaleLinkage called,"
                    + " but the valueMap is still empty - that's a bug." + " Leaf:" + getName());
            }
            if (isSingle()) {
                v.getValue(0).setScale(scale);
            } else {
                for (int i = 0; i < records; i++) {
                    v.getValue(i).setScale(scale);
                }
            }
        }
    }

    /**
     * Checks if the Scale of this Leaf is existent and correctly specified. To
     * achieve this, it calls {@link Scale#isCorrectlySpecified(String, List)}
     * if there is a scale, or returns false otherwise.
     *
     * @see TreeNode#isCompletelySpecified(List<ValidationError>)
     * @see Scale#isCorrectlySpecified(String, List)
     */
    @Override
    public boolean isCompletelySpecified(List<ValidationError> errors) {
        if (this.scale == null) {
            errors.add(new ValidationError("Leaf " + this.getName() + " has no scale", this));
            return false;
        }
        if (scale instanceof YanScale) {
            errors
                .add(new ValidationError(
                    "Criterion "
                        + getName()
                        + " is associated with a 'Yes/Acceptable/No' scale, which is discouraged. We recommend to refine the criterion to be as objective as possible.",
                    this));
        }
        return this.scale.isCorrectlySpecified(this.getName(), errors);
    }

    /**
     * Checks if this Leaf is completely evaluated, i.e. we have correct values
     * for all Alternatives and samples. For this means we need to iterate over
     * all alternatives and check all values. This is done by calling
     * {@link Scale#isEvaluated(Value)}
     *
     * @param alternatives
     *            the list of Alternatives over which to iterate when checking
     *            for evaluation values
     * @param errorMessages
     *            This is the list of messages where we add a message
     *            about this Leaf in case validation fails, i.e. it is not
     *            completely evaluated.
     * @see eu.scape_project.planning.model.tree.TreeNode#isCompletelyEvaluated(List,
     *      List)
     * @see Scale#isEvaluated(Value)
     */
    @Override
    public boolean isCompletelyEvaluated(List<Alternative> alternatives, List<ValidationError> errors) {
        boolean validates = true;
        log.debug("checking complete evaluation for leaf " + getName());
        for (Alternative a : alternatives) {
            Values values = valueMap.get(a.getName());
            log.debug("checking values for " + a.getName());
            if (this.isSingle()) {
                if (values.size() < 1) {
                    log.warn("Not Enough Value Objects in Values");
                    validates = false;
                } else {
                    if (!scale.isEvaluated(values.getValue(0))) {
                        validates = false;
                    }
                }
            } else {
                int i = 0;
                for (Value value : values.getList()) {
                    log.debug("checking value for " + (i));
                    if (!scale.isEvaluated(value)) {
                        validates = false;
                        break;
                    }
                    i++;
                }
            }
        }
        if (!validates) {
            // I add an error message to the list, and myself to the list of
            // error nodes
            errors.add(new ValidationError("Leaf " + this.getName() + " is not properly evaluated", this));
        }
        return validates;
    }

    /**
     * Checks if the transformation settings for this Leaf are complete and
     * correct.
     *
     * @see Transformer#isTransformable(List)
     * @see TreeNode#isCompletelyTransformed(List)
     */
    @Override
    public boolean isCompletelyTransformed(List<ValidationError> errors) {
        if (this.transformer == null) {
            errors.add(new ValidationError("Leaf " + this.getName() + " is not properly transformed", this));
            log.error("Transformer is NULL in Leaf " + getParent().getName() + " > " + getName());
            return false;
        }
        if (!this.transformer.isTransformable(errors) || !this.transformer.isChanged()) {
            errors.add(new ValidationError("Leaf " + this.getName() + " is not properly transformed", this));
            return false;
        }
        return true;
    }

    @Override
    /**
     * Checks if the weight is in [0,1].
     * @see Node#isCorrecltlyWeighted(List<String>)
     */
    public boolean isCorrectlyWeighted(List<ValidationError> errors) {
        // A leaf is always weighted correctly as long as its weight is in [0,1]
        if (this.weight >= 0 && this.weight <= 1) {
            return true;
        }
        errors
            .add(new ValidationError("Leaf " + this.getName() + " has an illegal weight (" + this.weight + ")", this));
        return false;
    }

    @Override
    /**
     * Returns a clone of this Leaf. Includes:

     *
{@link Scale}

     *
{@link AggregationMode}

     *
{@link ValueMap} which is initialised, but not cloned

     *

     * Excludes transformer! The transformer is set to null
     */
    public TreeNode clone() {
        Leaf clone = (Leaf) super.clone();
        if (this.getScale() != null) {
            clone.setScale(this.getScale().clone());
        }
        clone.setValueMap(new HashMap<String, Values>());

        Transformer newTransformer = null;
        if (transformer != null) {
            newTransformer = transformer.clone();
        }
        clone.setTransformer(newTransformer);
        clone.setAggregationMode(this.getAggregationMode());
        if (measure != null) {
            clone.setMeasure(new Measure(measure));
        }
        return clone;
    }

    /**
     * @see ITouchable#handleChanges(IChangesHandler)
     */
    public void handleChanges(IChangesHandler h) {
        super.handleChanges(h);

        // call handleChanges of all properties
        if (scale != null) {
            scale.handleChanges(h);
        }
        if (transformer != null) {
            transformer.handleChanges(h);
        }
        if (measure != null) {
            measure.handleChanges(h);
        }

    }

    @Transient
    public boolean isMapped() {
        return (measure != null);
    }

    /**
     * this method updates the value map, changing the name of the alternative
     * to the new one.
     *
     * @param oldName
     *            old name to be updated
     * @param newName
     *            new name to be used instead of oldName
     */
    public void updateAlternativeName(String oldName, String newName) {
        if (valueMap.containsKey(oldName))
            valueMap.put(newName, valueMap.remove(oldName));

        /*
         * for (String name: valueMap.keySet()) { if (name.equals(oldName)) {
         * valueMap.put(newName, valueMap.get(oldName));
         * valueMap.remove(oldName); } }
         */

    }

    /**
     *

     *

     * removes all {@link Values} from the {@link #valueMap} which are not
     * mapped by one of the names provided in the list

     *

     * removes all {@link Value} objects in the {@link Values} which are out of
     * the index of the sample records (which should not happen, but apparently
     * we have some projects where this is the case), or where a leaf is single
     * and there is more than one {@link Value}

     *

     *
     * @param alternatives
     *            list of names of alternatives
     * @return number of {@link Values} objects removed
     */
    public int removeLooseValues(List<String> alternatives, int records) {
        int number = 0;
        Iterator<String> it = valueMap.keySet().iterator();
        List<String> namesToRemove = new ArrayList<String>();
        while (it.hasNext()) {
            String altName = it.next();
            if (!alternatives.contains(altName)) {
                log.warn("removing Values for " + altName + " at leaf " + getName());
                namesToRemove.add(altName);
                number++;
            } else {
                Values v = valueMap.get(altName);
                int removed = v.removeLooseValues(isSingle() ? 1 : records);
                log.warn("removed " + removed + " Value objects " + "for " + altName + " at leaf " + getName());
                number += removed;
            }
        }
        for (String s : namesToRemove) {
            valueMap.remove(s);
        }
        return number;
    }

    public void normalizeWeights(boolean recoursive) {
        // this is a leaf which means there are no children
        // and therefore there is nothing to do
    }

    public Measure getMeasure() {
        return measure;
    }

    public void setMeasure(Measure measure) {
        this.measure = measure;
    }

    /**
     * initialises the ordinal transformer for free text scales AND has a side
     * effect: textual values in free text scales with equalsIgnoreCase=true to
     * an existing mapping are changed to the case of the mapping string!
     */
    public void initTransformer() {
        initTransformer(null);
    }

    /**
     * initialises the ordinal transformer for free text scales, @see
     * #initTransformer()
     *
     * @param defaultTarget
     *            if this is used (must be 0.0<=defaultTarget<=5.0, unchecked)
     *            then for each newly added mapping, the default target is set
     *            as provided.
     */
    public void initTransformer(Double defaultTarget) {

        if (scale instanceof FreeStringScale) {
            FreeStringScale freeScale = (FreeStringScale) scale;
            // We collect all distinct actually EXISTING values
            OrdinalTransformer t = (OrdinalTransformer) transformer;
            Map<String, TargetValueObject> map = t.getMapping();

            HashSet<String> allValues = new HashSet<String>();
            for (Values values : valueMap.values()) {
                for (Value v : values.getList()) {
                    FreeStringValue text = (FreeStringValue) v;
                    if (!text.toString().equals("")) {
                        for (String s : map.keySet()) {
                            // if the value is NOT the same, but IS the same
                            // with other case,
                            // we replace the value with the cases predefined by
                            // the mapping
                            if (text.getValue().equalsIgnoreCase(s) && !text.getValue().equals(s)) {
                                text.setValue(s);
                            }
                        }
                        allValues.add(text.getValue());
                    }
                }
            }

            // We remove all values from the transformer that do not actually
            // occur (anymore)
            // I am disabling this for now - why would we want to remove known
            // mappings?
            // They don't do harm because for the lookup, we use the actually
            // encountered values
            // (see below)
            // HashSet<String> keysToRemove = new HashSet<String>();
            // for (String s: map.keySet()) {
            // if (!allValues.contains(s)) {
            // keysToRemove.add(s);
            // }
            // }
            // for (String s: keysToRemove) {
            // map.remove(s);
            // }

            // We add all values that occur, but are not in the map yet:
            for (String s : allValues) {
                if (!map.containsKey(s)) {
                    if (defaultTarget == null) {
                        map.put(s, new TargetValueObject());
                    } else {
                        map.put(s, new TargetValueObject(defaultTarget.doubleValue()));
                    }
                }
            }

            // We also have to publish the known values
            // to the SCALE because it provides the reference lookup
            // for iterating and defining the transformation
            freeScale.setPossibleValues(allValues);
        }
    }

    /**
     * Method responsible for assessing the potential output range of this
     * requirement. Calculation rule: if (minPossibleTransformedValue == 0)
     * koFactor = 1; else koFactor = 0; potentialOutputRange = relativeWeight *
     * (maxPossibleTransformedValue - minPossibleTransformedValue) + koFactor;
     *
     * @return potential output range. If the plan is not yet at a evaluation
     *         stage where potential output range can be calculated 0 is
     *         returned.
     */
    public double getPotentialOutputRange() {
        // If the plan is not yet at a evaluation stage where potential output
        // range can be calculated - return 0.
        if (transformer == null) {
            return 0;
        }

        double outputLowerBound = 10;
        double outputUpperBound = -10;

        // Check OrdinalTransformer
        if (transformer instanceof OrdinalTransformer) {
            OrdinalTransformer ot = (OrdinalTransformer) transformer;
            Map<String, TargetValueObject> otMapping = ot.getMapping();

            // set upper- and lower-bound
            for (TargetValueObject tv : otMapping.values()) {
                if (tv.getValue() > outputUpperBound) {
                    outputUpperBound = tv.getValue();
                }
                if (tv.getValue() < outputLowerBound) {
                    outputLowerBound = tv.getValue();
                }
            }
        }

        // Check OrdinalTransformer
        if (transformer instanceof NumericTransformer) {
            // I have to identify the scale bounds before I can calculate the
            // output bounds.
            double scaleLowerBound = Double.MIN_VALUE;
            double scaleUpperBound = Double.MAX_VALUE;

            // At Positive Scales lowerBound is 0, upperBound has to be fetched
            if (scale instanceof PositiveIntegerScale) {
                PositiveIntegerScale s = (PositiveIntegerScale) scale;
                scaleLowerBound = 0;
                scaleUpperBound = s.getUpperBound();
            }
            if (scale instanceof PositiveFloatScale) {
                PositiveFloatScale s = (PositiveFloatScale) scale;
                scaleLowerBound = 0;
                scaleUpperBound = s.getUpperBound();
            }

            // At Range Scales lowerBound and upperBound have to be fetched
            if (scale instanceof IntRangeScale) {
                IntRangeScale s = (IntRangeScale) scale;
                scaleLowerBound = s.getLowerBound();
                scaleUpperBound = s.getUpperBound();
            }
            if (scale instanceof FloatRangeScale) {
                FloatRangeScale s = (FloatRangeScale) scale;
                scaleLowerBound = s.getLowerBound();
                scaleUpperBound = s.getUpperBound();
            }

            // get Transformer thresholds
            NumericTransformer nt = (NumericTransformer) transformer;
            double transformerT1 = nt.getThreshold1();
            double transformerT2 = nt.getThreshold2();
            double transformerT3 = nt.getThreshold3();
            double transformerT4 = nt.getThreshold4();
            double transformerT5 = nt.getThreshold5();

            // calculate output bounds
            if (nt.hasIncreasingOrder()) {
                // increasing thresholds
                // lower bound
                if (scaleLowerBound < transformerT1) {
                    outputLowerBound = 0;
                } else if (scaleLowerBound < transformerT2) {
                    outputLowerBound = 1;
                } else if (scaleLowerBound < transformerT3) {
                    outputLowerBound = 2;
                } else if (scaleLowerBound < transformerT4) {
                    outputLowerBound = 3;
                } else if (scaleLowerBound < transformerT5) {
                    outputLowerBound = 4;
                } else {
                    outputLowerBound = 5;
                }

                // upper bound
                if (scaleUpperBound < transformerT1) {
                    outputUpperBound = 0;
                } else if (scaleUpperBound < transformerT2) {
                    outputUpperBound = 1;
                } else if (scaleUpperBound < transformerT3) {
                    outputUpperBound = 2;
                } else if (scaleUpperBound < transformerT4) {
                    outputUpperBound = 3;
                } else if (scaleUpperBound < transformerT5) {
                    outputUpperBound = 4;
                } else {
                    outputUpperBound = 5;
                }
            } else {
                // decreasing thresholds
                // lower bound
                if (scaleUpperBound > transformerT1) {
                    outputLowerBound = 0;
                } else if (scaleUpperBound > transformerT2) {
                    outputLowerBound = 1;
                } else if (scaleUpperBound > transformerT3) {
                    outputLowerBound = 2;
                } else if (scaleUpperBound > transformerT4) {
                    outputLowerBound = 3;
                } else if (scaleUpperBound > transformerT5) {
                    outputLowerBound = 4;
                } else {
                    outputLowerBound = 5;
                }

                // upper bound
                if (scaleLowerBound > transformerT1) {
                    outputUpperBound = 0;
                } else if (scaleLowerBound > transformerT2) {
                    outputUpperBound = 1;
                } else if (scaleLowerBound > transformerT3) {
                    outputUpperBound = 2;
                } else if (scaleLowerBound > transformerT4) {
                    outputUpperBound = 3;
                } else if (scaleLowerBound > transformerT5) {
                    outputUpperBound = 4;
                } else {
                    outputUpperBound = 5;
                }
            }
        }

        double koFactor = 0;
        if (outputLowerBound == 0) {
            koFactor = 1;
        }

        double potentialOutputRange = getTotalWeight() * (outputUpperBound - outputLowerBound) + koFactor;

        return potentialOutputRange;
    }

    public double getPotentialImpact() {
        if (transformer == null) {
            return 0.0;
        }
        double maxRating = 0.0;
        if (transformer instanceof OrdinalTransformer) {
            for (TargetValueObject tv : ((OrdinalTransformer) transformer).getMapping().values()) {
                if (tv.getValue() > maxRating) {
                    maxRating = tv.getValue();
                }
            }
        } else {
            maxRating = 5.0;
        }
        return this.getTotalWeight() * maxRating;
    }

    /**
     * Method responsible for assessing the actual output range of this
     * requirement. Calculation rule: if (minActualTransformedValue == 0)
     * koFactor = 1; else koFactor = 0; actualOutputRange = relativeWeight *
     * (maxActualTransformedValue - minActualTransformedValue) + koFactor;
     *
     * @return actual output range. If the plan is not yet at a evaluation stage
     *         where actual output range can be calculated 0 is returned.
     */
    public double getActualOutputRange() {
        // If the plan is not yet at a evaluation stage where actual output
        // range can be calculated - return 0.
        if (transformer == null) {
            return 0;
        }

        // Collect all measured values from all alternatives
        List<Value> valueList = new ArrayList<Value>();
        Collection<Values> valuesCollection = valueMap.values();
        for (Values values : valuesCollection) {
            for (Value value : values.getList()) {
                valueList.add(value);
            }
        }

        // if nothing is measured yet - return 0
        if (valueList.size() == 0) {
            return 0;
        }

        // transform measured values
        List<Double> transformedValues = new ArrayList<Double>();
        for (Value val : valueList) {
            TargetValue targetValue;

            // do ordinal transformationCriterion
            if (transformer instanceof OrdinalTransformer) {
                OrdinalTransformer ordTrans = (OrdinalTransformer) transformer;

                if (val instanceof IOrdinalValue) {
                    try {
                        targetValue = ordTrans.transform((IOrdinalValue) val);
                    } catch (NullPointerException e) {
                        log.warn("Measurement of leaf doesn't match with OrdinalTransformer! Ignoring it!");
                        log.warn("MeasuredValue-id: " + val.getId() + "; Transformer-id: " + ordTrans.getId());
                        continue;
                    }
                    transformedValues.add(targetValue.getValue());
                } else {
                    log.warn("getActualOutputRange(): INumericValue value passed to OrdinalTransformer - ignore value");
                }
            }

            // do numeric transformation
            if (transformer instanceof NumericTransformer) {
                NumericTransformer numericTrans = (NumericTransformer) transformer;

                if (val instanceof INumericValue) {
                    targetValue = numericTrans.transform((INumericValue) val);
                    transformedValues.add(targetValue.getValue());
                } else {
                    log.warn("getActualOutputRange(): IOrdinalValue value passed to NumericTransformer - ignore value");
                }
            }
        }

        // if nothing could be transformed successfully - return 0
        if (transformedValues.size() == 0) {
            return 0;
        }

        // calculate upper/lower bound
        double outputLowerBound = 10;
        double outputUpperBound = -10;

        for (Double tVal : transformedValues) {
            if (tVal > outputUpperBound) {
                outputUpperBound = tVal;
            }
            if (tVal < outputLowerBound) {
                outputLowerBound = tVal;
            }
        }

        double koFactor = 0;
        if (outputLowerBound == 0) {
            koFactor = 1;
        }

        double actualOutputRange = getTotalWeight() * (outputUpperBound - outputLowerBound) + koFactor;

        return actualOutputRange;
    }

    /**
     * touches everything: this, the scale and the transformer (if existing)
     */
    @Override
    public void touchAll(String username) {
        touch(username);
        if (scale != null) {
            scale.touch(username);
        }
        if (transformer != null) {
            transformer.touch(username);
        }
    }

    /**
     * Method responsible for touching this Leaf and its Scale.
     */
    public void touchIncludingScale() {
        touch();
        if (scale != null) {
            scale.touch();
        }
    }
}


text:
export SRCROOT="<%= compileDir %>" &&
mkdir -p $SRCROOT &&
cd $SRCROOT &&

### Set versions and directories
export PVERSION_SW="<%= softwareVersion %>" &&

### HarfBuzz
cd $SRCROOT && . ../build_functions.sh &&
export PNAME="harfbuzz" &&
export PVERSION="$PVERSION_SW" &&
export PDIR="$PNAME-$PVERSION" &&
export PFILE="$PDIR.tar.bz2" &&
export PURI="http://www.freedesktop.org/software/harfbuzz/release/$PFILE" &&

rm -rf $PDIR &&
GetUnpackCd &&

./configure &&
make &&
make install &&
ldconfig &&

cd $SRCROOT &&
rm -rf $PDIR &&

true


text:
module FFaker
  module Sport
    extend ModuleUtils
    extend self

    def name
      NAMES.sample
    end
  end
end


text:
//
//  HCPPluginConfig.h
//
//  Created by Nikolay Demyankov on 10.08.15.
//

#import <Foundation/Foundation.h>
#import "HCPJsonConvertable.h"

/**
 *  Model for plugin preferences, that can be changed during runtime.
 *  Using this you can disable/enable updates download and installation,
 *  and even change application config file url (by default it is set in config.xml).
 *
 *  Also, it stores current build version of the application,
 *  so we could determine if it has been updated through the App Store.
 */
@interface HCPPluginInternalPreferences : NSObject<HCPJsonConvertable>

/**
 *  Build version of the app which was detected on the last launch.
 *  Using it we can determine if application has been updated through the App Store.
 */
@property (nonatomic, strong) NSString *appBuildVersion;

/**
 *  Flag to check, if www folder from the bundle is installed on external storage.
 */
@property (nonatomic, getter=isWwwFolderInstalled) BOOL wwwFolderInstalled;

/**
 *  Previous version of the content. Can be used to rollback.
 */
@property (nonatomic, strong) NSString *previousReleaseVersionName;

/**
 *  Current version of the content, that is displayed to the user.
 */
@property (nonatomic, strong) NSString *currentReleaseVersionName;

/**
 *  Name of the new version, that was loaded and ready to be installed.
 */
@property (nonatomic, strong) NSString *readyForInstallationReleaseVersionName;

/**
 *  Create default plugin config.
 *
 *  @return default config instance
 */
+ (HCPPluginInternalPreferences *)defaultConfig;

@end


text:
{% extends "wginfo/wg_base.html" %}
{% comment %}
Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
All rights reserved. Contact: Pasi Eronen <pasi.eronen@nokia.com>

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

 * Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above
   copyright notice, this list of conditions and the following
   disclaimer in the documentation and/or other materials provided
   with the distribution.

 * Neither the name of the Nokia Corporation and/or its
   subsidiary(-ies) nor the names of its contributors may be used
   to endorse or promote products derived from this software
   without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{% endcomment %}
{% load ietf_filters %}
{% block wg_titledetail %}Charter{% endblock %}

{% block morecss %}
{{ block.super }}
h2 a.button { margin-left: 0.5em; font-size: 13px; }
{% endblock %}

{% block wg_content %}

{% if concluded %}
Note: The data for concluded WGs
is occasionally incorrect.
{% endif %}

Group

    Name:
    {{ wg.name }}

Acronym:	{{ wg.acronym }}

  {% if wg.parent %}

Area:	{{ wg.parent.name }} ({{ wg.parent.acronym }})

  {% endif %}

    State:
    {{ wg.state.name }}
      {% if requested_close %}
      (but in the process of being closed)
      {% endif %}

    Charter:

      {% if wg.charter %}
      {{ wg.charter.name }}-{{ wg.charter.rev }} ({{ wg.charter.get_state.name }})
      {% else %}
      none
      {% if user|has_role:"Area Director,Secretariat" %}
      - Submit Charter
      {% endif %}
      {% endif %}

Personnel

    Chair{{ wg.chairs|pluralize }}:

      {% for chair in wg.chairs %}
      {{ chair.person.plain_name }} <{{ chair.address }}>

      {% endfor %}

Area Director:

    {% if not wg.ad %}?{% else %}
    {{ wg.ad.plain_name }} <{{ wg.areadirector.address }}>{% endif %}

  {% if wg.techadvisors %}

    Tech Advisor{{ wg.techadvisors|pluralize }}:

      {% for techadvisor in wg.techadvisors %}
      {{ techadvisor.person.plain_name }} <{{ techadvisor.address }}>

      {% endfor %}

  {% endif %}
  {% if wg.editors %}
  Editor{{ wg.editors|pluralize }}:

    {% for editor in wg.editors %}
    {{ editor.person.plain_name }} <{{ editor.address }}>

    {% endfor %}

  {% endif %}
  {% if wg.secretaries %}

    Secretar{{ wg.secretaries|pluralize:"y,ies" }}:

      {% for secretary in wg.secretaries %}
      {{ secretary.person.plain_name }} <{{ secretary.address }}>

      {% endfor %}

  {% endif %}

Mailing List

Address:	{{ wg.email_address|urlize }}

To Subscribe:	{{ wg.email_subscribe|urlize }}

Archive:	{{ wg.clean_email_archive|urlize }}

  {% if not concluded %}

Jabber Chat

Room Address:	xmpp:{{ wg.acronym }}@jabber.ietf.org

Logs:	http://jabber.ietf.org/logs/{{ wg.acronym }}/

  {% endif %}

{% if user|has_role:"Area Director,Secretariat" %}

  {% for name, url in actions %}
  {{ name }}
  {% if not forloop.last %}|{% endif %}
  {% endfor %}

{% endif %}

{% if wg.additional_urls %}

In addition to the charter maintained by the IETF Secretariat, there is additional information about this working group on the Web at:
{% for url in wg.additional_urls %}
{{ url.name }}{% if not forloop.last %}, {% endif %}
{% endfor %}

{% endif %}

Charter for {% if wg.state_id == "proposed" %}Proposed{% endif %} Working Group

{{ wg.charter_text|escape|format_charter|safe }}

{% if wg.state_id == "proposed" %}Proposed{% endif %} Milestones
{% if wg.state_id != "proposed" %}
{% if user|has_role:"Area Director,Secretariat" or is_chair %}
Add or edit milestones
{% endif %}
{% endif %}

{% with wg.milestones as milestones %}{% include "wginfo/milestones.html" %}{% endwith %}

{% if milestones_in_review %}

+ {{ milestones_in_review|length }} new milestone{{ milestones_in_review|pluralize }}
currently in Area Director review.

{% endif %}
{% endblock wg_content %}


text:
package com.github.cc007.sciencespinoffsquiz.language;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

/**
 *
 * @author Rik Schaaf aka CC007 <http://coolcat007.nl/>
 */
public class LanguagesController {

    private final ResourceBundle translation;

    public LanguagesController(String language) {
        Locale dutch = new Locale("nl", "NL");
        Map<String, Locale> supportedLanguages = new HashMap<>();
        supportedLanguages.put("Nederlands", dutch);
        supportedLanguages.put("English", Locale.ENGLISH);
        translation = ResourceBundle.getBundle("language", supportedLanguages.get(language));
    }

    public String getText(String keyword) {
        return translation.getString(keyword);
    }

}


text:
package org.drools.compiler.compiler.xml.rules;

import org.junit.Test;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

/**
 * Test the dump/convert format utilities.
 */

public class DumperTest {

    // Xml Dumper test

    @Test
    public void testRoundTripAccumulateXml() throws Exception {
        DumperTestHelper.XmlFile( "test_ParseAccumulate.xml" );
    }

    @Test
    public void testRoundTripCollectXml() throws Exception {
        DumperTestHelper.XmlFile( "test_ParseCollect.xml" );
    }

    @Test
    public void testRoundTripExistsXml() throws Exception {
        DumperTestHelper.XmlFile( "test_ParseExists.xml" );
    }

    @Test
    public void testRoundTripForallXml() throws Exception {
        DumperTestHelper.XmlFile( "test_ParseForall.xml" );
    }

    @Test
    public void testRoundTripFromXml() throws Exception {
        DumperTestHelper.XmlFile( "test_ParseFrom.xml" );
    }

    @Test
    public void testRoundTripComplexRuleXml() throws Exception {
        DumperTestHelper.XmlFile( "test_RoundTrip.xml" );
    }

    // Drl Dumper test

    @Test
    public void testRoundTripComplexRuleDrl() throws Exception {
        DumperTestHelper.DrlFile( "test_RoundTrip.drl" );
    }

    @Test
    public void testRoundTripCollectDrl() throws Exception {
        DumperTestHelper.DrlFile( "../../../integrationtests/test_Collect.drl" );
    }

    @Test
    public void testRoundTripAccumulateDrl() throws Exception {
        DumperTestHelper.DrlFile( "test_accumulateall.drl" );
    }

    @Test
    public void testRoundTripExistsDrl() throws Exception {
        DumperTestHelper.DrlFile( "../../../integrationtests/test_exists.drl" );
    }

    @Test
    public void testRoundTripForallDrl() throws Exception {
        DumperTestHelper.DrlFile( "../../../integrationtests/test_Forall.drl" );
    }

    @Test
    public void testRoundTripFromDrl() throws Exception {
        DumperTestHelper.DrlFile( "test_from.drl" );
    }

    @Test
    public void testRoundTripSimpleRuleDrl() throws Exception {
        DumperTestHelper.DrlFile( "test_simplerule.drl" );
    }

    @Test
    public void testRoundTripPComplexDrl() throws Exception {
        DumperTestHelper.DrlFile( "test_complex.drl" );
    }

    @Test
    public void testRoundTripDRLAnnotations() throws Exception {
        DumperTestHelper.DrlFile( "test_DumpAnnotations.drl" );
    }

    @Test
    public void testRoundTripDRLNamedConsequences() throws Exception {
        DumperTestHelper.DrlFile( "test_NamedConsequences.drl" );
    }

    @Test
    public void testRoundTripPComplexXml() throws Exception {
        DumperTestHelper.XmlFile( "test_ParseComplex.xml" );
    }

    @Test
    public void testRoundTripTraitDeclarations() throws Exception {
        DumperTestHelper.DrlFile( "test_TraitDeclaration.drl" );

        String out = DumperTestHelper.dump( "test_TraitDeclaration.drl" );
        assertTrue( out.contains( "declare trait Foo" ) );
    }

    @Test
    public void testRoundTripEnumDeclarations() throws Exception {
        DumperTestHelper.DrlFile( "test_EnumDeclaration.drl" );

        String out = DumperTestHelper.dump( "test_EnumDeclaration.drl" );
        assertTrue( out.contains( "declare enum Planets" ) );
        assertTrue( out.contains( "MERCURY" ) );
        assertTrue( out.contains( "7.1492e7" ) );
    }

    @Test
    public void testRoundTripAccumulate() throws Exception {
        String out = DumperTestHelper.dump( "test_Accumulate.drl" );
        assertTrue( out.contains( "$sum : count( $s1 )" ) );
        assertFalse( out.contains("null : count( $s2 )") );
        assertTrue( out.contains("count( $s2 )") );
    }
}


text:
'use strict';

describe('$templateRequest', function() {

  it('should download the provided template file',
    inject(function($rootScope, $templateRequest, $httpBackend) {

    $httpBackend.expectGET('tpl.html').respond('
abc
');

    var content;
    $templateRequest('tpl.html').then(function(html) { content = html; });

    $rootScope.$digest();
    $httpBackend.flush();

    expect(content).toBe('
abc
');
  }));

  it('should cache the request to prevent extra downloads',
    inject(function($rootScope, $templateRequest, $httpBackend) {

    $httpBackend.expectGET('tpl.html').respond('matias');

    var content = [];
    function tplRequestCb(html) {
      content.push(html);
    }

    $templateRequest('tpl.html').then(tplRequestCb);
    $httpBackend.flush();

    $templateRequest('tpl.html').then(tplRequestCb);
    $rootScope.$digest();

    expect(content[0]).toBe('matias');
    expect(content[1]).toBe('matias');
  }));

  it('should throw an error when the template is not found',
    inject(function($rootScope, $templateRequest, $httpBackend) {

    $httpBackend.expectGET('tpl.html').respond(404, '', {}, 'Not found');

    $templateRequest('tpl.html');

    $rootScope.$digest();

    expect(function() {
      $rootScope.$digest();
      $httpBackend.flush();
    }).toThrowMinErr('$compile', 'tpload', 'Failed to load template: tpl.html (HTTP status: 404 Not found)');
  }));

  it('should not throw when the template is not found and ignoreRequestError is true',
    inject(function($rootScope, $templateRequest, $httpBackend) {

      $httpBackend.expectGET('tpl.html').respond(404);

      var err;
      $templateRequest('tpl.html', true).catch(function(reason) { err = reason; });

      $rootScope.$digest();
      $httpBackend.flush();

      expect(err.status).toBe(404);
  }));

  it('should not throw an error when the template is empty',
    inject(function($rootScope, $templateRequest, $httpBackend) {

    $httpBackend.expectGET('tpl.html').respond('');

    $templateRequest('tpl.html');

    $rootScope.$digest();

    expect(function() {
      $rootScope.$digest();
      $httpBackend.flush();
    }).not.toThrow();
  }));

  it('should keep track of how many requests are going on',
    inject(function($rootScope, $templateRequest, $httpBackend) {

    $httpBackend.expectGET('a.html').respond('a');
    $httpBackend.expectGET('b.html').respond('c');
    $templateRequest('a.html');
    $templateRequest('b.html');

    expect($templateRequest.totalPendingRequests).toBe(2);

    $rootScope.$digest();
    $httpBackend.flush();

    expect($templateRequest.totalPendingRequests).toBe(0);

    $httpBackend.expectGET('c.html').respond(404);
    $templateRequest('c.html');

    expect($templateRequest.totalPendingRequests).toBe(1);
    $rootScope.$digest();

    try {
      $httpBackend.flush();
    } catch (e) {}

    expect($templateRequest.totalPendingRequests).toBe(0);
  }));

  it('should not try to parse a response as JSON',
    inject(function($templateRequest, $httpBackend) {
      var spy = jasmine.createSpy('success');
      $httpBackend.expectGET('a.html').respond('{{text}}', {
        'Content-Type': 'application/json'
      });
      $templateRequest('a.html').then(spy);
      $httpBackend.flush();
      expect(spy).toHaveBeenCalledOnceWith('{{text}}');
  }));

  it('should use custom response transformers (array)', function() {
    module(function($httpProvider) {
      $httpProvider.defaults.transformResponse.push(function(data) {
        return data + '!!';
      });
    });
    inject(function($templateRequest, $httpBackend) {
      var spy = jasmine.createSpy('success');
      $httpBackend.expectGET('a.html').respond('{{text}}', {
        'Content-Type': 'application/json'
      });
      $templateRequest('a.html').then(spy);
      $httpBackend.flush();
      expect(spy).toHaveBeenCalledOnceWith('{{text}}!!');
    });
  });

  it('should use custom response transformers (function)', function() {
    module(function($httpProvider) {
      $httpProvider.defaults.transformResponse = function(data) {
        return data + '!!';
      };
    });
    inject(function($templateRequest, $httpBackend) {
      var spy = jasmine.createSpy('success');
      $httpBackend.expectGET('a.html').respond('{{text}}', {
        'Content-Type': 'application/json'
      });
      $templateRequest('a.html').then(spy);
      $httpBackend.flush();
      expect(spy).toHaveBeenCalledOnceWith('{{text}}!!');
    });
  });
});


text:
<?php

namespace Cqrs\ReadModel\Repository;
use Cqrs\ReadModel\ReadModelInterface;

/**
 * @author      Iqbal Maulana <iq.bluejack@gmail.com>
 * @created     4/14/15
 */
interface ReadModelRepositoryInterface {

	/**
	 * Persist read model to storage
	 *
	 * @param ReadModelInterface $model
	 *
	 * @author Iqbal Maulana <iq.bluejack@gmail.com>
	 */
	public function save(ReadModelInterface $model);

	/**
	 * Find read model by id
	 *
	 * @param string $id
	 *
	 * @return ReadModelInterface|null
	 *
	 * @author Iqbal Maulana <iq.bluejack@gmail.com>
	 */
	public function find($id);

	/**
	 * Find read models with criteria
	 *
	 * @param array $fields
	 *
	 * @return ReadModelInterface[]
	 *
	 * @author Iqbal Maulana <iq.bluejack@gmail.com>
	 */
	public function findBy(array $fields);

	/**
	 * Return all read models
	 *
	 * @return ReadModelInterface[]
	 *
	 * @author Iqbal Maulana <iq.bluejack@gmail.com>
	 */
	public function findAll();

	/**
	 * Remove read model from storage
	 *
	 * @param string $id
	 *
	 * @author Iqbal Maulana <iq.bluejack@gmail.com>
	 */
	public function remove($id);
}


text:
function Seed=meltTrajectorySeed(Geometry,Grid,Res,Lid,T_MeltSeed,SpreadingDirection,indFigure)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% meltTrajectorySeed.m
% Determine seed for melt lines by following contour of ExcessT
% Laurent Montesi with Mark Behn, Laura Hebert
% Modified by Hailong Bai
% September 2015
%--------------------------------------------------------------------------
% INPUT -------------------------------------------------------------------
%   Geometry
%       |.PlateBoundary.x,y : Plate boundary coordinates [km]
%       |.ModelBoundary.x,y : Model boundary in x and y direction [km]
%       |.PlateBoundaryType : Plate boundary type (1:ridge, 2:transform, 3:oblique segment
%       |......
%   Grid
%       |.x, .y             : 2D matrices of lid sampling coordinates [km]
%   Res
%       |.MeltSeed          : Distance between adjacent melt seeds [km]
%       |......
%   Lid
%       |.Depth             : Depth of lid [km]
%       |.ExcessT           : Excess temperature above solidus [degC]
%       |......
%   T_MeltSeed              : Desired countour of ExcessT for seed generation [degC]
%   SpreadingDirection      : Direction of seafloor spreading [deg]
%   indFigure               : Figure index
%--------------------------------------------------------------------------
% OUTPUT ------------------------------------------------------------------
%   Seed(ind)
%       |.x, .y             : Coordinates of melt line seeds
%--------------------------------------------------------------------------
% INTERNAL ----------------------------------------------------------------
%   RidgeIndex              : Index of ridge segment along plate boundaries
%   TargetRidgeIndex        : Index of target (first and last) ridge segment
%   TargetPoint             : Coordinates for centers of target ridge segment [km]
%   Section
%       |.x, .y             : Coordinates for sections parallel to spreading direction and going through centers of ridge segment [km]
%       |.ExcessT           : Excess temperature above solidus along section [degC]
%   MaxT                    : Maximum ExcessT along section [degC]
%   iStart                  : Index for starting point for first melt seeds searching
%   SearchRange             : Search range for first melt seeds
%   InitialSeed
%       |_x, _y             : Coordinates for first melt seeds [km]
%   SeedDis                 : Distance along melt seed searching line [km]
%   SeedCoordinate1         : Coordinates for melt seeds from one searching direction [km]
%   SeedCoordinate2         : Coordinates for melt seeds from the other searching direction [km]
%   SeedCoordinate          : Coordinates for melt seeds [km]
%   SeedCoordinateDiff      : Distance between adjacent melt seeds [km]
%   iSeedDis                : Index for non-overlapping seeds
%   Seed_z                  : Depth of melt seeds [km]
%   InBoundaryIndex         : Index for point of interest within model boundary
%--------------------------------------------------------------------------
% ATTENDING SCRIPTS -------------------------------------------------------
%   crossToGrad
%   inBounds
%   lineSegmentIntersect
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% Section Location

figure(indFigure); clf; hold on;
contourf(Grid.x,Grid.y,Lid.ExcessT,[-40:20:200]); colorbar;
plot(Geometry.PlateBoundary.x,Geometry.PlateBoundary.y,'k.-');

% % find sections parallel to spreading direction and going through center of ridge axes
RidgeIndex=find(Geometry.PlateBoundaryType==1); % locate ridge segments along plate boundaries
[SortRidgeLength,SortRidgeLengthIndex]=sort(Geometry.PlateBoundary.y(RidgeIndex)); % sort ridge segment based on y coordinate
% TargetRidgeIndex=RidgeIndex(SortRidgeLengthIndex(1,:)); % index of ridge segments
TargetRidgeIndex=RidgeIndex(SortRidgeLengthIndex(1,[1,end])); % index of ridge segments

for i=1:length(TargetRidgeIndex);
    TargetPoint(i,1)=mean([Geometry.PlateBoundary.x(TargetRidgeIndex(i)),Geometry.PlateBoundary.x(TargetRidgeIndex(i)+1)]); % center of ridge segment
    TargetPoint(i,2)=mean([Geometry.PlateBoundary.y(TargetRidgeIndex(i)),Geometry.PlateBoundary.y(TargetRidgeIndex(i)+1)]); % center of ridge segment

    % % locate a section across center of ridge segment, parallel to spreading direction
    if SpreadingDirection==0; % if spreading is along x-direction
        Section(i).x=[Geometry.ModelBoundary.x(1):Res.MeltSeed:Geometry.ModelBoundary.x(2)];
        Section(i).y=linspace(TargetPoint(i,2),TargetPoint(i,2),length(Section(i).x));
    elseif SpreadingDirection==90; % if spreading is along y-direction
        Section(i).y=[Geometry.ModelBoundary.y(1):Res.MeltSeed:Geometry.ModelBoundary.y(2)];
        Section(i).x=linspace(TargetPoint(i,1),TargetPoint(i,1),length(Section(i).y));
    else % if spreading is along other direction
        sampleLine=@(x) tand(SpreadingDirection).*x+TargetPoint(i,2)-tand(SpreadingDirection).*TargetPoint(i,1);
        Section(i).x=[Geometry.ModelBoundary.x(1):Res.MeltSeed:Geometry.ModelBoundary.x(2)];
        Section(i).y=sampleLine(Section(i).x);
        InBoundaryIndex=find((Section(i).y>=Geometry.ModelBoundary.y(1))&(Section(i).y<=Geometry.ModelBoundary.y(2)));
        Section(i).x=Section(i).x(InBoundaryIndex);
        Section(i).y=Section(i).y(InBoundaryIndex);
    end
    plot(Section(i).x,Section(i).y,'k','linewidth',2);
    Section(i).ExcessT=interp2(Grid.x,Grid.y,Lid.ExcessT,Section(i).x,Section(i).y); % get ExcessT data along section
end

%% Seeds Generation

options=odeset('reltol',1e-4); % odeset('reltol',1e-8), optimset('display','off')
% % along sections, find points with assigned ExcessT value and search for contour lines
for iSeed=1:length(Section); % two original seed-searching sections
    [MaxT,iStart]=max(Section(iSeed).ExcessT); % identify where melting is max along bottom boundary
    switch rem(iSeed,2); % each search starts from one side of ridge axis
        case 0
            SearchRange=[1:iStart];
        case 1
            SearchRange=[iStart:length(Section(iSeed).x)];
    end

    % % find first seeds along sections
    if mean(diff(Section(iSeed).y))==0; % if section is along x-direction
        InitialSeed_x=fzero(@(x) interp1(Section(iSeed).x(SearchRange),Section(iSeed).ExcessT(SearchRange),x)-T_MeltSeed,...
            [Section(iSeed).x(SearchRange(1)),Section(iSeed).x(SearchRange(end))],options);
        % % alternatively, use fsolve if optimization toolbox is available
%         InitialSeed_x=fsolve(@(x) interp1(Section(iSeed).x(SearchRange),Section(iSeed).ExcessT(SearchRange),x)-T_MeltSeed,...
%             [Section(iSeed).x(iStart)],options);
        InitialSeed_y=interp1(Section(iSeed).x,Section(iSeed).y,InitialSeed_x);
    else % if section is not along x-direction
        InitialSeed_y=fzero(@(y) interp1(Section(iSeed).y(SearchRange),Section(iSeed).ExcessT(SearchRange),y)-T_MeltSeed,...
            [Section(iSeed).y(SearchRange(1)),Section(iSeed).y(SearchRange(end))],options);
        % % alternatively, use fsolve if optimization toolbox is available
%         InitialSeed_y=fsolve(@(y) interp1(Section(iSeed).y(SearchRange),Section(iSeed).ExcessT(SearchRange),y)-T_MeltSeed,...
%             [Section(iSeed).y(iStart)],options);
        InitialSeed_x=interp1(Section(iSeed).y,Section(iSeed).x,InitialSeed_y);
    end
    scatter(InitialSeed_x,InitialSeed_y);

    % % starting from first seeds, find rest seeds
    [SeedDis,SeedCoordinate1]=ode113(@(l,P) crossToGrad(P,Grid,Geometry.ModelBoundary,Lid,1),[0:Res.MeltSeed:1000],...
        [InitialSeed_x,InitialSeed_y],options);
    [SeedDis,SeedCoordinate2]=ode113(@(l,P) crossToGrad(P,Grid,Geometry.ModelBoundary,Lid,2),[0:Res.MeltSeed:1000],...
        [InitialSeed_x,InitialSeed_y],options);
    clear SeedDis;

    % % find the seed contours located within the model domain, these seed contours may have looping problems,
    % while seed contours cut by the model edges don't
    EdgeFinder=[];
    for iEdgeFinder=1:size(SeedCoordinate1,1);
        Seed_z(iEdgeFinder)=interp2(Grid.x,Grid.y,Lid.Depth,SeedCoordinate1(iEdgeFinder,1),SeedCoordinate1(iEdgeFinder,2));
        EdgeFinder=[EdgeFinder,inBounds(SeedCoordinate1(iEdgeFinder,1),SeedCoordinate1(iEdgeFinder,2),Seed_z(iEdgeFinder),Geometry.ModelBoundary)];
    end
    for iEdgeFinder=1:size(SeedCoordinate2,1);
        Seed_z(iEdgeFinder)=interp2(Grid.x,Grid.y,Lid.Depth,SeedCoordinate2(iEdgeFinder,1),SeedCoordinate2(iEdgeFinder,2));
        EdgeFinder=[EdgeFinder,inBounds(SeedCoordinate2(iEdgeFinder,1),SeedCoordinate2(iEdgeFinder,2),Seed_z(iEdgeFinder),Geometry.ModelBoundary)];
    end
    % % clear the looping portion of seed contours
    if min(EdgeFinder)==1;
        SeedSegment1=[SeedCoordinate1(2:end-1,1),SeedCoordinate1(2:end-1,2),SeedCoordinate1(3:end,1),SeedCoordinate1(3:end,2)];
        SeedSegment2=[SeedCoordinate2(2:end-1,1),SeedCoordinate2(2:end-1,2),SeedCoordinate2(3:end,1),SeedCoordinate2(3:end,2)];
        SectionSegment=[Section(iSeed).x(1:end-1)',Section(iSeed).y(1:end-1)',Section(iSeed).x(2:end)',Section(iSeed).y(2:end)'];
        Intersection1=lineSegmentIntersect(SeedSegment1,SectionSegment);
        Intersection2=lineSegmentIntersect(SeedSegment2,SectionSegment);
        [IntInd1_Row,IntInd1_Col]=find(Intersection1.intAdjacencyMatrix==1);
        [IntInd2_Row,IntInd2_Col]=find(Intersection2.intAdjacencyMatrix==1);
        IntInd1=min(IntInd1_Row);
        [IntInd2,iIntInd2]=min(IntInd2_Row);
        SeedCoordinate1=SeedCoordinate1(1:IntInd1+1,:);
        SeedCoordinate2=[SeedCoordinate2(1:IntInd2+1,:);...
            Intersection2.intMatrixX(IntInd2_Row(iIntInd2),IntInd2_Col(iIntInd2)),Intersection2.intMatrixY(IntInd2_Row(iIntInd2),IntInd2_Col(iIntInd2))];
    end
    SeedCoordinate=[flipud(SeedCoordinate1);SeedCoordinate2];

    % % remove overlapping seeds
    SeedCoordinateDiff=diff(SeedCoordinate);
    SeedDis=sqrt(SeedCoordinateDiff(:,1).^2+SeedCoordinateDiff(:,2).^2);
    iSeedDis=find(SeedDis~=0);
    SeedCoordinate=SeedCoordinate(iSeedDis,:);

    % % store seed information
    Seed_x=[];Seed_y=[];
    for iIn=1:size(SeedCoordinate,1);
        Seed_z(iIn)=interp2(Grid.x,Grid.y,Lid.Depth,SeedCoordinate(iIn,1),SeedCoordinate(iIn,2));
        InBoundaryIndex=inBounds(SeedCoordinate(iIn,1),SeedCoordinate(iIn,2),Seed_z(iIn),Geometry.ModelBoundary);
        if InBoundaryIndex;
            Seed_x=[Seed_x;SeedCoordinate(iIn,1)];
            Seed_y=[Seed_y;SeedCoordinate(iIn,2)];
        end
    end
    Seed(iSeed).x=Seed_x;
    Seed(iSeed).y=Seed_y;

    disp(sprintf('>>>    Melt seed contour from (%g,%g) to (%g,%g)',SeedCoordinate(1,:),SeedCoordinate(end,:)));
end

%% Seeds Plot

for iSeed=1:numel(Seed);
    plot(Seed(iSeed).x,Seed(iSeed).y,'w.');
end
axis equal; axis tight; box on;
title('ExcessT and Melt Line Seeds');

return