---
title: Interactions and contrasts
layout: page
---

```{r options, echo=FALSE}
library(knitr)
opts_chunk$set(fig.path=paste0("figure/", sub("(.*).Rmd","\\1",basename(knitr:::knit_concord$get('infile'))), "-"))
```

## Interactions and Contrasts

As a running example to learn about more complex linear models, we will be using a dataset which compares the different frictional coefficients on the different legs of a spider. Specifically, we will be determining whether more friction comes from a pushing or pulling motion of the leg. The original paper from which the data was provided is:

Jonas O. Wolff  & Stanislav N. Gorb, [Radial arrangement of Janus-like setae permits friction control in spiders](http://dx.doi.org/10.1038/srep01101), Scientific Reports, 22 January 2013.

The abstract of the paper says,

> The hunting spider Cupiennius salei (Arachnida, Ctenidae) possesses hairy attachment pads (claw tufts) at its distal legs, consisting of directional branched setae... Friction of claw tufts on smooth glass was measured to reveal the functional effect of seta arrangement within the pad.

[Figure 1](http://www.nature.com/articles/srep01101/figures/1)
includes some pretty cool electron microscope images of the tufts. We are interested in the comparisons in
[Figure 4](http://www.nature.com/articles/srep01101/figures/4),
where the pulling and pushing motions are compared for different leg pairs (for a diagram of pushing and pulling see the top of
[Figure 3](http://www.nature.com/articles/srep01101/figures/3)).

We include the data in our dagdata package and can download it from [here](https://raw.githubusercontent.com/genomicsclass/dagdata/master/inst/extdata/spider_wolff_gorb_2013.csv).

```{r,echo=FALSE}
url <- "https://raw.githubusercontent.com/genomicsclass/dagdata/master/inst/extdata/spider_wolff_gorb_2013.csv"
filename <- "spider_wolff_gorb_2013.csv"
library(downloader)
if (!file.exists(filename)) download(url, filename)
```

```{r}
spider <- read.csv("spider_wolff_gorb_2013.csv", skip=1)
```

#### Initial visual inspection of the data

Each measurement comes from one of our legs while it is either pushing or pulling. So we have two variables:

```{r}
table(spider$leg,spider$type)
```

We can make a boxplot summarizing the measurements for each of the eight pairs. This is similar to Figure 4 of the original paper:

```{r spide_data, fig.cap="Comparison of friction coefficients of spiders' different leg pairs. The friction coefficient is calculated as the ratio of two forces (see paper Methods) so it is unitless."}
boxplot(spider$friction ~ spider$type * spider$leg,
        col=c("grey90","grey40"), las=2,
        main="Comparison of friction coefficients of different leg pairs")
```

What we can immediately see are two trends:

* The pulling motion has higher friction than the pushing motion.
* The leg pairs to the back of the spider (L4 being the last) have higher pulling friction.

Another thing to notice is that the groups have different spread around their average, what we call *within-group variance*. This is somewhat of a problem for the kinds of linear models we will explore below, since we will be assuming that around the population average values, the errors $\varepsilon_i$ are distributed identically, meaning the same variance within each group. The consequence of ignoring the different variances for the different groups is that comparisons between those groups with small variances will be overly "conservative" (because the overall estimate of variance is larger than an estimate for just these groups), and comparisons between those groups with large variances will be overly confident. If the spread is related to the range of friction, such that groups with large friction values also have larger spread, a possibility is to transform the data with a function such as the `log` or `sqrt`. This looks like it could be useful here, since three of the four push groups (L1, L2, L3) have the smallest friction values and also the smallest spread.

Some alternative tests for comparing groups without transforming the values first include: t-tests without the equal variance assumption using a "Welch" or "Satterthwaite approximation", or the Wilcoxon rank sum test mentioned previously. However here, for simplicity of illustration, we will fit a model that assumes equal variance and shows the different kinds of linear model designs using this dataset, setting aside the issue of different within-group variances.

#### A linear model with one variable

To remind ourselves how the simple two-group linear model looks, we will subset the data to include only the L1 leg pair, and run `lm`:

```{r}
spider.sub <- spider[spider$leg == "L1",]
fit <- lm(friction ~ type, data=spider.sub)
summary(fit)
(coefs <- coef(fit))
```

These two estimated coefficients are the mean of the pull observations (the first estimated coefficient) and the difference between the means of the two groups (the second coefficient). We can show this with R code:

```{r}
s <- split(spider.sub$friction, spider.sub$type)
mean(s[["pull"]])
mean(s[["push"]]) - mean(s[["pull"]])
```

We can form the design matrix, which was used inside `lm`:

```{r}
X <- model.matrix(~ type, data=spider.sub)
colnames(X)
head(X)
tail(X)
```

Now we'll make a plot of the $\mathbf{X}$ matrix by putting a black block for the 1's and a white block for the 0's. This plot will be more interesting for the linear models later on in this script. Along the y-axis is the sample number (the row number of the `data`) and along the x-axis is the column of the design matrix $\mathbf{X}$. If you have installed the *rafalib* library, you can make this plot with the `imagemat` function:

```{r model_matrix_image, fig.cap="Model matrix for linear model with one variable."}
library(rafalib)
imagemat(X, main="Model matrix for linear model with one variable")
```

#### Examining the estimated coefficients

Now we show the coefficient estimates from the linear model in a diagram with arrows (code not shown).

```{r spider_main_coef, fig.cap="Diagram of the estimated coefficients in the linear model. The green arrow indicates the Intercept term, which goes from zero to the mean of the reference group (here the 'pull' samples). The orange arrow indicates the difference between the push group and the pull group, which is negative in this example. The circles show the individual samples, jittered horizontally to avoid overplotting.",echo=FALSE}
set.seed(1) #same jitter in stripchart
stripchart(split(spider.sub$friction, spider.sub$type),
           vertical=TRUE, pch=1, method="jitter", las=2, xlim=c(0,3), ylim=c(0,2))
a <- -0.25
lgth <- .1
library(RColorBrewer)
cols <- brewer.pal(3,"Dark2")
abline(h=0)
arrows(1+a,0,1+a,coefs[1],lwd=3,col=cols[1],length=lgth)
abline(h=coefs[1],col=cols[1])
arrows(2+a,coefs[1],2+a,coefs[1]+coefs[2],lwd=3,col=cols[2],length=lgth)
abline(h=coefs[1]+coefs[2],col=cols[2])
legend("right",names(coefs),fill=cols,cex=.75,bg="white")
```

#### A linear model with two variables

Now we'll continue and examine the full dataset, including the observations from all leg pairs. In order to model both the leg pair differences (L1, L2, L3, L4) and the push vs. pull difference, we need to include both terms in the R formula. Let's see what kind of design matrix will be formed with two variables in the formula:

```{r model_matrix_image2, fig.cap="Image of the model matrix for a formula with type + leg"}
X <- model.matrix(~ type + leg, data=spider)
colnames(X)
head(X)
imagemat(X, main="Model matrix for linear model with two factors")
```

The first column is the intercept, and so it has 1's for all samples. The second column has 1's for the push samples, and we can see that there are four groups of them. Finally, the third, fourth and fifth columns have 1's for the L2, L3 and L4 samples. The L1 samples do not have a column, because *L1* is the reference level for `leg`. Similarly, there is no *pull* column, because *pull* is the reference level for the `type` variable.

To estimate coefficients for this model, we use `lm` with the formula `~ type + leg`. We'll save the linear model to `fitTL` standing for a *fit* with *Type* and *Leg*.

```{r}
fitTL <- lm(friction ~ type + leg, data=spider)
summary(fitTL)
(coefs <- coef(fitTL))
```

R uses the name `coefficient` to denote the component containing the least squares **estimates**. It is important to remember that the coefficients are parameters that we do not observe, but only estimate.

#### Mathematical representation

The model we are fitting above can be written as

$$
Y_i = \beta_0 + \beta_1 x_{i,1} + \beta_2 x_{i,2} + \beta_3 x_{i,3} + \beta_4 x_{i,4} + \varepsilon_i, i=1,\dots,N
$$

with the $x$ all indicator variables denoting push or pull and which leg. For example, a push on leg 3 will have $x_{i,1}$ and $x_{i,3}$ equal to 1 and the rest would be 0. Throughout this section we will refer to the $\beta$ s with the effects they represent. For example we call $\beta_0$ the intercept, $\beta_1$ the pull effect, $\beta_2$ the L2 effect, etc. We do not observe the coefficients, e.g.  $\beta_1$, directly, but estimate them with, e.g. $\hat{\beta}_4$.

We can now form the matrix $\mathbf{X}$ depicted above and obtain the least square estimates with:

$$ \hat{\boldsymbol{\beta}} = (\mathbf{X}^\top \mathbf{X})^{-1} \mathbf{X}^\top \mathbf{Y} $$

```{r}
Y <- spider$friction
X <- model.matrix(~ type + leg, data=spider)
beta.hat <- solve(t(X) %*% X) %*% t(X) %*% Y
t(beta.hat)
coefs
```

We can see that these values agree with the output of `lm`.

#### Examining the estimated coefficients

We can make the same plot as before, with arrows for each of the estimated coefficients in the model (code not shown).

```{r spider_interactions, fig.cap="Diagram of the estimated coefficients in the linear model. As before, the teal-green arrow represents the Intercept, which fits the mean of the reference group (here, the pull samples for leg L1). The purple, pink, and yellow-green arrows represent differences between the three other leg groups and L1. The orange arrow represents the difference between the push and pull samples for all groups.",echo=FALSE}
spider$group <- factor(paste0(spider$leg, spider$type))
stripchart(split(spider$friction, spider$group),
           vertical=TRUE, pch=1, method="jitter", las=2, xlim=c(0,11), ylim=c(0,2))
cols <- brewer.pal(5,"Dark2")
abline(h=0)
arrows(1+a,0,1+a,coefs[1],lwd=3,col=cols[1],length=lgth)
abline(h=coefs[1],col=cols[1])
arrows(3+a,coefs[1],3+a,coefs[1]+coefs[3],lwd=3,col=cols[3],length=lgth)
arrows(5+a,coefs[1],5+a,coefs[1]+coefs[4],lwd=3,col=cols[4],length=lgth)
arrows(7+a,coefs[1],7+a,coefs[1]+coefs[5],lwd=3,col=cols[5],length=lgth)
arrows(2+a,coefs[1],2+a,coefs[1]+coefs[2],lwd=3,col=cols[2],length=lgth)
segments(3+a,coefs[1]+coefs[3],4+a,coefs[1]+coefs[3],lwd=3,col=cols[3])
arrows(4+a,coefs[1]+coefs[3],4+a,coefs[1]+coefs[3]+coefs[2],lwd=3,col=cols[2],length=lgth)
segments(5+a,coefs[1]+coefs[4],6+a,coefs[1]+coefs[4],lwd=3,col=cols[4])
arrows(6+a,coefs[1]+coefs[4],6+a,coefs[1]+coefs[4]+coefs[2],lwd=3,col=cols[2],length=lgth)
segments(7+a,coefs[1]+coefs[5],8+a,coefs[1]+coefs[5],lwd=3,col=cols[5])
arrows(8+a,coefs[1]+coefs[5],8+a,coefs[1]+coefs[5]+coefs[2],lwd=3,col=cols[2],length=lgth)
legend("right",names(coefs),fill=cols,cex=.75,bg="white")
```

In this case, the fitted means for each group, derived from the fitted coefficients, do not line up with those we obtain from simply taking the average from each of the eight possible groups. The reason is that our model uses five coefficients, instead of eight. We are **assuming** that the effects are additive. However, as we demonstrate in more detail below, this particular dataset is better described with a model including interactions.

```{r}
s <- split(spider$friction, spider$group)
mean(s[["L1pull"]])
coefs[1]
mean(s[["L1push"]])
coefs[1] + coefs[2]
```

Here we can demonstrate that the push vs. pull estimated coefficient, `coefs[2]`, is a weighted average of the difference of the means for each group. Furthermore, the weighting is determined by the sample size of each group. The math works out simply here because the sample size is equal for the push and pull subgroups within each leg pair. If the sample sizes were not equal for push and pull within each leg pair, the weighting is more complicated but uniquely determined by a formula involving the sample size of each subgroup, the total sample size, and the number of coefficients. This can be worked out from $(\mathbf{X}^\top \mathbf{X})^{-1} \mathbf{X}^\top$.

```{r}
means <- sapply(s, mean)
##the sample size of push or pull groups for each leg pair
ns <- sapply(s, length)[c(1,3,5,7)]
(w <- ns/sum(ns))
sum(w * (means[c(2,4,6,8)] - means[c(1,3,5,7)]))
coefs[2]
```

#### Contrasting coefficients

Sometimes, the comparison we are interested in is represented directly by a single coefficient in the model, such as the push vs. pull difference, which was `coefs[2]` above. However, sometimes, we want to make a comparison which is not a single coefficient, but a combination of coefficients, which is called a _contrast_. To introduce the concept of _contrasts_, first consider the comparisons which we can read off from the linear model summary:

```{r}
coefs
```

Here we have the intercept estimate, the push vs. pull estimated effect across all leg pairs, and the estimates for the L2 vs. L1 effect, the L3 vs. L1 effect, and the L4 vs. L1 effect. What if we want to compare two groups and one of those groups is not L1? The solution to this question is to use *contrasts*.

A *contrast* is a combination of estimated coefficient: $\mathbf{c^\top} \hat{\boldsymbol{\beta}}$, where $\mathbf{c}$ is a column vector with as many rows as the number of coefficients in the linear model. If $\mathbf{c}$ has a 0 for one or more of its rows, then the corresponding estimated coefficients in $\hat{\boldsymbol{\beta}}$ are not involved in the contrast.

If we want to compare leg pairs L3 and L2, this is equivalent to contrasting two coefficients from the linear model because, in this contrast, the comparison to the reference level *L1* cancels out:

$$ (\mbox{L3} - \mbox{L1}) - (\mbox{L2} - \mbox{L1}) = \mbox{L3} - \mbox{L2 }$$

An easy way to make these contrasts of two groups is to use the `contrast` function from the *contrast* package. We just need to specify which groups we want to compare. We have to pick one of *pull* or *push* types, although the answer will not differ, as we will see below.

```{r,message=FALSE,warning=FALSE}
library(contrast) #Available from CRAN
L3vsL2 <- contrast(fitTL,list(leg="L3",type="pull"),list(leg="L2",type="pull"))
L3vsL2
```

The first column `Contrast` gives the L3 vs. L2 estimate from the model we fit above.

We can show that the least squares estimates of a linear combination of coefficients is the same linear combination of the estimates.
Therefore, the effect size estimate is just the difference between two estimated coefficients. The contrast vector used by `contrast` is stored as a variable called `X` within the resulting object (not to be confused with our original $\mathbf{X}$, the design matrix).

```{r}
coefs[4] - coefs[3]
(cT <- L3vsL2$X)
cT %*% coefs
```

What about the standard error and t-statistic? As before, the t-statistic is the estimate divided by the standard error. The standard error of the contrast estimate is formed by multiplying the contrast vector $\mathbf{c}$ on either side of the estimated covariance matrix, $\hat{\Sigma}$, our estimate for $\mathrm{var}(\hat{\boldsymbol{\beta}})$:

$$ \sqrt{\mathbf{c^\top} \hat{\boldsymbol{\Sigma}} \mathbf{c}} $$

where we saw the covariance of the coefficients earlier:

$$
\boldsymbol{\Sigma} = \sigma^2 (\mathbf{X}^\top \mathbf{X})^{-1}
$$

We estimate $\sigma^2$ with the sample estimate $\hat{\sigma}^2$ described above and obtain:

```{r}
Sigma.hat <- sum(fitTL$residuals^2)/(nrow(X) - ncol(X)) * solve(t(X) %*% X)
signif(Sigma.hat, 2)
sqrt(cT %*% Sigma.hat %*% t(cT))
L3vsL2$SE
```

We would have obtained the same result for a contrast of L3 and L2 had we picked `type="push"`. The reason it does not change the contrast is because it leads to addition of the `typepush` effect on both sides of the difference, which cancels out:

```{r}
L3vsL2.equiv <- contrast(fitTL,list(leg="L3",type="push"),list(leg="L2",type="push"))
L3vsL2.equiv$X
```

## Linear Model with Interactions

In the previous linear model, we assumed that the push vs. pull effect was the same for all of the leg pairs (the same orange arrow). You can easily see that this does not capture the trends in the data that well. That is, the tips of the arrows did not line up perfectly with the group averages. For the L1 leg pair, the push vs. pull estimated coefficient was too large, and for the L3 leg pair, the push vs. pull coefficient was somewhat too small.

_Interaction terms_ will help us overcome this problem by introducing additional coefficients to compensate for differences in the push vs. pull effect across the 4 groups. As we already have a push vs. pull term in the model, we only need to add three more terms to have the freedom to find leg-pair-specific push vs. pull differences. As we will see, interaction terms are added to the design matrix by multiplying the columns of the design matrix representing existing terms.

We can rebuild our linear model with an interaction between `type` and `leg`, by including an extra term in the formula `type:leg`. The `:` symbol adds an interaction between the two variables surrounding it. An equivalent way to specify this model is `~ type*leg`, which will expand to the formula `~ type + leg + type:leg`, with main effects for `type`, `leg` and an interaction term `type:leg`.

```{r model_matrix_with_interaction_image, fig.cap="Image of model matrix with interactions."}
X <- model.matrix(~ type + leg + type:leg, data=spider)
colnames(X)
head(X)
imagemat(X, main="Model matrix for linear model with interactions")
```

Columns 6-8 (`typepush:legL2`, `typepush:legL3`, and `typepush:legL4`) are the product of the 2nd column (`typepush`) and columns 3-5 (the three `leg` columns). Looking at the last column, for example, the `typepush:legL4` column is adding an extra coefficient $\beta_{\textrm{push,L4}}$ to those samples which are both push samples and leg pair L4 samples. This accounts for a possible difference when the mean of samples in the L4-push group are not at the location which would be predicted by adding the estimated intercept, the estimated push coefficient `typepush`, and the estimated L4 coefficient `legL4`.

We can run the linear model using the same code as before:

```{r}
fitX <- lm(friction ~ type + leg + type:leg, data=spider)
summary(fitX)
coefs <- coef(fitX)
```

#### Examining the estimated coefficients

Here is where the plot with arrows really helps us interpret the coefficients. The estimated interaction coefficients (the yellow, brown and silver arrows) allow leg-pair-specific differences in the push vs. pull difference. The orange arrow now represents the estimated push vs. pull difference only for the reference leg pair, which is L1. If an estimated interaction coefficient is large, this means that the push vs. pull difference for that leg pair is very different than the push vs. pull difference in the reference leg pair.

Now, as we have eight terms in the model and eight parameters, you can check that the tips of the arrowheads are exactly equal to the group means (code not shown).

```{r spider_interactions2, fig.cap="Diagram of the estimated coefficients in the linear model. In the design with interaction terms, the orange arrow now indicates the push vs. pull difference only for the reference group (L1), while three new arrows (yellow, brown and grey) indicate the additional push vs. pull differences in the non-reference groups (L2, L3 and L4) with respect to the reference group.",echo=FALSE}
stripchart(split(spider$friction, spider$group),
           vertical=TRUE, pch=1, method="jitter", las=2, xlim=c(0,11), ylim=c(0,2))
cols <- brewer.pal(8,"Dark2")
abline(h=0)
arrows(1+a,0,1+a,coefs[1],lwd=3,col=cols[1],length=lgth)
abline(h=coefs[1],col=cols[1])
arrows(2+a,coefs[1],2+a,coefs[1]+coefs[2],lwd=3,col=cols[2],length=lgth)
arrows(3+a,coefs[1],3+a,coefs[1]+coefs[3],lwd=3,col=cols[3],length=lgth)
arrows(5+a,coefs[1],5+a,coefs[1]+coefs[4],lwd=3,col=cols[4],length=lgth)
arrows(7+a,coefs[1],7+a,coefs[1]+coefs[5],lwd=3,col=cols[5],length=lgth)
#now the interactions:
segments(3+a,coefs[1]+coefs[3],4+a,coefs[1]+coefs[3],lwd=3,col=cols[3])
arrows(4+a,coefs[1]+coefs[3],4+a,coefs[1]+coefs[3]+coefs[2],lwd=3,col=cols[2],length=lgth)
arrows(4+a,coefs[1]+coefs[2]+coefs[3],4+a,coefs[1]+coefs[2]+coefs[3]+coefs[6],lwd=3,col=cols[6],length=lgth)

segments(5+a,coefs[1]+coefs[4],6+a,coefs[1]+coefs[4],lwd=3,col=cols[4])
arrows(6+a,coefs[1]+coefs[4],6+a,coefs[1]+coefs[4]+coefs[2],lwd=3,col=cols[2],length=lgth)
arrows(6+a,coefs[1]+coefs[4]+coefs[2],6+a,coefs[1]+coefs[4]+coefs[2]+coefs[7],lwd=3,col=cols[7],length=lgth)

segments(7+a,coefs[1]+coefs[5],8+a,coefs[1]+coefs[5],lwd=3,col=cols[5])
arrows(8+a,coefs[1]+coefs[5],8+a,coefs[1]+coefs[5]+coefs[2],lwd=3,col=cols[2],length=lgth)
arrows(8+a,coefs[1]+coefs[5]+coefs[2],8+a,coefs[1]+coefs[5]+coefs[2]+coefs[8],lwd=3,col=cols[8],length=lgth)
legend("right",names(coefs),fill=cols,cex=.75,bg="white")
```

#### Contrasts

Again we will show how to combine estimated coefficients from the model using contrasts. For some simple cases, we can use the contrast package. Suppose we want to know the push vs. pull effect for the L2 leg pair samples. We can see from the arrow plot that this is the orange arrow plus the yellow arrow. We can also specify this comparison with the `contrast` function:

```{r,message=FALSE,message=FALSE}
library(contrast) ##Available from CRAN
L2push.vs.pull <- contrast(fitX,
                   list(leg="L2", type = "push"),
                   list(leg="L2", type = "pull"))
L2push.vs.pull
coefs[2] + coefs[6] ##we know this is also orange + yellow arrow
```

#### Differences of differences

The question of whether the push vs. pull difference is *different* in L2 compared to L1, is answered by a single term in the model: the `typepush:legL2` estimated coefficient corresponding to the yellow arrow in the plot. A p-value for whether this coefficient is actually equal to zero can be read off from the table printed with `summary(fitX)` above. Similarly, we can read off the p-values for the differences of differences for L3 vs. L1 and for L4 vs. L1.

Suppose we want to know if the push vs. pull difference is *different* in L3 compared to L2. By examining the arrows in the diagram above, we can see that the push vs. pull effect for a leg pair other than L1 is the `typepush` arrow plus the interaction term for that group.

If we work out the math for comparing across two non-reference leg pairs, this is:

$$
(\mbox{typepush} + \mbox{typepush:legL3}) - (\mbox{typepush} + \mbox{typepush:legL2})
$$

...which simplifies to:

$$
= \mbox{typepush:legL3} - \mbox{typepush:legL2}
$$

We can't make this contrast using the `contrast` function shown before, but we can make this comparison using the `glht` (for "general linear hypothesis test") function from the *multcomp* package. We need to form a 1-row matrix which has a -1 for the `typepush:legL2` coefficient and a +1 for the `typepush:legL3` coefficient. We provide this matrix to the `linfct` (linear function) argument, and obtain a summary table for this contrast of estimated interaction coefficients.

Note that there are other ways to perform contrasts using base R, and this is just our preferred way.

```{r,message=FALSE}
library(multcomp) ##Available from CRAN
C <- matrix(c(0,0,0,0,0,-1,1,0), 1)
L3vsL2interaction <- glht(fitX, linfct=C)
summary(L3vsL2interaction)
coefs[7] - coefs[6] ##we know this is also brown - yellow
```

## Analysis of Variance

Suppose that we want to know if the push vs. pull difference is different across leg pairs in general. We do not want to compare any two leg pairs in particular, but rather we want to know if the three interaction terms which represent differences in the push vs. pull difference across leg pairs are larger than we would expect them to be if the push vs. pull difference was in fact equal across all leg pairs.

Such a question can be answered by an _analysis of variance_, which is often abbreviated as ANOVA. ANOVA compares the reduction in the sum of squares of the residuals for models of different complexity. The model with eight coefficients is more complex than the model with five coefficients where we assumed the push vs. pull difference was equal across leg pairs. The least complex model would only use a single coefficient, an intercept. Under certain assumptions we can also perform inference that determines the probability of improvements as large as what we observed. Let's first print the result of an ANOVA in R and then examine the results in detail:

```{r}
anova(fitX)
```

The first line tells us that adding a variable `type` (push or pull) to the design is very useful (reduces the sum of squared residuals) compared to a model with only an intercept. We can see that it is useful, because this single coefficient reduces the sum of squares by 42.783. The original sum of squares of the model with just an intercept is:

```{r}
mu0 <- mean(spider$friction)
(initial.ss <- sum((spider$friction - mu0)^2))
```

Note that this initial sum of squares is just a scaled version of the sample variance:

```{r}
N <- nrow(spider)
(N - 1) * var(spider$friction)
```

Let's see exactly how we get this 42.783. We need to calculate the sum of squared residuals for the model with only the type information. We can do this by calculating the residuals, squaring these, summing these within groups and then summing across the groups.

```{r}
s <- split(spider$friction, spider$type)
after.type.ss <- sum( sapply(s, function(x) {
  residual <- x - mean(x)
  sum(residual^2)
  }) )
```

The reduction in sum of squared residuals from introducing the `type` coefficient is therefore:

```{r}
(type.ss <- initial.ss - after.type.ss)
```

Through [simple arithmetic](http://en.wikipedia.org/wiki/Partition_of_sums_of_squares#Proof), this reduction can be shown to be equivalent to the sum of squared differences between the fitted values for the models with formula `~type` and `~1`:

```{r}
sum(sapply(s, length) * (sapply(s, mean) - mu0)^2)
```

Keep in mind that the order of terms in the formula, and therefore rows in the ANOVA table, is important: each row considers the reduction in the sum of squared residuals after adding coefficients *compared to the model in the previous row*.

The other columns in the ANOVA table show the "degrees of freedom" with each row. As the `type` variable introduced only one term in the model, the `Df` column has a 1. Because the `leg` variable introduced three terms in the model (`legL2`, `legL3` and `legL4`), the `Df` column has a 3.

Finally, there is a column which lists the *F value*. The F value is the *mean of squares* for the inclusion of the terms of interest (the sum of squares divided by the degrees of freedom) divided by the mean squared residuals (from the bottom row):

$$ r_i = Y_i - \hat{Y}_i $$

$$ \mbox{Mean Sq Residuals} = \frac{1}{N - p} \sum_{i=1}^N r_i^2 $$

where $p$ is the number of coefficients in the model (here eight, including the intercept term).

Under the null hypothesis (the true value of the additional coefficient(s) is 0), we have a theoretical result for what the distribution of the F value will be for each row. The assumptions needed for this approximation to hold are similar to those of the t-distribution approximation we described in earlier chapters. We either need a large sample size so that CLT applies or we need the population data to follow a normal approximation.

As an example of how one interprets these p-values, let's take the last row `type:leg` which specifies the three interaction coefficients. Under the null hypothesis that the true value for these three additional terms is actually 0, e.g. $\beta_{\textrm{push,L2}} = 0, \beta_{\textrm{push,L3}} = 0, \beta_{\textrm{push,L4}} = 0$, then we can calculate the chance of seeing such a large F-value for this row of the ANOVA table. Remember that we are only concerned with large values here, because we have a ratio of sum of squares, the F-value can only be positive. The p-value in the last column for the `type:leg` row can be interpreted as: under the null hypothesis that there are no differences in the push vs. pull difference across leg pair, this is the probability of an estimated interaction coefficient explaining so much of the observed variance. If this p-value is small, we would consider rejecting the null hypothesis that the push vs. pull difference is the same across leg pairs.

The [F distribution](http://en.wikipedia.org/wiki/F-distribution) has two parameters: one for the degrees of freedom of the numerator (the terms of interest) and one for the denominator (the residuals). In the case of the interaction coefficients row, this is 3, the number of interaction coefficients divided by 274, the number of samples minus the total number of coefficients.

#### A different specification of the same model

Now we show an alternate specification of the same model, wherein we assume that each combination of type and leg has its own mean value (and so that the push vs. pull effect is not the same for each leg pair). This specification is in some ways simpler, as we will see, but it does not allow us to build the ANOVA table as above, because it does not split interaction coefficients out in the same way.

We start by constructing a factor variable with a level for each unique combination of `type` and `leg`. We include a `0 +` in the formula because we do not want to include an intercept in the model matrix.

```{r matrix_model_image_group_variable, fig.cap="Image of model matrix for linear model with group variable. This model, also with eight terms, gives a unique fitted value for each combination of type and leg."}
##earlier, we defined the 'group' column:
spider$group <- factor(paste0(spider$leg, spider$type))
X <- model.matrix(~ 0 + group, data=spider)
colnames(X)
head(X)
imagemat(X, main="Model matrix for linear model with group variable")
```

We can run the linear model with the familiar call:

```{r}
fitG <- lm(friction ~ 0 + group, data=spider)
summary(fitG)
coefs <- coef(fitG)
```

#### Examining the estimated coefficients

Now we have eight arrows, one for each group. The arrow tips align directly with the mean of each group:

```{r estimated_group_variables, fig.cap="Diagram of the estimated coefficients in the linear model, with each term representing the mean of a combination of type and leg.",echo=FALSE}
stripchart(split(spider$friction, spider$group),
           vertical=TRUE, pch=1, method="jitter", las=2, xlim=c(0,11), ylim=c(0,2))
cols <- brewer.pal(8,"Dark2")
abline(h=0)
for (i in 1:8) {
  arrows(i+a,0,i+a,coefs[i],lwd=3,col=cols[i],length=lgth)
}
legend("right",names(coefs),fill=cols,cex=.75,bg="white")
```

#### Simple contrasts using the contrast package

While we cannot perform an ANOVA with this formulation, we can easily contrast the estimated coefficients for individual groups using the `contrast` function:

```{r}
groupL2push.vs.pull <- contrast(fitG,
                                list(group = "L2push"),
                                list(group = "L2pull"))
groupL2push.vs.pull
coefs[4] - coefs[3]
```

#### Differences of differences when there is no intercept

We can also make pair-wise comparisons of the estimated push vs. pull difference across leg pair. For example, if we want to compare the push vs. pull difference in leg pair L3 vs. leg pair L2:

$$ (\mbox{L3push} - \mbox{L3pull}) - (\mbox{L2push} - \mbox{L2pull}) $$

$$ = \mbox{L3 push} + \mbox{L2pull} - \mbox{L3pull} - \mbox{L2push} $$

```{r}
C <- matrix(c(0,0,1,-1,-1,1,0,0), 1)
groupL3vsL2interaction <- glht(fitG, linfct=C)
summary(groupL3vsL2interaction)
names(coefs)
(coefs[6] - coefs[5]) - (coefs[4] - coefs[3])
```


/**
 * Copyright (c) 2006-2020 LOVE Development Team
 *
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    appreciated but is not required.
 * 2. Altered source versions must be plainly marked as such, and must not be
 *    misrepresented as being the original software.
 * 3. This notice may not be removed or altered from any source distribution.
 **/

#ifndef LOVE_PHYSICS_BOX2D_WRAP_PRISMATIC_JOINT_H
#define LOVE_PHYSICS_BOX2D_WRAP_PRISMATIC_JOINT_H

// LOVE
#include "common/runtime.h"
#include "wrap_Joint.h"
#include "PrismaticJoint.h"

namespace love
{
namespace physics
{
namespace box2d
{

PrismaticJoint *luax_checkprismaticjoint(lua_State *L, int idx);
extern "C" int luaopen_prismaticjoint(lua_State *L);

} // box2d
} // physics
} // love

#endif // LOVE_PHYSICS_BOX2D_WRAP_PRISMATIC_JOINT_H


/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/**
 *
 */
package org.mozilla.javascript.tests;

import junit.framework.TestCase;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.ContextAction;
import org.mozilla.javascript.Scriptable;

/**
 * Tests for global functions parseFloat and parseInt.
 * @author Marc Guillemot
 */
public class GlobalParseXTest extends TestCase {

	/**
	 * Test for bug #501972
	 * https://bugzilla.mozilla.org/show_bug.cgi?id=501972
	 * Leading whitespaces should be ignored with following white space chars
	 * (see ECMA spec 15.1.2.3)
	 * <TAB>, <SP>, <NBSP>, <FF>, <VT>, <CR>, <LF>, <LS>, <PS>, <USP>
	 */
    public void testParseFloatAndIntWhiteSpaces() {
    	testParseFloatWhiteSpaces("\\u00A0 "); // <NBSP>

    	testParseFloatWhiteSpaces("\\t ");
    	testParseFloatWhiteSpaces("\\u00A0 "); // <NBSP>
    	testParseFloatWhiteSpaces("\\u000C "); // <FF>
    	testParseFloatWhiteSpaces("\\u000B "); // <VT>
    	testParseFloatWhiteSpaces("\\u000D "); // <CR>
    	testParseFloatWhiteSpaces("\\u000A "); // <LF>
    	testParseFloatWhiteSpaces("\\u2028 "); // <LS>
    	testParseFloatWhiteSpaces("\\u2029 "); // <PS>
    }

    private void testParseFloatWhiteSpaces(final String prefix) {
        assertEvaluates("789", "String(parseInt('" + prefix + "789 '))");
        assertEvaluates("7.89", "String(parseFloat('" + prefix + "7.89 '))");
    }

	/**
	 * Test for bug #531436
	 * https://bugzilla.mozilla.org/show_bug.cgi?id=531436
	 * Trailing noise should be ignored
	 * (see ECMA spec 15.1.2.3)
	 */
    public void testParseFloatTrailingNoise() {
    	testParseFloat("7890", "789e1");
    	testParseFloat("7890", "789E1");
    	testParseFloat("7890", "789E+1");
    	testParseFloat("7890", "789E+1e");
    	testParseFloat("789", "7890E-1");
    	testParseFloat("789", "7890E-1e");

    	testParseFloat("789", "789hello");
    	testParseFloat("789", "789e");
    	testParseFloat("789", "789E");
    	testParseFloat("789", "789e+");
    	testParseFloat("789", "789Efgh");
    	testParseFloat("789", "789efgh");
    	testParseFloat("789", "789e-");
    	testParseFloat("789", "789e-hello");
    	testParseFloat("789", "789e+hello");
    	testParseFloat("789", "789+++hello");
    	testParseFloat("789", "789-e-+hello");
    	testParseFloat("789", "789e+e++hello");
    	testParseFloat("789", "789e-e++hello");
    }

    private void testParseFloat(final String expected, final String value) {
        assertEvaluates(expected, "String(parseFloat('" + value + "'))");
    }

    private void assertEvaluates(final Object expected, final String source) {
        final ContextAction action = new ContextAction() {
            public Object run(Context cx) {
                final Scriptable scope = cx.initStandardObjects();
                final Object rep = cx.evaluateString(scope, source, "test.js",
                        0, null);
                assertEquals(expected, rep);
                return null;
            }
        };
        Utils.runWithAllOptimizationLevels(action);
    }
 }


#include <gstdio.h>
#include <gimage.h>
#include <png.h>
#include <vector>

static void read_png_data(png_structp pngPtr, png_bytep data, png_size_t length)
{
    G_FILE* file = (G_FILE*)png_get_io_ptr(pngPtr);
    g_fread(data, 1, length, file);
}

static void write_png_data(png_structp pngPtr, png_bytep data, png_size_t length)
{
    G_FILE* file = (G_FILE*)png_get_io_ptr(pngPtr);
    g_fwrite(data, 1, length, file);
}

static void flush_png_data(png_structp pngPtr)
{
    G_FILE* file = (G_FILE*)png_get_io_ptr(pngPtr);
    g_fflush(file);
}

extern "C" {

int gimage_parsePng(const char *pathname, int *width, int *height, int *comp)
{
    G_FILE* fp = g_fopen(pathname, "rb");

    if (!fp)
        return GIMAGE_CANNOT_OPEN_FILE;

    #define HEADERSIZE 8
    unsigned char header[HEADERSIZE];
    if (g_fread(header, 1, HEADERSIZE, fp) != HEADERSIZE)
    {
        g_fclose(fp);
        return GIMAGE_UNRECOGNIZED_FORMAT;
    }

    if (png_sig_cmp(header, 0, HEADERSIZE) != 0)
    {
        g_fclose(fp);
        return GIMAGE_UNRECOGNIZED_FORMAT;
    }

    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

    png_infop info_ptr = png_create_info_struct(png_ptr);

    if (setjmp(png_jmpbuf(png_ptr)))
    {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        g_fclose(fp);
        return GIMAGE_ERROR_WHILE_READING;
    }

    png_set_read_fn(png_ptr, fp, read_png_data);

    png_set_sig_bytes(png_ptr, HEADERSIZE);
    png_read_info(png_ptr, info_ptr);

    // Strip 16 bit/color files down to 8 bits/color
    png_set_strip_16(png_ptr);

    // Pack 1, 2, 4 bit into bytes
    png_set_packing(png_ptr);

    // Auto-convert 1-, 2-, and 4- bit images to 8 bits, palette to RGB,
    // and transparency to alpha
    png_set_expand(png_ptr);

    // Update the information struct appropriately
    png_read_update_info(png_ptr, info_ptr);

    if (width)
        *width = png_get_image_width(png_ptr, info_ptr);

    if (height)
        *height = png_get_image_height(png_ptr, info_ptr);

    if (comp)
        *comp = png_get_channels(png_ptr, info_ptr);

    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
    g_fclose(fp);

    return GIMAGE_NO_ERROR;
}

int gimage_loadPng(const char *pathname, void *buf)
{
    G_FILE* fp = g_fopen(pathname, "rb");

    if (!fp)
        return GIMAGE_CANNOT_OPEN_FILE;

    #define HEADERSIZE 8
    unsigned char header[HEADERSIZE];
    if (g_fread(header, 1, HEADERSIZE, fp) != HEADERSIZE)
    {
        g_fclose(fp);
        return GIMAGE_UNRECOGNIZED_FORMAT;
    }

    if (png_sig_cmp(header, 0, HEADERSIZE) != 0)
    {
        g_fclose(fp);
        return GIMAGE_UNRECOGNIZED_FORMAT;
    }

    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

    png_infop info_ptr = png_create_info_struct(png_ptr);

    if (setjmp(png_jmpbuf(png_ptr)))
    {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        g_fclose(fp);
        return GIMAGE_ERROR_WHILE_READING;
    }

    png_set_read_fn(png_ptr, fp, read_png_data);

    png_set_sig_bytes(png_ptr, HEADERSIZE);
    png_read_info(png_ptr, info_ptr);

    // Strip 16 bit/color files down to 8 bits/color
    png_set_strip_16(png_ptr);

    // Pack 1, 2, 4 bit into bytes
    png_set_packing(png_ptr);

    // Auto-convert 1-, 2-, and 4- bit images to 8 bits, palette to RGB,
    // and transparency to alpha
    png_set_expand(png_ptr);

    // Update the information struct appropriately
    png_read_update_info(png_ptr, info_ptr);

    png_uint_32 width = png_get_image_width(png_ptr, info_ptr);
    png_uint_32 height = png_get_image_height(png_ptr, info_ptr);
    png_byte channels = png_get_channels(png_ptr, info_ptr);

    std::vector<unsigned char *> row_pointers(height);

    for (png_uint_32 i = 0; i < height; ++i)
        row_pointers[i] = (unsigned char*)buf + (i * width * channels);

    png_read_image(png_ptr, &row_pointers[0]);

    // If one has no need for the post-IDAT chunk data, the second argument can be NULL
    png_read_end(png_ptr, NULL);

    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
    g_fclose(fp);

    return GIMAGE_NO_ERROR;
}

int gimage_savePng(const char *filename, int width, int height, unsigned char *data)
{
    png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png)
        return GIMAGE_ERROR_WHILE_WRITING;

    png_infop info = png_create_info_struct(png);
    if (!info) {
        png_destroy_write_struct(&png, &info);
        return GIMAGE_ERROR_WHILE_WRITING;
    }

    G_FILE* fp = g_fopen(filename, "wb");

    if (!fp) {
        png_destroy_write_struct(&png, &info);
        return GIMAGE_CANNOT_OPEN_FILE;
    }

    png_set_write_fn(png, fp, write_png_data, flush_png_data);
    png_set_IHDR(png, info, width, height, 8 /* depth */, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE,
        PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
    png_colorp palette = (png_colorp)png_malloc(png, PNG_MAX_PALETTE_LENGTH * sizeof(png_color));
    if (!palette) {
        g_fclose(fp);
        png_destroy_write_struct(&png, &info);
        return false;
    }
    png_set_PLTE(png, info, palette, PNG_MAX_PALETTE_LENGTH);
    png_write_info(png, info);
    png_set_packing(png);

    png_bytepp rows = (png_bytepp)png_malloc(png, height * sizeof(png_bytep));
    for (int i = 0; i < height; ++i)
        rows[i] = (png_bytep)(data + i * width * 4);

    png_write_image(png, rows);
    png_write_end(png, info);
    png_free(png, palette);
    png_destroy_write_struct(&png, &info);

    g_fclose(fp);
    png_free(png,rows);
    return GIMAGE_NO_ERROR;
}

}


/*
 * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package java.lang.invoke;

import jdk.internal.vm.annotation.ForceInline;

// This class is auto-generated by java.lang.invoke.VarHandles$GuardMethodGenerator. Do not edit.
final class VarHandleGuards {

    @ForceInline
    @LambdaForm.Compiled
    final static Object guard_L_L(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            Object r = MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
            return ad.returnType.cast(r);
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static void guard_LL_V(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static Object guard_LL_L(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
            return ad.returnType.cast(r);
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static boolean guard_LLL_Z(VarHandle handle, Object arg0, Object arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static Object guard_LLL_L(VarHandle handle, Object arg0, Object arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
            return ad.returnType.cast(r);
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static int guard_L_I(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (int) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static void guard_LI_V(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static int guard_LI_I(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static boolean guard_LII_Z(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static int guard_LII_I(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static long guard_L_J(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (long) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static void guard_LJ_V(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static long guard_LJ_J(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static boolean guard_LJJ_Z(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static long guard_LJJ_J(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static float guard_L_F(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (float) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static void guard_LF_V(VarHandle handle, Object arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static float guard_LF_F(VarHandle handle, Object arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static boolean guard_LFF_Z(VarHandle handle, Object arg0, float arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static float guard_LFF_F(VarHandle handle, Object arg0, float arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static double guard_L_D(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (double) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static void guard_LD_V(VarHandle handle, Object arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static double guard_LD_D(VarHandle handle, Object arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static boolean guard_LDD_Z(VarHandle handle, Object arg0, double arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static double guard_LDD_D(VarHandle handle, Object arg0, double arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static Object guard__L(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            Object r = MethodHandle.linkToStatic(handle, handle.vform.getMemberName(ad.mode));
            return ad.returnType.cast(r);
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static void guard_L_V(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
        }
        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static boolean guard_LL_Z(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static int guard__I(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (int) MethodHandle.linkToStatic(handle, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static void guard_I_V(VarHandle handle, int arg0, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
        }
        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static int guard_I_I(VarHandle handle, int arg0, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (int) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static boolean guard_II_Z(VarHandle handle, int arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static int guard_II_I(VarHandle handle, int arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static long guard__J(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (long) MethodHandle.linkToStatic(handle, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static void guard_J_V(VarHandle handle, long arg0, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
        }
        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static long guard_J_J(VarHandle handle, long arg0, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (long) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static boolean guard_JJ_Z(VarHandle handle, long arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static long guard_JJ_J(VarHandle handle, long arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static float guard__F(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (float) MethodHandle.linkToStatic(handle, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static void guard_F_V(VarHandle handle, float arg0, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
        }
        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static float guard_F_F(VarHandle handle, float arg0, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (float) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static boolean guard_FF_Z(VarHandle handle, float arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static float guard_FF_F(VarHandle handle, float arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static double guard__D(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (double) MethodHandle.linkToStatic(handle, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static void guard_D_V(VarHandle handle, double arg0, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
        }
        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static double guard_D_D(VarHandle handle, double arg0, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (double) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static boolean guard_DD_Z(VarHandle handle, double arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static double guard_DD_D(VarHandle handle, double arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static Object guard_LI_L(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
            return ad.returnType.cast(r);
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static void guard_LIL_V(VarHandle handle, Object arg0, int arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static Object guard_LIL_L(VarHandle handle, Object arg0, int arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
            return ad.returnType.cast(r);
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static boolean guard_LILL_Z(VarHandle handle, Object arg0, int arg1, Object arg2, Object arg3, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static Object guard_LILL_L(VarHandle handle, Object arg0, int arg1, Object arg2, Object arg3, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
            return ad.returnType.cast(r);
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static void guard_LII_V(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static boolean guard_LIII_Z(VarHandle handle, Object arg0, int arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static int guard_LIII_I(VarHandle handle, Object arg0, int arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static long guard_LI_J(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static void guard_LIJ_V(VarHandle handle, Object arg0, int arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static long guard_LIJ_J(VarHandle handle, Object arg0, int arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static boolean guard_LIJJ_Z(VarHandle handle, Object arg0, int arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static long guard_LIJJ_J(VarHandle handle, Object arg0, int arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static float guard_LI_F(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static void guard_LIF_V(VarHandle handle, Object arg0, int arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static float guard_LIF_F(VarHandle handle, Object arg0, int arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static boolean guard_LIFF_Z(VarHandle handle, Object arg0, int arg1, float arg2, float arg3, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static float guard_LIFF_F(VarHandle handle, Object arg0, int arg1, float arg2, float arg3, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static double guard_LI_D(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static void guard_LID_V(VarHandle handle, Object arg0, int arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static double guard_LID_D(VarHandle handle, Object arg0, int arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static boolean guard_LIDD_Z(VarHandle handle, Object arg0, int arg1, double arg2, double arg3, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static double guard_LIDD_D(VarHandle handle, Object arg0, int arg1, double arg2, double arg3, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static int guard_LJ_I(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static void guard_LJI_V(VarHandle handle, Object arg0, long arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static int guard_LJI_I(VarHandle handle, Object arg0, long arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static boolean guard_LJII_Z(VarHandle handle, Object arg0, long arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static int guard_LJII_I(VarHandle handle, Object arg0, long arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static void guard_LJJ_V(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static boolean guard_LJJJ_Z(VarHandle handle, Object arg0, long arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
        }
    }

    @ForceInline
    @LambdaForm.Compiled
    final static long guard_LJJJ_J(VarHandle handle, Object arg0, long arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
        }
        else {
            MethodHandle mh = handle.getMethodHandle(ad.mode);
            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
        }
    }

}


/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.android.wearable.geofencing;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.wearable.DataApi;
import com.google.android.gms.wearable.Wearable;

import android.app.IntentService;
import android.app.NotificationManager;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.wearable.activity.ConfirmationActivity;
import android.util.Log;

import java.util.concurrent.TimeUnit;

import static com.example.android.wearable.geofencing.Constants.ACTION_CHECK_IN;
import static com.example.android.wearable.geofencing.Constants.ACTION_DELETE_DATA_ITEM;
import static com.example.android.wearable.geofencing.Constants.CONNECTION_TIME_OUT_MS;
import static com.example.android.wearable.geofencing.Constants.NOTIFICATION_ID;
import static com.example.android.wearable.geofencing.Constants.TAG;

/**
 * Handles "Check In" action on the location-based notification. Also deletes orphan DataItems
 * when a notification is dismissed from the wearable.
 */
public class CheckInAndDeleteDataItemsService extends IntentService
        implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    private GoogleApiClient mGoogleApiClient;

    public CheckInAndDeleteDataItemsService() {
        super(CheckInAndDeleteDataItemsService.class.getSimpleName());
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(Wearable.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        if (ACTION_CHECK_IN.equals(intent.getAction())) {
            // In a real app, code for checking in would go here. For this sample, we will simply
            // display a success animation.
            startConfirmationActivity(ConfirmationActivity.SUCCESS_ANIMATION,
                    getString(R.string.check_in_success));
            // Dismiss the check-in notification.
            ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).cancel(NOTIFICATION_ID);
        } else if (!ACTION_DELETE_DATA_ITEM.equals(intent.getAction())) {
            // The only possible actions should be checking in or dismissing the notification
            // (which causes an intent with ACTION_DELETE_DATA_ITEM).
            Log.e(TAG, "Unrecognized action: " + intent.getAction());
            return;
        }
        // Regardless of the action, delete the DataItem (we are only be handling intents
        // if the notification is dismissed or if the user has chosen to check in, either of which
        // would be completed at this point).
        mGoogleApiClient.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);
        Uri dataItemUri = intent.getData();
        if (mGoogleApiClient.isConnected()) {
            DataApi.DeleteDataItemsResult result = Wearable.DataApi
                    .deleteDataItems(mGoogleApiClient, dataItemUri).await();
            if (!result.getStatus().isSuccess()) {
                Log.e(TAG, "CheckInAndDeleteDataItemsService.onHandleIntent: "
                         + "Failed to delete dataItem: " + dataItemUri);
            } else if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, "Successfully deleted data item: " + dataItemUri);
            }
        } else {
            Log.e(TAG, "Failed to delete data item: " + dataItemUri
                     + " - Client disconnected from Google Play Services");
        }
        mGoogleApiClient.disconnect();
    }

    /**
     * Helper method to create confirmation animations on the wearable.
     * @param animationType Defined by constants in ConfirmationActivity.
     * @param message The message to display with the animation.
     */
    private void startConfirmationActivity(int animationType, String message) {
        Intent confirmationActivity = new Intent(this, ConfirmationActivity.class)
                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION)
                .putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE, animationType)
                .putExtra(ConfirmationActivity.EXTRA_MESSAGE, message);
        startActivity(confirmationActivity);
    }

    @Override
    public void onConnected(Bundle connectionHint) {
    }

    @Override
    public void onConnectionSuspended(int cause) {
    }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
    }

}


<?php namespace BackupManager\Filesystems;

use BackblazeB2\Client;
use League\Flysystem\Filesystem as Flysystem;
use Mhetreramesh\Flysystem\BackblazeAdapter;

/**
 * Class BackblazeFilesystem
 * @package BackupManager\Filesystems
 */
class BackblazeFilesystem implements Filesystem
{

    /**
     * Test fitness of visitor.
     * @param $type
     * @return bool
     */
    public function handles($type)
    {
        return strtolower($type) == 'b2';
    }

    /**
     * @param array $config
     * @return Flysystem
     * @throws \Exception
     */
    public function get(array $config)
    {
        if (!isset($config['options'])) {
            $config['options'] = [];
        }

        $client = new Client($config['accountId'], $config['key'], $config['options']);
        return new Flysystem(new BackblazeAdapter($client, $config['bucket']));
    }
}


/**
 * @license
 * Copyright Akveo. All Rights Reserved.
 * Licensed under the MIT License. See License.txt in the project root for license information.
 */

import React from 'react';

export interface Icons<T> {
  [key: string]: IconProvider<T>;
}

export interface IconPack<T> {
  name: string;
  icons: Icons<T>;
}

export interface IconProvider<T> {
  toReactElement(props?: T): React.ReactElement<T>;
}