text:
$(function() {

	$.fn.googleMap = function(params) {
		params = $.extend( {
			zoom : 10,
			coords : [48.895651, 2.290569],
			type : "ROADMAP",
			debug : false,
			langage : "english",
			overviewMapControl: false,
			streetViewControl: false,
			scrollwheel: false,
			mapTypeControl: false
		}, params);

		switch(params.type) {
			case 'ROADMAP':
			case 'SATELLITE':
			case 'HYBRID':
			case 'TERRAIN':
				params.type = google.maps.MapTypeId[params.type];
				break;
			default:
				params.type = google.maps.MapTypeId.ROADMAP;
				break;
		}

		this.each(function() {

			var map = new google.maps.Map(this, {
				zoom: params.zoom,
				center: new google.maps.LatLng(params.coords[0], params.coords[1]),
				mapTypeId: params.type,
				scrollwheel: params.scrollwheel,
				streetViewControl: params.streetViewControl,
				overviewMapControl: params.overviewMapControl,
				mapTypeControl: params.mapTypeControl

			});

			$(this).data('googleMap', map);
			$(this).data('googleLang', params.langage);
			$(this).data('googleDebug', params.debug);
			$(this).data('googleMarker', new Array());
			$(this).data('googleBound', new google.maps.LatLngBounds());
		});

		return this;
	}

	$.fn.addMarker = function(params) {
		params = $.extend( {
			coords : false,
			address : false,
			url : false,
			id : false,
			icon : false,
			draggable : false,
			title : "",
			text : "",
			success : function() {}
		}, params);

		this.each(function() {
			$this = $(this);

			if(!$this.data('googleMap')) {
				if($this.data('googleDebug'))
					console.error("jQuery googleMap : Unable to add a marker where there is no map !");

				return false;
			}

			if(!params.coords && !params.address) {
				if($this.data('googleDebug'))
					console.error("jQuery googleMap : Unable to add a marker if you don't tell us where !");

				return false;
			}

			if(params.address && typeof params.address == "string") {

				var geocodeAsync = function($that) {

					var geocoder = new google.maps.Geocoder();

					geocoder.geocode({
						address : params.address,
						bounds : $that.data('googleBound'),
						language : $that.data('googleLang')
					}, function(results, status) {

						if (status == google.maps.GeocoderStatus.OK) {
							$that.data('googleBound').extend(results[0].geometry.location);

							if(params.icon) {
								var marker = new google.maps.Marker({
									map: $this.data('googleMap'),
									position: results[0].geometry.location,
									title: params.title,
									icon: params.icon,
									draggable: params.draggable
								});
							} else {
								var marker = new google.maps.Marker({
									map: $that.data('googleMap'),
									position: results[0].geometry.location,
									title: params.title,
									draggable: params.draggable
								});
							}

							if(params.draggable) {
								google.maps.event.addListener(marker, 'dragend', function() {
									var location = marker.getPosition();

									var coords = {};

									coords.lat = location.lat();
									coords.lon = location.lng();

									params.success(coords, $this);
								});
							}

							if(params.title != "" && params.text != "" && !params.url) {
								var infowindow = new google.maps.InfoWindow({
									content: "
"+params.title+"
"+params.text
								});

								var map = $that.data('googleMap');
                                previous_infowindow = null;
								google.maps.event.addListener(marker, 'click', function() {
                                    if(previous_infowindow!==null)
                                        previous_infowindow.close(map, marker);
									infowindow.open(map, marker);
                                    previous_infowindow=infowindow;
								});
							} else if(params.url) {
								google.maps.event.addListener(marker, 'click', function() {
									document.location = params.url;
								});
							}

							if(!params.id) {
								$that.data('googleMarker').push(marker);
							} else {
								$that.data('googleMarker')[params.id] = marker;
							}

							if($that.data('googleMarker').length == 1) {
								$that.data('googleMap').setCenter(results[0].geometry.location);
								$that.data('googleMap').setZoom($that.data('googleMap').getZoom());
							} else {
								$that.data('googleMap').fitBounds($that.data('googleBound'));
							}

							var coords = {};
							coords.lat = results[0].geometry.location.lat();
							coords.lon = results[0].geometry.location.lng();

							for(var i in results[0].address_components) {
								if(results[0].address_components[i].types.indexOf("postal_code") > -1) {
									coords.zipcode = results[0].address_components[i].long_name;
								}
							}

							params.success(coords, $this);

						} else {
							if($this.data('googleDebug'))
								console.error("jQuery googleMap : Unable to find the place asked for the marker ("+status+")");
						}
					});
				}($this);
			} else {
				$this.data('googleBound').extend(new google.maps.LatLng(params.coords[0], params.coords[1]));

        			if(params.icon) {
					var marker = new google.maps.Marker({
						map: $this.data('googleMap'),
						position: new google.maps.LatLng(params.coords[0], params.coords[1]),
						title: params.title,
						icon: params.icon,
						draggable: params.draggable
					});
				} else {
					var marker = new google.maps.Marker({
						map: $this.data('googleMap'),
						position: new google.maps.LatLng(params.coords[0], params.coords[1]),
						title: params.title,
						draggable: params.draggable
					});
				}

        			if(params.title != "" && params.text != "" && !params.url) {
          				var infowindow = new google.maps.InfoWindow({
						content: "
"+params.title+"
"+params.text
					});

					var map = $this.data('googleMap');
                    previous_infowindow = null;
	        			google.maps.event.addListener(marker, 'click', function() {
                            if(previous_infowindow!==null)
                                previous_infowindow.close(map, marker);
		        			infowindow.open(map, marker);
                            previous_infowindow=infowindow;
	        			});
				} else if(params.url) {
          				google.maps.event.addListener(marker, 'click', function() {
              					document.location = params.url;
        				});
				}

				if(params.draggable) {
					google.maps.event.addListener(marker, 'dragend', function() {
						var location = marker.getPosition();

						var coords = {};

						coords.lat = location.lat();
						coords.lon = location.lng();

						params.success(coords, $this);
					});
				}

				if(!params.id) {
       					$this.data('googleMarker').push(marker);
        			} else {
        				$this.data('googleMarker')[params.id] = marker;
        			}

				if($this.data('googleMarker').length == 1) {
					$this.data('googleMap').setCenter(new google.maps.LatLng(params.coords[0], params.coords[1]));
					$this.data('googleMap').setZoom($this.data('googleMap').getZoom());
				} else {
					$this.data('googleMap').fitBounds($this.data('googleBound'));
				}

				params.success({
					lat: params.coords[0],
					lon: params.coords[1]
				}, $this);
			}
		});

		return this;
	}

	$.fn.removeMarker = function(id) {
		this.each(function() {
			var $this = $(this);

    			if(!$this.data('googleMap')) {
    				if($this.data('googleDebug'))
      					console.log("jQuery googleMap : Unable to delete a marker where there is no map !");

      				return false;
    			}

    			var $markers = $this.data('googleMarker');

    			if(typeof $markers[id] != 'undefined') {
    				$markers[id].setMap(null);

      				if($this.data('googleDebug'))
      					console.log('jQuery googleMap : marker deleted');

      				return true;
    			} else {
      				if($this.data('googleDebug'))
      					console.error("jQuery googleMap : Unable to delete a marker if it not exists !");

      				return false;
    			}
		});
	}

	$.fn.addWay = function(params) {
		params = $.extend( {
			start : false,
			end : false,
			step : [],
			route : false,
			langage : 'english'
		}, params);

		var direction = new google.maps.DirectionsService({
			region: "fr"
		});

		var way = new google.maps.DirectionsRenderer({
			draggable: true,
			map: $(this).data('googleMap'),
			panel: document.getElementById(params.route),
			provideTripAlternatives: true
		});

		document.getElementById.innerHTML = "";

		var waypoints = [];

    		for(var i in params.step) {
    			var step;
      			if(typeof params.step[i] == "object") {
        			step = new google.maps.LatLng(params.step[i][0], params.step[i][1]);
      			} else {
        			step = params.step[i];
      			}

      			waypoints.push({
      				location: step,
      				stopover: true
      			});
		}

		if(typeof params.end != "object") {
			var geocodeAsync = function($that) {
				var geocoder = new google.maps.Geocoder();

		    		geocoder.geocode({
		    			address  : params.end,
		    			bounds   : $that.data('googleBound'),
		    			language : params.langage
		    		}, function(results, status) {
	        			if (status == google.maps.GeocoderStatus.OK) {
	        				var request = {
	            					origin: params.start,
	            					destination: results[0].geometry.location,
	            					travelMode: google.maps.DirectionsTravelMode.DRIVING,
	            					region: "fr",
	            					waypoints: waypoints
		        			};

		        			direction.route(request, function(response, status) {
	            					if (status == google.maps.DirectionsStatus.OK) {
	              						way.setDirections(response);
	            					} else {
	              						if($that.data('googleDebug'))
	            							console.error("jQuery googleMap : Unable to find the place asked for the route ("+response+")");
	            					}
		        			});

	        			} else {
	          				if($that.data('googleDebug'))
	          					console.error("jQuery googleMap : Address not found");
	        			}
		    		});
	    		}($(this));
		} else {
			var request = {
				origin: params.start,
				destination: new google.maps.LatLng(params.end[0], params.end[1]),
				travelMode: google.maps.DirectionsTravelMode.DRIVING,
				region: "fr",
				waypoints: waypoints
			};

			direction.route(request, function(response, status) {
				if (status == google.maps.DirectionsStatus.OK) {
					way.setDirections(response);
				} else {
					if($(this).data('googleDebug'))
          					console.error("jQuery googleMap : Address not found");
				}
			});
		}

		return this;
	}
});


text:
CConfigLongPage::CConfigLongPage(
    char* title,
    long* intvar,
    long minval,
    long maxval
) :
    CPage(title),
    value_variable(intvar),
    minimum_value(minval),
    maximum_value(maxval),
    previous_value(0),
    previous_page(NULL)
{
}

CConfigLongPage::~CConfigLongPage()
{
}

void CConfigLongPage::Init()
{
    previous_value = *value_variable;
    previous_page = current_page;
}

void CConfigLongPage::Display()
{
    txtClear();
    txtPrintf("%s\n\n", GetTitle());

    txtPrint("Curr value: ");
    txtAttrBold();
    txtPrintf("%d", *value_variable);
    txtAttrReset();
}

void CConfigLongPage::HandleKeys(short key)
{
    if (!key) {
        return;
    }

    if (key == KI_BACK) {
        *value_variable = previous_value;
        current_page = previous_page;
    }

    if (key == KI_ENTER) {
        current_page = previous_page;
    }

    if (key == KI_UP || key == KI_PREV) {
        int delta = 1;
        if (IsKeyDown(KI_FAST)) {
            delta = 10;
        }
        if (*value_variable + delta < maximum_value) {
            *value_variable += delta;
        } else {
            *value_variable = maximum_value;
        }
    }

    if (key == KI_DOWN || key == KI_NEXT) {
        int delta = 1;
        if (IsKeyDown(KI_FAST)) {
            delta = 10;
        }
        if (*value_variable - delta > minimum_value) {
            *value_variable -= delta;
        } else {
            *value_variable = minimum_value;
        }
    }

    UpdateDisplay();
}

redpajama_set_name: RedPajamaGithub


text:
layout: page
title: Coleman 55th Anniversary
date: 2016-05-24
author: Virginia Barker
tags: weekly links, java
status: published
summary: Nulla congue euismod ante, vel scelerisque.
banner: images/banner/leisure-05.jpg
booking:
  startDate: 01/16/2017
  endDate: 01/17/2017
  ctyhocn: BYGWYHX
  groupCode: C5A
published: true
---
Sed ut nulla quis orci mollis luctus. Vestibulum lacinia turpis est, vitae maximus nibh lobortis sit amet. Donec ante lorem, aliquet sit amet blandit ac, maximus eget dui. Nam condimentum semper interdum. Praesent non consequat tellus, nec elementum orci. In hac habitasse platea dictumst. Vivamus ante eros, finibus ut dolor at, suscipit tristique odio. In hac habitasse platea dictumst. Curabitur non pulvinar tortor. Fusce malesuada, orci in ornare consectetur, ligula lectus facilisis libero, at mattis ex magna eu turpis. Sed gravida euismod diam. Nulla facilisi. Donec sit amet dui nec ex volutpat fermentum.

1 Nulla ac sem aliquam, rhoncus ex ut, imperdiet tortor
1 Fusce scelerisque ligula eleifend urna euismod, lobortis rhoncus mauris accumsan
1 In sagittis nibh in ante eleifend, a rutrum orci sagittis
1 Vivamus vestibulum est nec est pretium, nec commodo quam mollis.

Nullam imperdiet ipsum eget nisi tempus, nec rhoncus neque laoreet. Vestibulum quis volutpat erat. Maecenas bibendum lobortis euismod. Quisque pretium lacinia arcu, finibus finibus arcu accumsan nec. Aliquam eu eros libero. Fusce at eros quam. Aliquam id ipsum arcu. Maecenas vehicula feugiat risus. Donec justo dolor, lacinia convallis felis nec, auctor egestas nulla. Nullam malesuada, arcu commodo gravida volutpat, diam nisi semper nunc, quis bibendum tellus nunc id velit. Nam magna justo, pretium quis luctus id, tristique in lacus. Proin pharetra vulputate lectus, id iaculis lacus commodo et.


text:
package com.intellij.compiler.chainsSearch;

import com.intellij.codeInsight.NullableNotNullManager;
import com.intellij.codeInsight.completion.InsertionContext;
import com.intellij.codeInsight.completion.JavaChainLookupElement;
import com.intellij.codeInsight.completion.JavaMethodCallElement;
import com.intellij.codeInsight.lookup.ExpressionLookupItem;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementDecorator;
import com.intellij.codeInsight.lookup.VariableLookupItem;
import com.intellij.compiler.chainsSearch.completion.lookup.ChainCompletionNewVariableLookupElement;
import com.intellij.compiler.chainsSearch.completion.lookup.JavaRelevantChainLookupElement;
import com.intellij.compiler.chainsSearch.context.ChainCompletionContext;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.Couple;
import com.intellij.psi.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.stream.Collectors;

public class MethodChainLookupRangingHelper {
  @NotNull
  public static LookupElement toLookupElement(MethodChain chain,
                                              ChainCompletionContext context) {
    int unreachableParametersCount = 0;
    int matchedParametersInContext = 0;
    LookupElement chainLookupElement = null;

    for (PsiMethod[] psiMethods : chain.getPath()) {
      PsiMethod method = ObjectUtils.notNull(MethodChainsSearchUtil.getMethodWithMinNotPrimitiveParameters(psiMethods, context.getTarget().getTargetClass()));
      Couple<Integer> info = calculateParameterInfo(method, context);
      unreachableParametersCount += info.getFirst();
      matchedParametersInContext += info.getSecond();

      if (chainLookupElement == null) {
        LookupElement qualifierLookupElement = createQualifierLookupElement(method, chain.getQualifierClass(), context);
        LookupElement headLookupElement = createMethodLookupElement(method);
        chainLookupElement = qualifierLookupElement == null ? headLookupElement : new JavaChainLookupElement(qualifierLookupElement, headLookupElement);
      } else {
        chainLookupElement = new JavaChainLookupElement(chainLookupElement, new JavaMethodCallElement(method));
      }
    }

    if (context.getTarget().isIteratorAccess()) {
      chainLookupElement = decorateWithIteratorAccess(chain.getFirst()[0], chainLookupElement);
    }

    return new JavaRelevantChainLookupElement(ObjectUtils.notNull(chainLookupElement),
                                              new ChainRelevance(chain.length(), unreachableParametersCount, matchedParametersInContext));
  }

  @NotNull
  private static LookupElementDecorator<LookupElement> decorateWithIteratorAccess(PsiMethod method, LookupElement chainLookupElement) {
    return new LookupElementDecorator<LookupElement>(chainLookupElement) {
      @Override
      public void handleInsert(InsertionContext context) {
        super.handleInsert(context);
        Document document = context.getDocument();
        int tail = context.getTailOffset();
        PsiType tailReturnType = method.getReturnType();
        if (tailReturnType instanceof PsiArrayType) {
          document.insertString(tail, "[0]");
          context.getEditor().getCaretModel().moveToOffset(tail + 1);
        } else {
          PsiClass returnClass = ObjectUtils.notNull(PsiUtil.resolveClassInClassTypeOnly(tailReturnType));
          PsiDocumentManager.getInstance(context.getProject()).doPostponedOperationsAndUnblockDocument(document);
          if (InheritanceUtil.isInheritor(returnClass, CommonClassNames.JAVA_UTIL_LIST)) {
            document.insertString(tail, ".get(0)");
            context.getEditor().getCaretModel().moveToOffset(tail + 5);
          } else if (InheritanceUtil.isInheritor(returnClass, CommonClassNames.JAVA_UTIL_COLLECTION)) {
            document.insertString(tail, ".iterator().next()");
          } else if (InheritanceUtil.isInheritor(returnClass, CommonClassNames.JAVA_UTIL_ITERATOR)) {
            document.insertString(tail, ".next()");
          } else if (InheritanceUtil.isInheritor(returnClass, CommonClassNames.JAVA_UTIL_STREAM_STREAM)) {
            document.insertString(tail, ".findFirst().get()");
          }
        }
      }
    };
  }

  @Nullable
  private static LookupElement createQualifierLookupElement(@NotNull PsiMethod method, @NotNull PsiClass qualifierClass, @NotNull ChainCompletionContext context) {
    if (method.hasModifierProperty(PsiModifier.STATIC)) return null;
    PsiNamedElement element = context.getQualifiers(qualifierClass).findFirst().orElse(null);
    if (element == null) {
      return new ChainCompletionNewVariableLookupElement(qualifierClass, context);
    } else {
      if (element instanceof PsiVariable) {
        return new VariableLookupItem((PsiVariable)element);
      }
      else if (element instanceof PsiMethod) {
        return createMethodLookupElement((PsiMethod)element);
      }
      throw new AssertionError("unexpected element: " + element);
    }
  }

  @NotNull
  private static Couple<Integer> calculateParameterInfo(@NotNull PsiMethod method,
                                                        @NotNull ChainCompletionContext context) {
    NullableNotNullManager nullableNotNullManager = NullableNotNullManager.getInstance(method.getProject());
    int unreachableParametersCount = 0;
    int matchedParametersInContext = 0;
    for (PsiParameter parameter : method.getParameterList().getParameters()) {
      PsiType type = parameter.getType();
      if (!ChainCompletionContext.isWidelyUsed(type)) {
        Collection<PsiElement> contextVariables = context.getQualifiers(type).collect(Collectors.toList());
        PsiElement contextVariable = ContainerUtil.getFirstItem(contextVariables, null);
        if (contextVariable != null) {
          matchedParametersInContext++;
          continue;
        }
        if (!nullableNotNullManager.isNullable(parameter, true)) {
          unreachableParametersCount++;
        }
      }
    }

    return Couple.of(unreachableParametersCount, matchedParametersInContext);
  }

  @NotNull
  private static LookupElement createMethodLookupElement(@NotNull PsiMethod method) {
    LookupElement result;
    if (method.isConstructor()) {
      PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(method.getProject());
      result = new ExpressionLookupItem(elementFactory.createExpressionFromText("new " + method.getContainingClass().getQualifiedName() + "()", null));
    } else if (method.hasModifierProperty(PsiModifier.STATIC)) {
      result = new JavaMethodCallElement(method, false, true);
    } else {
      result = new JavaMethodCallElement(method);
    }
    return result;
  }
}


text:
Kubernetes Steps
----------------

This plugin provides pipeline steps useful for working with kubernetes:

- [Working with Kubernetes Pods](#working-with-kubernetes-pods)
- [Working with Docker Images](#working-with-docker-images)

## Working with Kubernetes Pods

Quite often a build needs to run some steps using specific tools and environment configuration.
In kubernetes this translates to a container that uses a specific image *(that provides the tools)*, has access to volume mounts (persistent volumes, secrets, configmaps).

This plugin provides pipeline steps, that allow you to create a pod and run custom shell steps inside a container.

The overall syntax looks like this:

    kubernetes.pod('buildpod')
        .withSerivceAccount(<serivce accoutn>)
        .withSecret(<mount path>, <secret name>)
        .withEnvar(<gloabal key1>, <value1>)
        .withNewContainer().withName(<name1>).withImage(<image1>)
                           .withEnv(<key1>,<value1>)
                           .and()
        .withNewContainer().withName(<name2>).withImage(<image2>).inside {
            sh '<some shell commands that are going to be run inside name2>'
    }

The are are a lot of shortcuts that make the syntax less verbose, and sugar that makes it read better. Most of the options are explained below.
It's even possible to skip the DSL completely and just use the steps directly or with the help of the script builder.

When a snippet like the above is wrapped inside a `node` it will just create the build pod and run the specified shell commands inside it.
If there is no `none` it will delegate to [kubernetes plugin](#https://github.com/jenkinsci/kubernetes-plugin) and create a kubernetes slave pod, that will additionally
contain the specified container.

### Using a maven kubernetes pod

    kubernetes.pod('buildpod').withImage('maven').inside {
        //for a single container you can avoid the .withNewContainer() thing.
        git 'https://github.com/jenkinsci/kubernetes-pipeline.git'
        sh 'mvn clean install'
    }

### Using environment variables

    kubernetes.pod('buildpod').withImage('maven').withEnvar('DOCKER_CONFIG','/home/jenkins/.docker/').inside {
        git 'https://github.com/fabric8io/kubernetes-pipeline.git'
        sh 'mvn clean install'
    }

### Using Volumes

Currently the following volume types are supported:

- Secrets
- Host Path
- Empty Dir

#### Using secrets

    kubernetes.pod('buildpod').withImage('maven').withSecret('gpg-key','/home/jenkins/.gnupg').inside {
        git 'https://github.com/fabric8io/kubernetes-pipeline.git'
        sh 'mvn clean install'
    }

#### Using host path mounts

    kubernetes.pod('buildpod').withImage('maven').withHostPathMount('/path/on/host', '/path/on/container').inside {
        git 'https://github.com/fabric8io/kubernetes-pipeline.git'
        sh 'mvn clean install'
    }

#### Using empty Dir mounts

    kubernetes.pod('buildpod').withImage('maven').withEmptyDir('/path/on/container').inside {
        git 'https://github.com/fabric8io/kubernetes-pipeline.git'
        sh 'mvn clean install'
    }

This also supports specifying the medium (e.g. "Memory")

    kubernetes.pod('buildpod').withImage('maven').withEmptyDir('/path/on/container', 'Memory').inside {
        git 'https://github.com/fabric8io/kubernetes-pipeline.git'
        sh 'mvn clean install'
    }

#### Using volume claim mounts

    kubernetes.pod('buildpod').withImage('maven').withVolumeClaim('/path/on/container', 'volume-claim-name').inside {
        git 'https://github.com/fabric8io/kubernetes-pipeline.git'
        sh 'mvn clean install'
    }

### Using privileged containers

    kubernetes.pod('buildpod').withImage('maven').withPrivileged(true).inside {
        git 'https://github.com/fabric8io/kubernetes-pipeline.git'
        sh 'mvn clean install'
    }

### Workspace Requirements

The build pod needs to access the workspace of the project. This can be achieved with the use of volume mounts.
You can configure volume mounts manually in order to mount `/home/jenkins/workspace` or `/home/jenkins/workspace/<job name>`
or let the plugin configure them for you.

The plugin will search and reuse any volume mounts you've configured for these paths.

If none is found it will try to create them using Persistent Volume Claims or Host Path mounts.

#### Using Persistent Volume Claim

If there is a pvc named `jenkins-workspace` the plugin will automatically mount it to `/home/jenkins/workspace`.
Else if there is a pvc named `jenkins-workspace-<job name>` the plugin will automatically mount it to `/home/jenkins/workspace/<job name>`.

If none of the above is found it will fallback to hostPath volumes.

#### Using Host Path Volumes

As a last resort the plugin will try to mount the hostPath `/home/jenkins/workspace`.
In some case host path volumes are not allowed, so this is the last resort and should be avoided as much as possible.

## Working with Docker Images

### Building, Tagging and Pushing

    node {
        git 'https://github.com/fabric8-quickstarts/node-example.git'
        if (!fileExists ('Dockerfile')) {
          writeFile file: 'Dockerfile', text: 'FROM node:5.3-onbuild'
        }
        kubernetes.image().withName("example").build().fromPath(".")
        kubernetes.image().withName("example").tag().inRepository("172.30.101.121:5000/default/example").withTag("1.0")
        kubernetes.image().withName("172.30.101.121:5000/default/example").push().withTag("1.0").toRegistry()
    }

### Skipping the tagging part

You can directly tag the image during the build step:

    node {
        git 'https://github.com/fabric8-quickstarts/node-example.git'
        if (!fileExists ('Dockerfile')) {
          writeFile file: 'Dockerfile', text: 'FROM node:5.3-onbuild'
        }
        kubernetes.image().withName("172.30.101.121:5000/default/example").build().fromPath(".")
        kubernetes.image().withName("172.30.101.121:5000/default/example").push().toRegistry()
    }

## Technical notes

Under the hood the plugin is using hostPath mounts. This requires two things

- A service account associated with a security context constraint that allows hostPath mounts.
- A host capable of hostPath mounts

An example security context constraint that configures *myserviceacccount* in the *default* namespace can be found [here](docs/scc-example.json)

In some linux distros in order to use hostPath mounts you may need to use the following command on the docker host:

    chcon -Rt svirt_sandbox_file_t <host path>


text:
import { Component } from '@angular/core';

@Component({
  selector: 'app-how-dialog',
  templateUrl: './how-dialog.component.html',
  styleUrls: ['./how-dialog.component.scss']
})
export class HowDialogComponent {
  constructor() { }
}


text:
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/platform/graphics/video_frame_image_util.h"

#include "base/logging.h"
#include "build/build_config.h"
#include "components/viz/common/gpu/raster_context_provider.h"
#include "components/viz/common/resources/release_callback.h"
#include "gpu/command_buffer/client/raster_interface.h"
#include "gpu/config/gpu_feature_info.h"
#include "media/base/video_frame.h"
#include "media/base/video_types.h"
#include "media/base/video_util.h"
#include "media/base/wait_and_replace_sync_token_client.h"
#include "media/renderers/paint_canvas_video_renderer.h"
#include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/gpu/GrDriverBugWorkarounds.h"
#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/skia_conversions.h"

namespace blink {

namespace {

bool CanUseZeroCopyImages(const media::VideoFrame& frame) {
  // SharedImage optimization: create AcceleratedStaticBitmapImage directly.
  // Disabled on Android because the hardware decode implementation may neuter
  // frames, which would violate ImageBitmap requirements.
  // TODO(sandersd): Handle YUV pixel formats.
  // TODO(sandersd): Handle high bit depth formats.
  // TODO(crbug.com/1203713): Figure out why macOS zero copy ends up with y-flip
  // images in zero copy mode.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
  return false;
#else
  return frame.NumTextures() == 1 &&
         frame.mailbox_holder(0).mailbox.IsSharedImage() &&
         (frame.format() == media::PIXEL_FORMAT_ARGB ||
          frame.format() == media::PIXEL_FORMAT_XRGB ||
          frame.format() == media::PIXEL_FORMAT_ABGR ||
          frame.format() == media::PIXEL_FORMAT_XBGR ||
          frame.format() == media::PIXEL_FORMAT_BGRA);
#endif
}

bool ShouldCreateAcceleratedImages(
    viz::RasterContextProvider* raster_context_provider) {
  if (!SharedGpuContext::IsGpuCompositingEnabled())
    return false;

  if (!raster_context_provider)
    return false;

  if (raster_context_provider->GetGpuFeatureInfo().IsWorkaroundEnabled(
          DISABLE_IMAGEBITMAP_FROM_VIDEO_USING_GPU)) {
    return false;
  }

  return true;
}

}  // namespace

ImageOrientationEnum VideoTransformationToImageOrientation(
    media::VideoTransformation transform) {
  if (!transform.mirrored) {
    switch (transform.rotation) {
      case media::VIDEO_ROTATION_0:
        return ImageOrientationEnum::kOriginTopLeft;
      case media::VIDEO_ROTATION_90:
        return ImageOrientationEnum::kOriginRightTop;
      case media::VIDEO_ROTATION_180:
        return ImageOrientationEnum::kOriginBottomRight;
      case media::VIDEO_ROTATION_270:
        return ImageOrientationEnum::kOriginLeftBottom;
    }
  }

  switch (transform.rotation) {
    case media::VIDEO_ROTATION_0:
      return ImageOrientationEnum::kOriginTopRight;
    case media::VIDEO_ROTATION_90:
      return ImageOrientationEnum::kOriginLeftTop;
    case media::VIDEO_ROTATION_180:
      return ImageOrientationEnum::kOriginBottomLeft;
    case media::VIDEO_ROTATION_270:
      return ImageOrientationEnum::kOriginRightBottom;
  }
}

media::VideoTransformation ImageOrientationToVideoTransformation(
    ImageOrientationEnum orientation) {
  switch (orientation) {
    case ImageOrientationEnum::kOriginTopLeft:
      return media::kNoTransformation;
    case ImageOrientationEnum::kOriginTopRight:
      return media::VideoTransformation(media::VIDEO_ROTATION_0,
                                        /*mirrored=*/true);
    case ImageOrientationEnum::kOriginBottomRight:
      return media::VIDEO_ROTATION_180;
    case ImageOrientationEnum::kOriginBottomLeft:
      return media::VideoTransformation(media::VIDEO_ROTATION_180,
                                        /*mirrored=*/true);
    case ImageOrientationEnum::kOriginLeftTop:
      return media::VideoTransformation(media::VIDEO_ROTATION_90,
                                        /*mirrored=*/true);
    case ImageOrientationEnum::kOriginRightTop:
      return media::VIDEO_ROTATION_90;
    case ImageOrientationEnum::kOriginRightBottom:
      return media::VideoTransformation(media::VIDEO_ROTATION_270,
                                        /*mirrored=*/true);
    case ImageOrientationEnum::kOriginLeftBottom:
      return media::VIDEO_ROTATION_270;
  };
}

bool WillCreateAcceleratedImagesFromVideoFrame(const media::VideoFrame* frame) {
  return CanUseZeroCopyImages(*frame) ||
         ShouldCreateAcceleratedImages(GetRasterContextProvider().get());
}

scoped_refptr<StaticBitmapImage> CreateImageFromVideoFrame(
    scoped_refptr<media::VideoFrame> frame,
    bool allow_zero_copy_images,
    CanvasResourceProvider* resource_provider,
    media::PaintCanvasVideoRenderer* video_renderer,
    const gfx::Rect& dest_rect,
    bool prefer_tagged_orientation) {
  DCHECK(frame);
  const auto transform =
      frame->metadata().transformation.value_or(media::kNoTransformation);
  if (allow_zero_copy_images && dest_rect.IsEmpty() &&
      transform == media::kNoTransformation && CanUseZeroCopyImages(*frame)) {
    // TODO(sandersd): Do we need to be able to handle limited-range RGB? It
    // may never happen, and SkColorSpace doesn't know about it.
    auto sk_color_space =
        frame->ColorSpace().GetAsFullRangeRGB().ToSkColorSpace();
    if (!sk_color_space)
      sk_color_space = SkColorSpace::MakeSRGB();

    const SkImageInfo sk_image_info = SkImageInfo::Make(
        frame->coded_size().width(), frame->coded_size().height(),
        kN32_SkColorType, kUnpremul_SkAlphaType, std::move(sk_color_space));

    // Hold a ref by storing it in the release callback.
    auto release_callback = WTF::BindOnce(
        [](scoped_refptr<media::VideoFrame> frame,
           base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider,
           const gpu::SyncToken& sync_token, bool is_lost) {
          if (is_lost || !context_provider)
            return;
          auto* ri = context_provider->ContextProvider()->RasterInterface();
          media::WaitAndReplaceSyncTokenClient client(ri);
          frame->UpdateReleaseSyncToken(&client);
        },
        frame, SharedGpuContext::ContextProviderWrapper());

    return AcceleratedStaticBitmapImage::CreateFromCanvasMailbox(
        frame->mailbox_holder(0).mailbox, frame->mailbox_holder(0).sync_token,
        0u, sk_image_info, frame->mailbox_holder(0).texture_target,
        frame->metadata().texture_origin_is_top_left,
        // Pass nullptr for |context_provider_wrapper|, because we don't
        // know which context the mailbox came from. It is used only to
        // detect when the mailbox is invalid due to context loss, and is
        // ignored when |is_cross_thread|.
        base::WeakPtr<WebGraphicsContext3DProviderWrapper>(),
        // Pass null |context_thread_ref|, again because we don't know
        // which context the mailbox came from. This should always trigger
        // |is_cross_thread|.
        base::PlatformThreadRef(),
        // The task runner is only used for |release_callback|.
        ThreadScheduler::Current()->CleanupTaskRunner(),
        std::move(release_callback),
        /*supports_display_compositing=*/true,
        // TODO(junov): Figure out how to determine whether frame is an
        // overlay candidate. StorageType info seems insufficient.
        /*is_overlay_candidate=*/false);
  }

  gfx::Rect final_dest_rect = dest_rect;
  if (final_dest_rect.IsEmpty()) {
    // Since we're copying, the destination is always aligned with the origin.
    const auto& visible_rect = frame->visible_rect();
    final_dest_rect =
        gfx::Rect(0, 0, visible_rect.width(), visible_rect.height());
    if (transform.rotation == media::VIDEO_ROTATION_90 ||
        transform.rotation == media::VIDEO_ROTATION_270) {
      final_dest_rect.Transpose();
    }
  } else if (!resource_provider) {
    DLOG(ERROR) << "An external CanvasResourceProvider must be provided when "
                   "providing a custom destination rect.";
    return nullptr;
  } else if (!gfx::Rect(resource_provider->Size()).Contains(final_dest_rect)) {
    DLOG(ERROR)
        << "Provided CanvasResourceProvider is too small. Expected at least "
        << final_dest_rect.ToString() << " got "
        << resource_provider->Size().ToString();
    return nullptr;
  }

  auto raster_context_provider = GetRasterContextProvider();
  // TODO(https://crbug.com/1341235): The choice of color type, alpha type,
  // and color space is inappropriate in many circumstances.
  const auto resource_provider_info =
      SkImageInfo::Make(gfx::SizeToSkISize(final_dest_rect.size()),
                        kN32_SkColorType, kPremul_SkAlphaType, nullptr);
  std::unique_ptr<CanvasResourceProvider> local_resource_provider;
  if (!resource_provider) {
    local_resource_provider = CreateResourceProviderForVideoFrame(
        resource_provider_info, raster_context_provider.get());
    if (!local_resource_provider) {
      DLOG(ERROR) << "Failed to create CanvasResourceProvider.";
      return nullptr;
    }

    resource_provider = local_resource_provider.get();
  }

  if (resource_provider->IsAccelerated())
    prefer_tagged_orientation = false;

  if (!DrawVideoFrameIntoResourceProvider(
          std::move(frame), resource_provider, raster_context_provider.get(),
          final_dest_rect, video_renderer,
          /*ignore_video_transformation=*/prefer_tagged_orientation)) {
    return nullptr;
  }

  return resource_provider->Snapshot(
      prefer_tagged_orientation
          ? VideoTransformationToImageOrientation(transform)
          : ImageOrientationEnum::kDefault);
}

bool DrawVideoFrameIntoResourceProvider(
    scoped_refptr<media::VideoFrame> frame,
    CanvasResourceProvider* resource_provider,
    viz::RasterContextProvider* raster_context_provider,
    const gfx::Rect& dest_rect,
    media::PaintCanvasVideoRenderer* video_renderer,
    bool ignore_video_transformation) {
  DCHECK(frame);
  DCHECK(resource_provider);
  DCHECK(gfx::Rect(resource_provider->Size()).Contains(dest_rect));

  if (frame->HasTextures()) {
    if (!raster_context_provider) {
      DLOG(ERROR) << "Unable to process a texture backed VideoFrame w/o a "
                     "RasterContextProvider.";
      return false;  // Unable to get/create a shared main thread context.
    }
    if (!raster_context_provider->GrContext() &&
        !raster_context_provider->ContextCapabilities().supports_oop_raster) {
      DLOG(ERROR) << "Unable to process a texture backed VideoFrame w/o a "
                     "GrContext or OOP raster support.";
      return false;  // The context has been lost.
    }
  }

  cc::PaintFlags media_flags;
  media_flags.setAlpha(0xFF);
  media_flags.setFilterQuality(cc::PaintFlags::FilterQuality::kLow);
  media_flags.setBlendMode(SkBlendMode::kSrc);

  std::unique_ptr<media::PaintCanvasVideoRenderer> local_video_renderer;
  if (!video_renderer) {
    local_video_renderer = std::make_unique<media::PaintCanvasVideoRenderer>();
    video_renderer = local_video_renderer.get();
  }

  // If the provider isn't accelerated, avoid GPU round trips to upload frame
  // data from GpuMemoryBuffer backed frames which aren't mappable.
  if (frame->HasGpuMemoryBuffer() && !frame->IsMappable() &&
      !resource_provider->IsAccelerated()) {
    frame = media::ConvertToMemoryMappedFrame(std::move(frame));
    if (!frame) {
      DLOG(ERROR) << "Failed to map VideoFrame.";
      return false;
    }
  }

  video_renderer->Paint(
      frame.get(), resource_provider->Canvas(/*needs_will_draw*/ true),
      gfx::RectF(dest_rect), media_flags,
      ignore_video_transformation
          ? media::kNoTransformation
          : frame->metadata().transformation.value_or(media::kNoTransformation),
      raster_context_provider);
  return true;
}

void DrawVideoFrameIntoCanvas(scoped_refptr<media::VideoFrame> frame,
                              cc::PaintCanvas* canvas,
                              cc::PaintFlags& flags,
                              bool ignore_video_transformation) {
  viz::RasterContextProvider* raster_context_provider = nullptr;
  if (auto wrapper = SharedGpuContext::ContextProviderWrapper()) {
    if (auto* context_provider = wrapper->ContextProvider())
      raster_context_provider = context_provider->RasterContextProvider();
  }

  const gfx::RectF dest_rect(frame->natural_size().width(),
                             frame->natural_size().height());

  media::PaintCanvasVideoRenderer video_renderer;
  auto transformation =
      ignore_video_transformation
          ? media::kNoTransformation
          : frame->metadata().transformation.value_or(media::kNoTransformation);
  video_renderer.Paint(frame, canvas, dest_rect, flags, transformation,
                       raster_context_provider);
}

scoped_refptr<viz::RasterContextProvider> GetRasterContextProvider() {
  auto wrapper = SharedGpuContext::ContextProviderWrapper();
  if (!wrapper)
    return nullptr;

  if (auto* provider = wrapper->ContextProvider())
    return base::WrapRefCounted(provider->RasterContextProvider());

  return nullptr;
}

std::unique_ptr<CanvasResourceProvider> CreateResourceProviderForVideoFrame(
    const SkImageInfo& info,
    viz::RasterContextProvider* raster_context_provider) {
  if (!ShouldCreateAcceleratedImages(raster_context_provider)) {
    return CanvasResourceProvider::CreateBitmapProvider(
        info, cc::PaintFlags::FilterQuality::kLow,
        CanvasResourceProvider::ShouldInitialize::kNo);
  }
  return CanvasResourceProvider::CreateSharedImageProvider(
      info, cc::PaintFlags::FilterQuality::kLow,
      CanvasResourceProvider::ShouldInitialize::kNo,
      SharedGpuContext::ContextProviderWrapper(), RasterMode::kGPU,
      false,  // Origin of GL texture is bottom left on screen
      gpu::SHARED_IMAGE_USAGE_DISPLAY_READ);
}

}  // namespace blink


text:
require 'formatron/util/winrm'

class Formatron
  class Chef
    # Perform commands on chef nodes over WinRM
    class WinRM
      def initialize(administrator_name:, administrator_password:)
        @administrator_name = administrator_name
        @administrator_password = administrator_password
      end

      def run_chef_client(hostname:)
        # use the first-boot.json to ensure the runlist is correct
        # if the node fails to converge the first time (in which case
        # the server will show an empty run list for the node)
        Formatron::Util::WinRM.exec(
          hostname: hostname,
          administrator_name: @administrator_name,
          administrator_password: @administrator_password,
          command: 'chef-client -j C:\chef\first-boot.json'
        )
      end

      def bootstrapped?(hostname:)
        Formatron::Util::WinRM.exec(
          hostname: hostname,
          administrator_name: @administrator_name,
          administrator_password: @administrator_password,
          command: 'if (-not (Test-Path C:\chef\client.pem)) { exit 1 }'
        )
        true
      rescue
        false
      end
    end
  end
end


text:
require 'spec_helper'

RSpec.describe LiveEditor::CLI::Config::ContentTemplatesConfig, fakefs: true do
  context 'with valid JSON' do
    let(:content_templates) do
      [
        { 'title' => 'Article' }
      ]
    end

    let(:data) do
      { 'content_templates' => content_templates }
    end

    before do
      File.open('/config.json', 'w') do |f|
        f.write JSON.generate(data)
      end
    end

    it 'returns content templates' do
      config = LiveEditor::CLI::Config::ContentTemplatesConfig.new('/config.json')
      expect(config.content_templates).to eql content_templates
    end
  end

  context 'with invalid JSON' do
    let(:data) { 'banana' }

    before do
      File.open('/config.json', 'w') do |f|
        f.write data
      end
    end

    it 'returns an empty array' do
      config = LiveEditor::CLI::Config::ContentTemplatesConfig.new('/config.json')
      expect(config.content_templates).to eql []
    end
  end
end


text:
@interface JIAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end


text:
using System.Collections;
#if dotnet2
using System.Collections.Generic;
#endif

namespace IBatisNet.DataMapper.Test.Domain
{
    public class Coupon
    {
        private int id;
        private string _code;

        public virtual int Id
        {
            get { return id; }
            set { id = value; }
        }

        public string Code
        {
            get { return _code; }
            set { _code = value; }
        }

#if dotnet2
        private IList<int> _brandIds = new List<int>();

        public IList<int> BrandIds
        {
            get { return _brandIds; }
            set { _brandIds = value; }
        }
#else
        private IList _brandIds = new List();

        public IList BrandIds
        {
            get { return _brandIds; }
            set { _brandIds = value; }
        }
#endif
    }
}


text:
namespace base {
class FilePath;
}

// Observes changes in BrowserStateInfoCache.
class BrowserStateInfoCacheObserver {
 public:
  BrowserStateInfoCacheObserver() {}

  BrowserStateInfoCacheObserver(const BrowserStateInfoCacheObserver&) = delete;
  BrowserStateInfoCacheObserver& operator=(
      const BrowserStateInfoCacheObserver&) = delete;

  virtual ~BrowserStateInfoCacheObserver() {}

  // Called when a BrowserState has been added.
  virtual void OnBrowserStateAdded(const base::FilePath& path) = 0;

  // Called when a BrowserState has been removed.
  virtual void OnBrowserStateWasRemoved(const base::FilePath& path) = 0;
};

#endif  // IOS_CHROME_BROWSER_BROWSER_STATE_BROWSER_STATE_INFO_CACHE_OBSERVER_H_


text:
require 'test_helper'

module Shipit
  class WebhooksControllerTest < ActionController::TestCase
    setup do
      @stack = shipit_stacks(:shipit)
      GithubHook.any_instance.stubs(:verify_signature).returns(true)
    end

    test ":push with the target branch queues a GithubSyncJob" do
      request.headers['X-Github-Event'] = 'push'
      params = payload(:push_master)

      assert_enqueued_with(job: GithubSyncJob, args: [stack_id: @stack.id]) do
        post :push, params: {stack_id: @stack.id}.merge(params)
      end
    end

    test ":push does not enqueue a job if not the target branch" do
      request.headers['X-Github-Event'] = 'push'
      params = payload(:push_not_master)
      assert_no_enqueued_jobs do
        post :push, params: {stack_id: @stack.id}.merge(params)
      end
    end

    test ":state create a Status for the specific commit" do
      request.headers['X-Github-Event'] = 'status'

      status_payload = payload(:status_master)
      commit = shipit_commits(:first)

      assert_difference 'commit.statuses.count', 1 do
        post :state, params: {stack_id: @stack.id}.merge(status_payload)
      end

      status = commit.statuses.last
      assert_equal status_payload['target_url'], status.target_url
      assert_equal status_payload['state'], status.state
      assert_equal status_payload['description'], status.description
      assert_equal status_payload['context'], status.context
      assert_equal status_payload['created_at'], status.created_at.iso8601
    end

    test ":state with a unexisting commit respond with 200 OK" do
      request.headers['X-Github-Event'] = 'status'
      params = {'sha' => 'notarealcommit', 'state' => 'pending', 'branches' => [{'name' => 'master'}]}
      post :state, params: {stack_id: @stack.id}.merge(params)
      assert_response :ok
    end

    test ":state in an untracked branche bails out" do
      request.headers['X-Github-Event'] = 'status'
      params = {'sha' => 'notarealcommit', 'state' => 'pending', 'branches' => []}
      post :state, params: {stack_id: @stack.id}.merge(params)
      assert_response :ok
    end

    test ":push returns head :ok if request is ping" do
      @request.headers['X-Github-Event'] = 'ping'

      assert_no_enqueued_jobs do
        post :state, params: {stack_id: @stack.id, zen: 'Git is beautiful'}
        assert_response :ok
      end
    end

    test ":state returns head :ok if request is ping" do
      @request.headers['X-Github-Event'] = 'ping'

      assert_no_enqueued_jobs do
        post :state, params: {stack_id: @stack.id}
        assert_response :ok
      end
    end

    test ":state verifies webhook signature" do
      commit = shipit_commits(:first)

      params = {"sha" => commit.sha, "state" => "pending", "target_url" => "https://ci.example.com/1000/output"}
      signature = 'sha1=4848deb1c9642cd938e8caa578d201ca359a8249'

      @request.headers['X-Github-Event'] = 'push'
      @request.headers['X-Hub-Signature'] = signature

      GithubHook.any_instance.expects(:verify_signature).with(signature, URI.encode_www_form(params)).returns(false)

      post :push, params: {stack_id: @stack.id}.merge(params)
      assert_response :unprocessable_entity
    end

    test ":push verifies webhook signature" do
      params = {"ref" => "refs/heads/master"}
      signature = 'sha1=ad1d939e9acd6bdc2415a2dd5951be0f2a796ce0'

      @request.headers['X-Github-Event'] = 'push'
      @request.headers['X-Hub-Signature'] = signature

      GithubHook.any_instance.expects(:verify_signature).with(signature, URI.encode_www_form(params)).returns(false)

      post :push, params: {stack_id: @stack.id}.merge(params)
      assert_response :unprocessable_entity
    end

    test ":membership creates the mentioned team on the fly" do
      assert_difference -> { Team.count }, 1 do
        post :membership, params: membership_params.merge(team: {
          id: 48,
          name: 'Ouiche Cooks',
          slug: 'ouiche-cooks',
          url: 'https://example.com',
        })
        assert_response :ok
      end
    end

    test ":membership creates the mentioned user on the fly" do
      Shipit.github_api.expects(:user).with('george').returns(george)
      assert_difference -> { User.count }, 1 do
        post :membership, params: membership_params.merge(member: {login: 'george'})
        assert_response :ok
      end
    end

    test ":membership can delete an user membership" do
      assert_difference -> { Membership.count }, -1 do
        post :membership, params: membership_params.merge(_action: 'removed')
        assert_response :ok
      end
    end

    test ":membership can append an user membership" do
      assert_difference -> { Membership.count }, 1 do
        post :membership, params: membership_params.merge(member: {login: 'bob'})
        assert_response :ok
      end
    end

    test ":membership can append an user twice" do
      assert_no_difference -> { Membership.count } do
        post :membership, params: membership_params
        assert_response :ok
      end
    end

    test ":membership can delete an user twice" do
      assert_no_difference -> { Membership.count } do
        post :membership, params: membership_params.merge(_action: 'removed', member: {login: 'bob'})
        assert_response :ok
      end
    end

    test ":membership can append a user membership for an organization with capitals" do
      assert_difference -> { Membership.count }, 1 do
        post :membership, params: membership_params.merge(organization: {login: 'Shopify'}, member: {login: 'bob'})
        assert_response :ok
      end
    end

    private

    def membership_params
      {_action: 'added', team: team_params, organization: {login: 'shopify'}, member: {login: 'walrus'}}
    end

    def team_params
      {id: shipit_teams(:shopify_developers).id, slug: 'developers', name: 'Developers', url: 'http://example.com'}
    end

    def george
      stub(
        id: 42,
        name: 'George Abitbol',
        login: 'george',
        email: 'george@cyclim.se',
        avatar_url: 'https://avatars.githubusercontent.com/u/42?v=3',
        url: 'https://api.github.com/user/george',
      )
    end
  end
end


text:
<?php

namespace ZendTest\Loader\TestAsset\TestPlugins2;

/**
 * @category   Zend
 * @package    Loader
 * @subpackage UnitTests
 * @group      Loader
 */
class Foo
{
}


text:
package org.wso2.msf4j;

import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.wso2.msf4j.conf.Constants;
import org.wso2.msf4j.interceptor.HighPriorityGlobalRequestInterceptor;
import org.wso2.msf4j.interceptor.HighPriorityGlobalResponseInterceptor;
import org.wso2.msf4j.interceptor.LowPriorityGlobalRequestInterceptor;
import org.wso2.msf4j.interceptor.LowPriorityGlobalResponseInterceptor;
import org.wso2.msf4j.interceptor.MediumPriorityGlobalRequestInterceptor;
import org.wso2.msf4j.interceptor.MediumPriorityGlobalResponseInterceptor;
import org.wso2.msf4j.interceptor.PriorityDataHolder;
import org.wso2.msf4j.interceptor.TestBreakRequestInterceptor;
import org.wso2.msf4j.interceptor.TestBreakResponseInterceptor;
import org.wso2.msf4j.interceptor.TestExceptionBreakRequestInterceptor;
import org.wso2.msf4j.interceptor.TestInterceptorDeprecated;
import org.wso2.msf4j.interceptor.TestRequestInterceptor;
import org.wso2.msf4j.interceptor.TestResponseInterceptor;
import org.wso2.msf4j.service.InterceptorTestMicroService;
import org.wso2.msf4j.service.PriorityInterceptorTestMicroService;
import org.wso2.msf4j.service.sub.Player;
import org.wso2.msf4j.service.sub.Team;

import java.net.URI;
import java.net.URL;
import java.util.Collections;

import static org.testng.AssertJUnit.assertEquals;

/**
 * Class for testing interceptors.
 *

 * Please note that the deprecated interceptors are also tested along the way.
 */
public class InterceptorTest extends InterceptorTestBase {

    private static final int port = Constants.PORT + 6;
    private final String microServiceBaseUrl = "/test/interceptorTest/";
    private MicroservicesRunner microservicesRunner;
    private final InterceptorTestMicroService interceptorTestMicroService = new InterceptorTestMicroService();
    private final PriorityInterceptorTestMicroService priorityInterceptorTestMicroService =
            new PriorityInterceptorTestMicroService();

    @BeforeClass
    public void setup() throws Exception {
        URL resource = Thread.currentThread().getContextClassLoader().getResource("netty-transports-3.yaml");
        if (resource == null) {
            Assert.fail("netty-transports-3.yaml not found");
        }
        System.setProperty("transports.netty.conf", resource.getPath());
        microservicesRunner = new MicroservicesRunner(port);

        // Global request interceptors are registered in the priority order of new interceptors -> old interceptors
        // Global response interceptors are registered in the priority order of old interceptors -> new interceptors
        microservicesRunner
                .deploy(interceptorTestMicroService)
                .deploy(priorityInterceptorTestMicroService)
                .addGlobalRequestInterceptor(new HighPriorityGlobalRequestInterceptor(),
                        new MediumPriorityGlobalRequestInterceptor(), new LowPriorityGlobalRequestInterceptor())
                .addInterceptor(new TestInterceptorDeprecated())
                .addGlobalResponseInterceptor(new HighPriorityGlobalResponseInterceptor(),
                        new MediumPriorityGlobalResponseInterceptor(), new LowPriorityGlobalResponseInterceptor())
                .start();
        baseURI = URI.create("http://" + Constants.HOSTNAME + ":" + port);
        Thread.sleep(1000);
    }

    @AfterClass
    public void tearDown() throws Exception {
        microservicesRunner.stop();
    }

    @BeforeMethod
    public void reset() {
        PriorityDataHolder.setPriorityOrder("");

        // Reset request interceptors
        TestRequestInterceptor.reset();

        // Reset response interceptors
        TestResponseInterceptor.reset();

        // Reset global request interceptors
        HighPriorityGlobalRequestInterceptor.reset();
        MediumPriorityGlobalRequestInterceptor.reset();
        LowPriorityGlobalRequestInterceptor.reset();

        // Reset global response interceptors
        HighPriorityGlobalResponseInterceptor.reset();
        MediumPriorityGlobalResponseInterceptor.reset();
        LowPriorityGlobalResponseInterceptor.reset();

        // Reset deprecated interceptor
        TestInterceptorDeprecated.reset();
    }

    /**
     * Test whether resource interceptors are called.
     *
     * @throws Exception on any exception
     */
    @Test
    public void interceptionTest() throws Exception {
        // No sub resource
        Team team = doGetAndGetResponseObject(microServiceBaseUrl + "subResourceLocatorTest/SL/",
                false, Team.class, Collections.unmodifiableMap(Collections.emptyMap()));

        // Assert response
        assertEquals("Cricket", team.getTeamType());
        assertEquals("SL", team.getCountryId());

        // Assert interceptor calls
        // Request interceptors
        assertEquals(1, HighPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(1, MediumPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(1, LowPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(1, TestInterceptorDeprecated.getPreCallInterceptorCallsCount()); // Global interceptors

        assertEquals(2, TestRequestInterceptor.getFilterCalls()); // Resource level interceptor

        // Response interceptors
        assertEquals(1, HighPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(1, MediumPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(1, LowPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(1, TestInterceptorDeprecated.getPostCallInterceptorCallsCount()); // Global interceptors

        assertEquals(2, TestResponseInterceptor.getFilterCalls()); // Resource level interceptor
    }

    /**
     * Test whether sub-resource interceptors are called.
     *
     * @throws Exception on any exception
     */
    @Test
    public void subResourceInterceptionTest() throws Exception {
        // 1 sub resource
        String rawData = "countryName=SriLanka&type=Batsman";
        Player player = doPostAndGetResponseObject(microServiceBaseUrl + "subResourceLocatorTest/SL/" +
                        "interceptorTest/99/", rawData, false, Player.class,
                Collections.unmodifiableMap(Collections.emptyMap()));

        // Assert response
        assertEquals("player_1", player.getName());
        assertEquals(99, player.getPlayerId());
        assertEquals("SriLanka", player.getCountryName());
        assertEquals(30, player.getAge());
        assertEquals("Batsman", player.getType());

        // Assert interceptor calls
        // Request interceptors
        assertEquals(1, HighPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(1, MediumPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(1, LowPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(1, TestInterceptorDeprecated.getPreCallInterceptorCallsCount()); // Global interceptors

        assertEquals(3, TestRequestInterceptor.getFilterCalls()); // Resource level interceptor

        // Response interceptors
        assertEquals(1, HighPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(1, MediumPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(1, LowPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(1, TestInterceptorDeprecated.getPostCallInterceptorCallsCount()); // Global interceptors

        assertEquals(3, TestResponseInterceptor.getFilterCalls()); // Resource level interceptor

        String executionOrderString = "HighPriorityGlobalRequestInterceptor" +
                "MediumPriorityGlobalRequestInterceptor" +
                "LowPriorityGlobalRequestInterceptor" +
                "TestInterceptorDeprecated - [PRE CALL]" +
                "TestRequestInterceptor" +
                "TestRequestInterceptor" +
                "[HTTP RESOURCE METHOD]" +
                "TestRequestInterceptor" +
                "[HTTP SUB RESOURCE METHOD]" +
                "TestResponseInterceptor" +
                "TestResponseInterceptor" +
                "TestResponseInterceptor" +
                "TestInterceptorDeprecated - [POST CALL]" +
                "HighPriorityGlobalResponseInterceptor" +
                "MediumPriorityGlobalResponseInterceptor" +
                "LowPriorityGlobalResponseInterceptor";
        assertEquals(executionOrderString, PriorityDataHolder.getPriorityOrder());
    }

    /**
     * Test the order of the filters.
     * Order of the execution should be
     *

     * 1) Global request interceptors according to the priority order (way developer writes them)
     * HighPriorityGlobalRequestInterceptor -> MediumPriorityGlobalRequestInterceptor ->
     * LowPriorityGlobalRequestInterceptor -> TestInterceptorDeprecated - [PRE CALL]
     *

     * 2) Resource level request interceptors according to the priority order (way developer writes them)
     * HighPriorityRRequestInterceptor -> MediumPriorityRRequestInterceptor -> LowPriorityRRequestInterceptor
     *

     * 3) Sub-resource level request interceptors according to the priority order (way developer writes them)
     * HighPrioritySRRequestInterceptor -> MediumPrioritySRRequestInterceptor -> LowPrioritySRRequestInterceptor
     *

     * 4) HTTP method
     *

     * 5) Sub-resource level response interceptors according to the priority order (way developer writes them)
     * HighPrioritySRResponseInterceptor -> MediumPrioritySRResponseInterceptor -> LowPrioritySRResponseInterceptor
     *

     * 6) Resource level response interceptors according to the priority order (way developer writes them)
     * HighPriorityRResponseInterceptor -> MediumPriorityRResponseInterceptor -> LowPriorityRResponseInterceptor
     *

     * 7) Global response interceptors according to the priority order (way developer writes them)
     * TestInterceptorDeprecated - [POST CALL] -> HighPriorityGlobalResponseInterceptor ->
     * MediumPriorityGlobalResponseInterceptor -> LowPriorityGlobalResponseInterceptor
     *
     * @throws Exception on any exception
     */
    @Test
    public void priorityTest() throws Exception {
        String response = doGetAndGetResponseString("/test/priorityInterceptorTest/priorityTest", false,
                Collections.unmodifiableMap(Collections.emptyMap()));
        assertEquals("Priority interceptor test", response);
        String executionOrderString = "HighPriorityGlobalRequestInterceptor" +
                "MediumPriorityGlobalRequestInterceptor" +
                "LowPriorityGlobalRequestInterceptor" +
                "TestInterceptorDeprecated - [PRE CALL]" +
                "HighPriorityClassRequestInterceptor" +
                "MediumPriorityClassRequestInterceptor" +
                "LowPriorityClassRequestInterceptor" +
                "HighPriorityMethodRequestInterceptor" +
                "MediumPriorityMethodRequestInterceptor" +
                "LowPriorityMethodRequestInterceptor" +
                "[HTTP METHOD]" +
                "HighPriorityMethodResponseInterceptor" +
                "MediumPriorityMethodResponseInterceptor" +
                "LowPriorityMethodResponseInterceptor" +
                "HighPriorityClassResponseInterceptor" +
                "MediumPriorityClassResponseInterceptor" +
                "LowPriorityClassResponseInterceptor" +
                "TestInterceptorDeprecated - [POST CALL]" +
                "HighPriorityGlobalResponseInterceptor" +
                "MediumPriorityGlobalResponseInterceptor" +
                "LowPriorityGlobalResponseInterceptor";
        assertEquals(executionOrderString, PriorityDataHolder.getPriorityOrder());
    }

    /**
     * Test for interception break on exception.
     */
    @Test
    public void interceptorFlowBreakOnExceptionTest() {
        try {
            doGetAndGetResponseString(microServiceBaseUrl + "interceptorBreakOnExceptionTest", false,
                    Collections.unmodifiableMap(Collections.emptyMap()));
            Assert.fail(); // Fail test if exception is not thrown
        } catch (Exception e) {
            assertEquals(e.getClass().getName(), "java.io.IOException");
            assertEquals(e.getMessage(), "Server returned HTTP response code: 500 for URL: " +
                    "http://localhost:8096/test/interceptorTest/interceptorBreakOnExceptionTest");

            assertEquals(1, HighPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors
            assertEquals(1, MediumPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors
            assertEquals(1, LowPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors
            assertEquals(1, TestInterceptorDeprecated.getPreCallInterceptorCallsCount()); // Global interceptors
            assertEquals(1, TestRequestInterceptor.getFilterCalls()); // Resource and sub-resource interceptors
            assertEquals(1, TestExceptionBreakRequestInterceptor.getFilterCalls()); // Faulty interceptor

            // Response interceptors
            assertEquals(0, TestResponseInterceptor.getFilterCalls()); // Resource and sub-resource interceptors
            assertEquals(0, TestInterceptorDeprecated.getPostCallInterceptorCallsCount()); // Global interceptors
            assertEquals(0, HighPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors
            assertEquals(0, MediumPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors
            assertEquals(0, LowPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors
        }
    }

    /**
     * Test for interception break manually by user.
     */
    @Test
    public void requestInterceptorFlowBreakByUserTest() throws Exception {
        String response =
                doGetAndGetResponseString(microServiceBaseUrl + "requestInterceptorBreakByUserTest",
                        false, Collections.unmodifiableMap(Collections.emptyMap()));
        assertEquals(response, "");
        // Request interceptors
        assertEquals(1, HighPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(1, MediumPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(1, LowPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(1, TestInterceptorDeprecated.getPreCallInterceptorCallsCount()); // Global interceptors
        assertEquals(1, TestRequestInterceptor.getFilterCalls()); // Resource and sub-resource interceptors
        assertEquals(1, TestBreakRequestInterceptor.getFilterCalls()); // Resource and sub-resource interceptors

        // Response interceptors
        assertEquals(0, TestResponseInterceptor.getFilterCalls()); // Resource and sub-resource interceptors
        assertEquals(0, TestInterceptorDeprecated.getPostCallInterceptorCallsCount()); // Global interceptors
        assertEquals(0, HighPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(0, MediumPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(0, LowPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors

    }

    /**
     * Test for interception break manually by user.
     *
     * @throws Exception on any exception
     */
    @Test
    public void responseInterceptorFlowBreakByUserTest() throws Exception {
        String response =
                doGetAndGetResponseString(microServiceBaseUrl + "responseInterceptorBreakByUserTest",
                        false, Collections.unmodifiableMap(Collections.emptyMap()));
        assertEquals(response, "");

        // Request interceptors
        assertEquals(1, HighPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(1, MediumPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(1, LowPriorityGlobalRequestInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(1, TestInterceptorDeprecated.getPreCallInterceptorCallsCount()); // Global interceptors
        assertEquals(2, TestRequestInterceptor.getFilterCalls()); // Resource and sub-resource interceptors

        // Response interceptors
        assertEquals(1, TestBreakResponseInterceptor.getFilterCalls()); // Break interception flow interceptor
        assertEquals(0, TestResponseInterceptor.getFilterCalls()); // Resource and sub-resource interceptors
        assertEquals(0, TestInterceptorDeprecated.getPostCallInterceptorCallsCount()); // Global interceptors
        assertEquals(0, HighPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(0, MediumPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors
        assertEquals(0, LowPriorityGlobalResponseInterceptor.getFilterCalls()); // Global interceptors
    }
}


text:
<!--
  Licensed to ObjectStyle LLC under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ObjectStyle LLC licenses
  this file to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

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

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

# UPGRADE INSTRUCTIONS

## 1.1

* [bootique #266](https://github.com/bootique/bootique/issues/266): To improve Java 11 compatibility, Bootique core
was upgraded to the latest Guice v 4.2.2. This is more of an FYI. No action is needed from the users, unless you
are manually managing Guice versions in your app.

* [bootique-agrest #37](https://github.com/bootique/bootique-agrest/issues/37): While `bootique-agrest` didn't change,
the underlying Agrest framework introduced a few breaking changes between 3.1 and 3.2, that hopefully affect only a small subset of users:

  * Response with overlapping relationship / attribute "includes" is `include` order dependent [#406](https://github.com/agrestio/agrest/issues/406)
  * @QueryParameter types changed to Strings and Integers [#408](https://github.com/agrestio/agrest/issues/408) If you are not directly injecting `Include`, `Exclude` and friends (injecting `UriInfo` instead), are you are not affected.

See [Agrest upgrade instructions](https://github.com/agrestio/agrest/blob/master/UPGRADE-NOTES.md#upgrading-to-32) for more details.

* [bootique-linkmove #37](https://github.com/bootique/bootique-linkmove/issues/37): LinkMove library was upgraded to
v 2.7. While `bootique-linkmove` didn't change, the underlying LinkMove framework introduced a few breaking changes
between 2.6 and 2.7. Namely switching of internal ETL data representation to DFLib DataFrame. If your get any
compilation errors as a result, see [LinkMove upgrade instructions](https://github.com/nhl/link-move/blob/master/UPGRADE-NOTES.md)
for details of the 2.7 changes.

## 1.0

Fully compatible with 1.0.RC1

## 1.0.RC1

* [bootique-agrest #35](https://github.com/bootique/bootique-agrest/issues/35): Group of `bootique-linkrest` artifact
changed from `io.bootique.linkrest` to `io.bootique.agrest`.

* [bootique #252](https://github.com/bootique/bootique/issues/252): Method `defaultValue()` in OptionMetadata builder
changed to `valueOptionalWithDefault()`

* [bootique #251](https://github.com/bootique/bootique/issues/251): Method `addConfigOnOption(String optionName, String configResourceId)`
in `BQCoreModuleExtender` renamed to `mapConfigResource`

* [bootique #249](https://github.com/bootique/bootique/issues/249): Confusing methods
`addOption(String configPath, String defaultValue, String name)` and `addOption(String configPath, String name)`
in `BQCoreModuleExtender` are replaced with new one `mapConfigPath(String optionName, String configPath)`
 that has much clearer signature. **Note** that option that will be mapped to config path should be added separately.

* [bootique #188](https://github.com/bootique/bootique/issues/188): Guice was upgraded from 4.0 to
4.2.0 for better support of the latest versions of Java. This changes the version of Guava lib to
`23.6-android` and that Guava brings with it a whole set of other libraries (see the screenshot
[here](https://groups.google.com/forum/#!topic/bootique-user/elLjQXaK-40). If your code depends
on Guava elsewhere, be aware of this change. Also (and this is very unfortunate) this upgrade
increased the dependency footprint by ~500K.

* [bootique #214](https://github.com/bootique/bootique/issues/214): All APIs previously deprecated are
removed from Bootique core. Please recompile your code and fix any failures (refer to 0.25 JavaDocs for
suggested API replacements).

The most notable change though, that you will not notice just by recompiling, is that Bootique now
completely ignores `BQ_` environment variables that used to set config properties. Please inspect
your app launch environment (be it IDE or server/Docker/cloud) to see if you still rely on such variables.
Switch to explicitly declared variables instead:

```java
// FWIW, you can use your old BQ_ var name here if you feel like it.
// Just need to bind it explicitly.
BQCoreModule.extend(bidner).declareVar("a.b.c", "MY_VAR");
```

* [bootique-jetty #75](https://github.com/bootique/bootique-jetty/issues/75): As a part of deprecated
API removal `bootique-jetty-test` module was removed. It is enough to use
`bootique-test` as described in the [0.25 blog](https://blog.bootique.io/the-state-of-bootique-early-2018-part-1-ed6806d9c99a)
("Test API Improvements" section).

* [bootique-undertow #13](https://github.com/bootique/bootique-undertow/issues/13): As a part of deprecated
API removal `bootique-undertow-test` module was removed. It is enough to use
`bootique-test` as described in the [0.25 blog](https://blog.bootique.io/the-state-of-bootique-early-2018-part-1-ed6806d9c99a)
("Test API Improvements" section).

* [bootique-jetty #77](https://github.com/bootique/bootique-jetty/issues/77): Jetty health checked thresholds structure has
changed as shown in the following diff:

```yaml
jetty:
    health:
-    queuedRequestsThreshold: "2 3"
-    poolUtilizationThreshold: "0.6 0.9"
+    queuedRequestsThresholds:
+      warning: 2
+      critical: 3
+    poolUtilizationThresholds:
+      warning: 60%
+      critical: 90%
```
* [bootique-jdbc #81](https://github.com/bootique/bootique-jdbc/issues/81): Hikari health check threashold structure has changed
as shown in the following diff. Now you can specify warning and critical ranges and use human-readable durations:

```yaml
jdbc:
  mydb:
    health:
-      connectivityCheckTimeout: 250
-      expected99thPercentile: 10
+      connectivity:
+        critical: 250ms
+      connection99Percent:
+        warning: 10ms
+        critical: 500ms
```

* [bootique-jdbc #82](https://github.com/bootique/bootique-jdbc/issues/82): `bootique-jdbc-instrumented` module was removed.
There are healthchecks specific to Tomcat and Hikari pools, so there's no need to have a generic set of healthchecks that interferes
with them. You will need to remove references to `bootique-jdbc-instrumented` from your build scripts and replace them with `bootique-jdbc-tomcat-instrumented` (that actually contains healtchecks ported from the removed module) or `bootique-jdbc-hikaricp-instrumented` (that has its own set of health checks).

* [bootique-job #64](https://github.com/bootique/bootique-job/pull/64): If you used Zookeeper for job locking, configuration is done differently
now. You will need to remove `scheduler.clusteredLocks: true` from YAML, and instead add a dependency on `io.bootique.job:bootique-job-zookeeper`
(or the new `io.bootique.job:bootique-job-consul`). Either will enable lock clustering, but with its own mechanism.

* [bootique-job #66](https://github.com/bootique/bootique-job/pull/66): Trigger configurations switched from numeric milliseconds to
"durations". While the configuration is backwards-compatible, we'd encourage you to review it and replace config keys "fixedDelayMs",
"fixedRateMs", "initialDelayMs" with "fixedDelay", "fixedRate", "initialDelay" respectively. While you are at it, you may switch to
more user-friendly forms, such as "3s" or "5min".

* [bootique-kafka #19](https://github.com/bootique/bootique-kafka/issues/19): `bootique-kafka-client` repository was renamed to `bootique-kafka`.
If you are using `bootique-kafka-client`, you will need change the Maven "groupId" to `io.bootique.kafka` from `io.bootique.kafka.client`.

* [bootique-kafka #21](https://github.com/bootique/bootique-kafka/issues/21): "kafkaclient.producer.lingerMs" property got renamed to
"kafkaclient.producer.linger" and was changed to a Duration type. Please change all references to `kafkaclient.producer.lingerMs`
in your config to be `kafkaclient.producer.linger`. Note that once you do it, you can use any supported duration format e.g. "1s".
Also note that the default value for this property was changed from 1 to 0 to match the Kafka default.

* [bootique-kafka #23](https://github.com/bootique/bootique-kafka/issues/23): Per this task, a new user-friendly Consumer API was
created. Breaking changes:

  * Consumers can no longer be obtained via `KafkaClientFactory`. Instead inject `KafkaConsumerFactory` and use its Consumer builder methods.
  * Producers can no longer be obtained via `KafkaClientFactory`. Instead inject `KafkaproducerFactory` and use its Producer builder methods.
  * `kafkaclient.consumer.autoCommitIntervalMs` config is renamed to
`kafkaclient.consumer.autoCommitInterval` and is now a duration (so you can use readable values like "1ms"). Same goes
for `kafkaclient.consumer.sessionTimeoutMs` that got renamed to `kafkaclient.consumer.sessionTimeout`.

* [bootique-metrics #30](https://github.com/bootique/bootique-metrics/issues/30): There was a massive renaming of module metrics to
follow a single naming convention. Follow the link to [bootique-metrics #30](https://github.com/bootique/bootique-metrics/issues/30)
to see the old vs new names across all affected modules.

* [bootique-metrics #31](https://github.com/bootique/bootique-metrics/issues/31): Similarly to metrics, health checks got similarly renamed to
follow the same naming convention. Follow the link to [bootique-metrics #31](https://github.com/bootique/bootique-metrics/issues/31)
to see the old vs new names across all affected modules.

* [bootique-agrest #34](https://github.com/bootique/bootique-agrest/issues/34) : LinkRest was changed to Agrest
and bootique-agrest. Bootique-linkrest now deprecated. Please use bootique-agrest dependency.

## 0.25

* [bootique-jdbc #48](https://github.com/bootique/bootique-jdbc/issues/48): This affects all users of `bootique-jdbc`,
including indirect users, such as those relying on `bootique-cayenne`, `bootique-linkrest`, `bootique-linkmove`,
`bootique-jooq`, `bootique-liquibase`, etc. Due to `bootique-jdbc` module becoming "abstract", if you have a JDBC app, on startup you will
see an error like this:

```
No concrete 'bootique-jdbc' implementations found. You will need to add one
(such as 'bootique-jdbc-tomcat', etc.) as an application dependency.
```
To fix the problem, you will need to do exactly as suggested, i.e. add the following dependency to your `pom.xml`:
```xml
<dependency>
    <groupId>io.bootique.jdbc</groupId>
    <artifactId>bootique-jdbc-tomcat</artifactId>
    <scope>compile</scope>
</dependency>
```
The original `bootique-jdbc` is now a transitive dependency of the new `bootique-jdbc-tomcat`, so you may remove
explicit `bootique-jdbc` import (or leave it, as no harm is being done by keeping it around). If you are using
`bootique-jdbc-instrumented` (i.e. JDBC with metrics), import a different dependency:

```xml
<dependency>
    <groupId>io.bootique.jdbc</groupId>
    <artifactId>bootique-jdbc-tomcat-instrumented</artifactId>
    <scope>compile</scope>
</dependency>
```

* [bootique-jdbc #66](https://github.com/bootique/bootique-jdbc/issues/66): DataSource connection health checks were
renamed to uniquely identify their origin and purpose. E.g. a health check that may have previously been called
`mydb` after the DataSource name, will now be called `bq.jdbc.mydb.canConnect`. If any of your code or the monitoring
system depended on the certain name format, you will need to update it accordingly.

* [bootique-metrics #20](https://github.com/bootique/bootique-metrics/issues/20): Health check module was separated
from the metric module. If you used healthcheck API in your code and are getting compilation errors now, you will need
to add an extra dependency:

```xml
<dependency>
	<groupId>io.bootique.metrics</groupId>
	<artifactId>bootique-metrics-healthchecks</artifactId>
	<scope>compile</scope>
</dependency>
```
Additionally if you called `MetricsModule.extend(binder)`, replace it with `HealthCheckModule.extend(binder)`.

* [bootique-jetty #69](https://github.com/bootique/bootique-jetty/issues/69): There was a slight change in health check
servlet output format. In case of errors the format now includes specific status (CRITICAL, WARNING, UNKNOWN). E.g.:

```yaml
// old format
! h3: ERROR - I am not healthy

// new format
! h3: WARNING - I am not healthy
! h3: CRITICAL - I am not healthy
```

* [bootique-jetty #70](https://github.com/bootique/bootique-jetty/issues/70): With introduction of explicit per-connector
`acceptorThreads` and `connectorThreads` configuration properties, the defaults used by the server for acceptors and
selectors have changed from 0.5 acceptor and 1 selector thread(s) per CPU core to  0.125 acceptor and 0.5 selector
thread(s) per CPU core. In the unlikely event that you need the old values back, you can configure them using the
new properties. E.g.:

```yaml
jetty:
  connectors:
    - acceptorThreads: 4
      selectorThreads: 8
```

* [bootique-jetty #71](https://github.com/bootique/bootique-jetty/issues/71): We decided to clarify the meaning of the
Jetty thread pool metrics. The old "utilization" metric was not very useful as it compared used threads against the
current thread pool size. But since the pool can grow/shrink at any moment, it didn't tell anything about the state of the
app. So its meaning is now replaced to be the same as the old "utilization-max" (i.e. a ratio of used threads to the
max possible threads in the pool). "utilization-max" was deprecated.

If you used "utilization" metric for anything in your monitoring system, etc., make sure to adjust for the new
meaning.

* [bootique-jersey-client #29](https://github.com/bootique/bootique-jersey-client/issues/29): `followRedirects` default value
has changed from "false" to "true". If you implicitly relied on `jerseyclient.followRedirects` default to be "false", you will need to reconfigure your app to set it to false explicitly:
```yaml
jerseyclient:
   followRedirects: false
```

## 0.24

* [bootique #180](https://github.com/bootique/bootique/issues/180): The ability to explicitly declare a BQ_* var was removed.
In other words this API is not longer available:

  ```java
  // this used to declare a variable BQ_PROP_XYZ
  BQCoreModule.extend(binder).declareVar("prop.xyz")
  ```
  You have two choices for upgrading your code: either (1) simply remove this line of code (`BQ_PROP_XYZ` will keep working,
  just won't show in help), or (2 - better) assign this variable an app-specific name. E.g.
  `BQCoreModule.extend(binder).declareVar("prop.xyz", "MY_VAR")`.

* [bootique-jdbc #39](https://github.com/bootique/bootique-jdbc/issues/39): If you had unit tests that are using `Table.insertFromCsv(..)` and the `.csv` files contain timestamps, replace the space between date and time portions with "T" symbol. The new format is proper ISO-8601.

## 0.23

* [bootique #141](https://github.com/bootique/bootique/issues/141): If you've ever implemented your own "main" method
instead of relying on the one from `io.bootique.Bootique`, you may want to replace the call to the deprecated `Bootique.run()`
with `Bootique.exec().exit()`. Notice how the new API allows to insert custom code after Bootique finish, but before the
app exit.

* [bootique #142](https://github.com/bootique/bootique/issues/142): This issue introduces API-breaking changes to the
integration testing API. Instead of `BQTestRuntime` and `BQDaemonTestRuntime`, test factories now produce simply
`BQRuntime`, that helps to focus on the object being tested instead of test wrappers. Upgrade instructions:

  1. `BQTestRuntime` and `BQDaemonTestRuntime` are gone, so replace references to them with just `BQRuntime`.
  2. A common call to `testRuntime.getRuntime().getInstance(..)` should now be shortened to `testRuntime.getInstance(..)`.
  3. If you need to get an outcome of a background task execution, instead of `daemonTestRuntime.getOutcome()` you need
  to call `daemonTestFactory.getOutcome(runtime)` ("daemonTestFactory" is a `BQDaemonTestFactory` or subclasses like
   `JettyTestFactory`, that are the `@Rule`'s in your test).
  4. Use factory API (the same approach as in the previous point) if you need to manually start/stop the daemon runtime:
  `daemonTestFactory.start(runtime)`, `daemonTestFactory.stop(runtime)`.
  5. If you need to capture STDOUT or STDERR of a specific BQRuntime run, use the new `TestIO` class that can capture
  this data. It additionally allows to suppress trace logging, making your test console much less verbose than before.
  E.g.:

	```java
	TestIO io = TestIO.noTrace();
	testFactory.app("-x")
		.bootLogger(io.getBootLogger())
		.createRuntime()
		.run();

	assertEquals("--out--", io.getStdout());
	assertEquals("--err--", io.getStderr());
	```
	Other modules that have been affected by this change are
	[bootique-jetty-test](https://github.com/bootique/bootique-jetty/issues/59),
	[bootique-undertow-test](https://github.com/bootique/bootique-undertow/issues/3),
	[bootique-jdbc-test](https://github.com/bootique/bootique-jdbc/issues/32),
	[bootique-cayenne-test](https://github.com/bootique/bootique-cayenne/issues/39).

* [bootique-liquibase #16](https://github.com/bootique/bootique-liquibase/issues/16): Names of Liquibase module
commands have been changed by adding prefix "lb" to distinguish them from commands of others modules.

    Old options:

      --changelog-sync
           Mark all changes as executed in the database.

      --changelog-sync-sql
           Writes SQL to mark all changes as executed in the database to STDOUT.

      --clear-check-sums
           Clears all checksums in the current changelog, so they will be
           recalculated next update.

      -u, --update
           Updates DB with available migrations

      -v, --validate
           Checks the changelog for errors.

    New options:

      --lb-changelog-sync
           Mark all changes as executed in the database.

      --lb-changelog-sync-sql
           Writes SQL to mark all changes as executed in the database to STDOUT.

      --lb-clear-check-sums
           Clears all checksums in the current changelog, so they will be
           recalculated next update.

      -u, --lb-update
           Updates DB with available migrations

      -v, --lb-validate
           Checks the changelog for errors.

Short names has been preserved for partial backwards compatibility.

## 0.22

* [bootique-cayenne #36](https://github.com/bootique/bootique-cayenne/issues/36): If you used `bootique-cayenne-jcache`,
note that a big chunk of its functionality is now handled by Cayenne itself. From the upgrade perspective only one thing is affected:
if you ever used custom `InvalidationHandler`, you will need to switch that to `org.apache.cayenne.lifecycle.cache.InvalidationHandler`
that has a slightly different method signature (due to the need to keep Java 7 compatibility in Cayenne 4.0).

## 0.21

* [bootique #105](https://github.com/bootique/bootique/issues/105): The new default style for multi-word command classes
that are spelled in camel-case will result in the name parts separated with dash, while previously
we'd use no separators. E.g. `MySpecialCommand.java` will result in command name being "--myspecial" in 0.20,
and "--my-special" in 0.21. This affects you if you've written custom command classes with multi-word names.
You can manually override public command names in metadata to return to the old style (see
[CommandWithMetadata](https://github.com/bootique/bootique/blob/master/bootique/src/main/java/io/bootique/command/CommandWithMetadata.java)) or embrace the new naming scheme.

* [bootique #112](https://github.com/bootique/bootique/issues/112): The implementation of this feature has a few
(intentional) side-effects: (1) joptsimple library was upgraded to 5.0.6, (2) CLI option abbreviations are no longer
supported. You may have not known this, but before 0.21, you could use partial option names (e.g. "--he" for help). Not
anymore. Now either a short option or a long option with full name must be used (i.e. "-h" or "--help" in case of the
help command).

* [bootique #113](https://github.com/bootique/bootique/issues/113): Classes in ```io.bootique.application``` package
were moved under ```io.bootique.meta.application``` in an effort to centralize Bootique metadata facilities. If you
referenced them in your code, you will need to fix the imports and recompile. This will primarily affect custom Commands.

* [bootique-jdbc #6](https://github.com/bootique/bootique-jdbc/issues/6): bootique-jdbc uses Tomcat DataSource that has
 a few dozens of config properties. As we migrated JDBC configuration from a map to a
 [specific class](https://github.com/bootique/bootique-jdbc/blob/master/bootique-jdbc/src/main/java/io/bootique/jdbc/TomcatDataSourceFactory.java),
 we dropped support for certain noop properties there were supported but ignored in the previous configuration. If you
 get configuration errors, review your configs and remove those properties. Additionally the following properties
 are treated differently than before:

  - ```connectionProperties``` property is not supported (as it is unclear why it may be useful)
  - ```jmxEnabled``` default is changed from true to false.
  - ```object_name``` is renamed to ```jmxObjectName```.

* [bootique-liquibase #4](https://github.com/bootique/bootique-liquibase/issues/4):  'liquibase.changeLog' YAML config
property is deprecated, but still supported. The new alternative is 'changeLogs' collection. When migrating to
'changeLogs', ensure that you rewrite the paths in Bootique YAML files as well as in Liquibase XML/YAML change logs to
follow Bootique ResourceFactory approach. Specifically, if the resource is expected to be on classpath, it requires
"classpath:" prefix. Otherwise it will be treated as a file path.

* [bootique-logback #26](https://github.com/bootique/bootique-logback/issues/26):  'log.level' and
'log.loggers.<xyz>.level' must be specified in lowercase. I.e. ```level: debug``` instead of ```level: DEBUG```.
Uppercase values will now cause an exception.

* [bootique-job #15](https://github.com/bootique/bootique-job/issues/15):  'scheduler.jobPropertiesPrefix' property is no longer supported in configuration and needs to be removed from the config files, etc. Parameters for individual jobs should now be specified under 'params' key (previously they were specified under the job's name).
```yaml
# prior to 0.21
jobs:
  myjob:
    param1: value1

# starting with 0.21
jobs:
  myjob:
    params:
        param1: value1
```

## 0.20

* [bootique #92](https://github.com/bootique/bootique/issues/92): We created a new application metadata package
at ```io.bootique.application```. The existing metadata objects where moved to this package from different places.
Specifically ```io.bootique.command.CommandMetadata``` was moved and ```io.bootique.cli.CliOption``` was moved and
renamed to ```OptionMetadata```.  **This is a breaking change.**  You will need to use module versions aligned with
0.20 Bootique BOM and fix any imports in your own code (especially in custom Commands).

* [bootique #97](https://github.com/bootique/bootique/issues/97): We simplifed integration test API. It now looks pretty much the same as a regular ```main(String[])``` method. There's no longer a need to use "configurator" lambda to configure test runtime. Instead you'd call Bootique-like methods on the test factory. When upgrading your tests you will need to change calls on ```BQTestFactory``` and ```BQDaemonTestFactory``` from ```newRuntime()``` to ```app(args)```. Terminating builder methods no longer take args (it is passed in the "app" method at the start of the chain). Pay attention to deprecating warnings and use your IDE for available APIs of the test factories.

* [bootique-jetty #52](https://github.com/bootique/bootique-jetty/issues/52): ```JettyTestFactory``` received the same API upgrades as ```BQTestFactory``` and ```BQDaemonTestFactory``` as described above. The upgrade instructions are similar.

## 0.19

The biggest change in 0.19 is combining modules under ```com.nhl.bootique``` and ```io.bootique``` into a single
namespace - ```io.bootique```. To upgrade, you will need to change module group names in your POM, Java package
names in imports, and the name of service provider files in your modules. Details are provided below:

* If you used Bootique-provided parent pom, in your ```pom.xml``` change the parent declaration:

```xml
<parent>
	<groupId>io.bootique.parent</groupId>
	<artifactId>bootique-parent</artifactId>
	<version>0.12</version>
</parent>
```
* Change all group names of Maven artifacts in your ```pom.xml``` from ```com.nhl.bootique.*``` to ```io.bootique.*```.
  Module names are preserved.

* Use ```io.bootique``` BOM, remove ```com.nhl.bootique``` BOM:

```xml
<dependency>
	<groupId>io.bootique.bom</groupId>
	<artifactId>bootique-bom</artifactId>
	<version>0.19</version>
	<type>pom</type>
	<scope>import</scope>
</dependency>
```

Note that there was a brief period of time (0.18) when required both BOMs to be imported. Not anymore. ```io.bootique```
one is sufficient now.

* Look for Java compilation errors in your IDE, and change ```com.nhl.bootique.*``` import statements to ```io.bootique.*```.

* If you've written any auto-loadable modules, you will have ```META-INF/services/com.nhl.bootique.BQModuleProvider```
  files sitting somewhere in your source.Rename these files to ```META-INF/services/io.bootique.BQModuleProvider```.

* Similarly if you've written any polymorphic config extensions, your sources will have ```META-INF/services/com.nhl.bootique.config.PolymorphicConfiguration```
  files somewhere. Rename these files to ```META-INF/services/io.bootique.config.PolymorphicConfiguration```.

## 0.18

* [bootique-cayenne #12](https://github.com/nhl/bootique-cayenne/issues/12) : ```CayenneModule.builder()``` is removed.
  Instead of using the builder, use YAML (or another form of) configuration. If you need a project-less Cayenne stack,
  simply do not reference any Cayenne projects (and make sure "cayenne-project.xml" is not on classpath).

* [bootique-curator #4](https://github.com/nhl/bootique-curator/issues/4) : ```bootique-zookeeper``` was renamed to
  ```bootique-curator```, so the dependency import and Java package names need to be changed accordingly.

## 0.17

* [bootique #62](https://github.com/nhl/bootique/issues/62) : To fully take advantage of the default main class, make
  sure you upgrade ```com.nhl.bootique.parent:bootique-parent``` to version 0.11.

## 0.12.2

* [bootique-cayenne #9](https://github.com/nhl/bootique-cayenne/issues/9) : CayenneModule ```noConfig``` and
  ```configName``` methods are moved into a builder, and constructor is made private. Now to set cayenne-...xml via
  API use something like this:

```java
CayenneModule.builder()./* configure module */.build();
```
* [bootique-jdbc #4](https://github.com/nhl/bootique-jdbc/issues/4) : Instrumentation is removed from
  ```bootique-jdbc``` and into a separate ```bootique-jdbc-instrumented``` module.If you relied on the
  DataSource metrics, change your import to the new Module.

## 0.12:

* Command API has been redone. If you have modules or apps that implement Commands,
  you will need to update those. Sample commands can be found in our modules, e.g.
  [bootique-jobs](https://github.com/nhl/bootique-job/tree/master/src/main/java/com/nhl/bootique/job/command).

* @Args annotation was moved to "com.nhl.bootique.annotation" package from "com.nhl.bootique.jopt".
  Update your imports.

* Now only one command can match command line options. THis was true before, but wasn't enforced.
  So you may see certain command line configs failing with errors, where they appeared to work before
  by pure chance.

* BQBinder is deprecated. From within your Module use static methods on BQCoreModule to contribute
  Module-specific commands, properties, CLI options.


text:
<?php

$mess=array(
"Audio Player" => "Lecteur audio",
"Uses HTML5 or Flash to play a sound" => "Utilise HTML5 ou Flash pour lire un fichier audio",
"Sound Player" => "Lecteur audio",
);