[![Build Status](https://img.shields.io/github/actions/workflow/status/tcurdt/jdeb/ci.yml?style=for-the-badge)](https://github.com/tcurdt/jdeb/actions)
[![Coverage Status](https://img.shields.io/codecov/c/github/tcurdt/jdeb/master?style=for-the-badge)](https://codecov.io/gh/tcurdt/jdeb)
[![Maven Central](https://img.shields.io/maven-central/v/org.vafer/jdeb.svg?style=for-the-badge&maxAge=86400)](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.vafer%22%20AND%20a%3A%22jdeb%22)

# Debian packages in Java

This library provides an Ant task and a Maven plugin to create Debian packages
from Java builds in a truly cross platform manner. Build your Debian packages
on any platform that has Java support. Windows, Linux, OS X - it doesn't require
additional native tools installed.

Check the documentation on how to use it with [Maven](http://github.com/tcurdt/jdeb/blob/master/docs/maven.md)
or [Ant](http://github.com/tcurdt/jdeb/blob/master/docs/ant.md). Especially don't forget to check out the
[examples](http://github.com/tcurdt/jdeb/blob/master/src/examples/). Current
[javadocs](http://tcurdt.github.io/jdeb/apidocs/) and a source
[xref](http://tcurdt.github.io/jdeb/xref/) is also available.

## Where to get it

The jars are available in the [Maven central repository](https://repo1.maven.org/maven2/org/vafer/jdeb/).

If you feel adventurous or want to help out feel free to get the latest code
[via git](http://github.com/tcurdt/jdeb/tree/master).

    git clone git://github.com/tcurdt/jdeb.git

## Where to ask questions

[via git issue](https://github.com/tcurdt/jdeb/issues)

## Working towards jdeb 2.0

Over the years jdeb has grown more and more powerful - but also got more complex. In order to simplify the usage and apply what we have learned we are taking a step back. If you want to help to shape the usage of jdeb 2.0 feel free to contribute to the [planning](https://github.com/tcurdt/jdeb/issues/195). I think it still could be worth but this needs a sponsor.

## Related projects

Some links to other cross platform tools to package Linux applications:
* [apt-repo](https://github.com/theoweiss/apt-repo)
* [ant-deb-task](http://code.google.com/p/ant-deb-task)
* [jRPM](http://jrpm.sourceforge.net)
* [Install-Toolkit](http://install-toolkit.sourceforge.net)


[![Build Status](https://travis-ci.com/connectbot/connectbot.svg?branch=master)](
https://travis-ci.com/connectbot/connectbot)

# ConnectBot

ConnectBot is a [Secure Shell](https://en.wikipedia.org/wiki/Secure_Shell)
client for Android that lets you connect to remote servers over a
cryptographically secure link.

## Google Play

[![Get it on Google Play][2]][1]

  [1]: https://play.google.com/store/apps/details?id=org.connectbot
  [2]: https://developer.android.com/images/brand/en_generic_rgb_wo_60.png

## Compiling

### Android Studio

ConnectBot is most easily developed in [Android Studio](
https://developer.android.com/studio/). You can import this project
directly from its project creation screen by importing from the GitHub URL.

### Command line

To compile ConnectBot using `gradlew`, you must first specify where your
Android SDK is via the `ANDROID_SDK_HOME` environment variable. Then
you can invoke the Gradle wrapper to build:

```sh
./gradlew build
```

### Reproducing Continuous Integration (CI) builds locally

To run the Jenkins CI pipeline locally, you can use
`jenkinsfile-runner` via a Docker installation which can be invoked like
this:

```sh
docker run -it -v $(pwd):/workspace \
    -v jenkinsfile-runner-cache:/var/jenkinsfile-runner-cache \
    -v jenkinsfile-runner:/var/jenkinsfile-runner \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v $(which docker):$(which docker) \
    -e ANDROID_ADB_SERVER_ADDRESS=host.docker.internal \
    jenkins/jenkinsfile-runner
```

## Translations

If you'd like to correct or contribute new translations to ConnectBot,
then head on over to [ConnectBot's translations project](
https://translations.launchpad.net/connectbot/trunk/+pots/fortune)


![Jdbi Logo](docs/src/adoc/images/logo.svg)

[![CD from master pushes](https://github.com/jdbi/jdbi/actions/workflows/cd.yml/badge.svg)](https://github.com/jdbi/jdbi/actions/workflows/cd.yml) |
[![CI Build with tests](https://github.com/jdbi/jdbi/actions/workflows/ci.yml/badge.svg)](https://github.com/jdbi/jdbi/actions/workflows/ci.yml) | [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=jdbi_jdbi&metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=jdbi_jdbi) | [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=jdbi_jdbi&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=jdbi_jdbi) | [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=jdbi_jdbi&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=jdbi_jdbi)

The Jdbi library provides convenient, idiomatic access to relational databases in Java and other JVM technologies such as Kotlin, Clojure or Scala.

Jdbi is built on top of JDBC. If your database has a JDBC driver, you can use Jdbi with it.

* [Developer Guide](https://jdbi.org/)
* [Javadoc](https://jdbi.org/apidocs/)
* [User forums](https://github.com/jdbi/jdbi/discussions)
* [Mailing List](http://groups.google.com/group/jdbi)
* [Stack Overflow](https://stackoverflow.com/questions/tagged/jdbi)

Also check out the code examples in the [Examples](https://github.com/jdbi/jdbi/tree/master/examples) module.

## Acknowledgements and Funding

*  Jdbi is a recipient of the Spotify FOSS 2023 Fund
* Jdbi is supported by Tidelift

## Prerequisites

Jdbi requires Java 11 or better to run.

We run CI tests against Java 11, 17 and 21.

### Compatibility with older Java versions

Java 8, 9 and 10 are supported by any Jdbi version before **3.40.0**.

## Building

Jdbi requires a JDK version 17 or better to build. We enforce the latest LTS (currently Java 21) for releases.

Jdbi is "batteries included" and uses the [Apache Maven Wrapper](https://maven.apache.org/wrapper/). If an external Maven installation is used, Apache Maven 3.9 or later is required. Using the `make` targets requires GNU make.

All build tasks are organized as `make` targets.

Build the code an install it into the local repository:

```bash
$ make install
```

Running `make` or `make help` displays all available build targets with a short explanation. Some of the goals will require project membership privileges.  The [CONTRIBUTING.md](https://github.com/jdbi/jdbi/blob/master/CONTRIBUTING.md) document contains a list of all supported targets.

To add command line parameters to the maven executions from the Makefile, set the `MAVEN_CONFIG` variable:

``` bash
% MAVEN_CONFIG="-B -fae" make install
```

## Testing

Running `make tests` runs all unit and integration tests.

Some tests use Postgres and H2 databases (the tests will spin up temporary database servers as needed). Most modern OS (Windows, MacOS, Linux) and host architecture (x86_64, aarch64) should work.

### Docker requirements

For a full release build, docker or a docker compatible environment
must be available. A small number of tests use testcontainers which in
turn requires docker.

`make install-nodocker` skips the tests when building and installing Jdbi locally. `make tests-nodocker` skips the tests when only running tests.

Supported configurations are

* Docker Desktop on MacOS
* docker-ce on Linux
* podman 3 or better on Linux and MacOS

Other docker installations such as [Colima](https://github.com/abiosoft/colima) may work but are untested and unsupported.

For podman on Linux, the podman socket must be activated (see
https://stackoverflow.com/questions/71549856/testcontainers-with-podman-in-java-tests)
for details. SELinux sometimes interferes with testcontainers if
SELinux is active; make sure that there is an exception configured.

For podman on MacOS, it is necessary to set the `DOCKER_HOST` environment variable correctly.

## Contributing

Please read
[CONTRIBUTING.md](https://github.com/jdbi/jdbi/blob/master/CONTRIBUTING.md)
for instructions to set up your development environment to build Jdbi.

## Versioning

Jdbi uses [SemVer](http://semver.org/) to version its public API.

## License

This project is licensed under the
[Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0.html).

## Project Members

* **Brian McCallister (@brianm)** - Project Founder
* **Steven Schlansker (@stevenschlansker)**
* **Henning Schmiedehausen (@hgschmie)**
* **Matthew Hall (@qualidafial)**
* **Artem Prigoda (@arteam)**
* **Marnick L'Eau (@TheRealMarnes)**

## Special Thanks

* **Alex Harin ([@aharin](https://github.com/aharin))** - Kotlin plugins.
* **Ali Shakiba ([@shakiba](https://github.com/shakiba))** - JPA plugin
* **[@alwins0n](https://github.com/alwins0n)** - Vavr plugin.
* **Fred Deschenes ([@FredDeschenes](https://github.com/FredDeschenes))** -
  Kotlin unchecked extensions for `Jdbi` functions. `@BindFields`,
  `@BindMethods` annotations.


# About SLF4J

The Simple Logging Facade for Java (SLF4J) serves as a simple facade
or abstraction for various logging frameworks (e.g. java.util.logging,
logback, reload4j, log4j 2.x) allowing the end user to plug in the desired logging
framework at deployment time.

More information can be found on the [SLF4J website](http://www.slf4j.org).

# Build Status
[![Build Status](https://travis-ci.org/qos-ch/slf4j.svg)](https://travis-ci.org/qos-ch/slf4j)

# Search org.slf4j artifacts on Maven Central
[![Maven Central](https://img.shields.io/badge/Search%20org%2Eslf4j%20artifacts%20on%20Maven%20Central-2.0.x-green)](https://search.maven.org/search?q=g:org.slf4j%20AND%20v:2.0.%3F)

# In case of problems

In case of problems please do not hesitate to post an e-mail message
on the slf4j-user@qos.ch mailing list.  However, please do not
directly e-mail SLF4J developers. The answer to your question might
be useful to other users. Moreover, there are many knowledgeable users
on the slf4j-user mailing lists who can quickly answer your
questions.

# Urgent issues

For urgent issues do not hesitate to [champion a release](https://github.com/sponsors/qos-ch/sponsorships?tier_id=77436).
In principle, most championed issues are solved within 3 business days ensued by a release.

# How to build SLF4J

SLF4J uses Maven as its build tool.

SLF4J version 2.0.x will run under Java 8 but requires Java 9 or later to build.

# How to contribute pull requests

If you are interested in improving SLF4J, that is great! The SLF4J
community looks forward to your contribution. Please follow this
process:

1. Start a discussion on the [slf4j-dev mailing
list](http://www.slf4j.org/mailing-lists.html) about your proposed
change. Alternately, file a [bug
report](http://www.slf4j.org/bug-reporting.html) to initiate the
discussion. Note that we ask pull requests to be linked to a [Jira
ticket](https://jira.qos.ch/).

2. Fork qos-ch/slf4j. Ideally, create a new branch from your fork for
your contribution to make it easier to merge your changes back.

3. Make your changes on the branch you hopefully created in Step 2. Be
sure that your code passes existing unit tests. Please add unit tests
for your work if appropriate. It usually is.

4. All commits must have signed off by the contributor attesting to
[Developer Certificate of Origin
(DCO)](https://developercertificate.org/). Commits without sign off
will be automatically rejected by the [DCO GitHub
check](https://probot.github.io/apps/dco/) application.

5. Push your changes to your fork/branch in GitHub. Don't push it to
your master! If you do it will make it harder to submit new changes
later.

6. Submit a pull request to SLF4J from your commit page on GitHub.

7. Did we mention that you will be asked to link your pull request
with a Jira ticket?


[<img src="http://shiro.apache.org/images/apache-shiro-logo.png" align="right" />](http://shiro.apache.org)

[![Maven Central](https://img.shields.io/maven-central/v/org.apache.shiro/shiro-core)](https://central.sonatype.com/artifact/org.apache.shiro/shiro-core/)
[![Build Status](https://ci-builds.apache.org/buildStatus/icon?job=Shiro%2FShiro-all%2Fmain)](https://ci-builds.apache.org/job/Shiro/job/Shiro-all/job/main/)
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/apache/shiro/badge)](https://api.securityscorecards.dev/projects/github.com/apache/shiro)

Apache Shiro
============

[Apache Shiro](http://shiro.apache.org) is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management. With Shiro’s easy-to-understand API, you can quickly and easily secure any application – from the smallest mobile applications to the largest web and enterprise applications.

Documentation and Examples
--------------------------
http://shiro.apache.org

Tutorials
---------
* [10 Minute Tutorial](http://shiro.apache.org/10-minute-tutorial.html)
* [Web Application](http://shiro.apache.org/webapp-tutorial.html)

License
-------
[Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt)


[![CI](https://github.com/haraldk/TwelveMonkeys/actions/workflows/ci.yml/badge.svg)](https://github.com/haraldk/TwelveMonkeys/actions/workflows/ci.yml)
[![CodeQL](https://github.com/haraldk/TwelveMonkeys/actions/workflows/codeql.yml/badge.svg)](https://github.com/haraldk/TwelveMonkeys/actions/workflows/codeql.yml)
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/haraldk/TwelveMonkeys/badge)](https://securityscorecards.dev/viewer/?uri=github.com/haraldk/TwelveMonkeys)
[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/7900/badge)](https://www.bestpractices.dev/projects/7900)

[![Maven Central](https://img.shields.io/maven-central/v/com.twelvemonkeys.imageio/imageio?color=slateblue)](https://search.maven.org/search?q=g:com.twelvemonkeys.imageio)
[![Maven Snapshot](https://img.shields.io/nexus/s/com.twelvemonkeys.imageio/imageio?label=development&server=https%3A%2F%2Foss.sonatype.org&color=slateblue)](https://oss.sonatype.org/content/repositories/snapshots/com/twelvemonkeys/)
[![StackOverflow](https://img.shields.io/badge/stack_overflow-twelvemonkeys-orange.svg)](https://stackoverflow.com/questions/tagged/twelvemonkeys)
[![Donate](https://img.shields.io/badge/donate-PayPal-blue.svg)](https://paypal.me/haraldk76/100)

![Logo](logo.png)

## About

TwelveMonkeys ImageIO provides extended image file format support for the Java platform, through plugins for the `javax.imageio.*` package.

The main goal of this project is to provide support for formats not covered by the JRE itself.
Support for these formats is important, to be able to read data found
"in the wild", as well as to maintain access to data in legacy formats.
As there is lots of legacy data out there, we see the need for open implementations of readers for popular formats.

----

## File formats supported

| Plugin | Format   | Description                                             | R |  W  | Metadata | Notes |
| ------ | -------- |---------------------------------------------------------|:---:|:---:| -------- | ----- |
| Batik  | **SVG**  | Scalable Vector Graphics                                | ✔ |  -  | - | Requires [Batik](https://xmlgraphics.apache.org/batik/) |
|        | WMF      | MS Windows Metafile                                     | ✔ |  -  | - | Requires [Batik](https://xmlgraphics.apache.org/batik/) |
| [BMP](https://github.com/haraldk/TwelveMonkeys/wiki/BMP-Plugin)    | **BMP**  | MS Windows and IBM OS/2 Device Independent Bitmap       | ✔  |  ✔  | [Native](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/bmp_metadata.html), [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|        | CUR      | MS Windows Cursor Format                                | ✔  |  -  | - |
|        | ICO      | MS Windows Icon Format                                  | ✔  |  ✔  | - |
| [HDR](https://github.com/haraldk/TwelveMonkeys/wiki/HDR-Plugin)    | HDR      | Radiance High Dynamic Range RGBE Format                 | ✔  |  -  | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
| [ICNS](https://github.com/haraldk/TwelveMonkeys/wiki/ICNS-Plugin)   | ICNS     | Apple Icon Image                                        | ✔  |  ✔  | -  |
| [IFF](https://github.com/haraldk/TwelveMonkeys/wiki/IFF-Plugin)    | IFF      | Commodore Amiga/Electronic Arts Interchange File Format | ✔  |  ✔  | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
| [JPEG](https://github.com/haraldk/TwelveMonkeys/wiki/JPEG-Plugin)   | **JPEG** | Joint Photographers Expert Group                        | ✔  |  ✔  | [Native](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/jpeg_metadata.html#image), [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|   | JPEG Lossless |                                                         | ✔  |  -  | [Native](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/jpeg_metadata.html#image), [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
| [PCX](https://github.com/haraldk/TwelveMonkeys/wiki/PCX-Plugin)    | PCX      | ZSoft Paintbrush Format                                 | ✔  |  -  | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|        | DCX      | Multi-page PCX fax document                             | ✔  |  -  | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
| [PICT](https://github.com/haraldk/TwelveMonkeys/wiki/PICT-Plugin)   | PICT     | Apple QuickTime Picture Format                          | ✔  |  ✔  | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|        | PNTG     | Apple MacPaint Picture Format                           | ✔  |  -  | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
| [PNM](https://github.com/haraldk/TwelveMonkeys/wiki/PNM-Plugin)    | PAM      | NetPBM Portable Any Map                                 | ✔  |  ✔  | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|        | PBM      | NetPBM Portable Bit Map                                 | ✔  |  -  | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|        | PGM      | NetPBM Portable Grey Map                                | ✔  |  -  | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|        | PPM      | NetPBM Portable Pix Map                                 | ✔  |  ✔  | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|        | PFM      | Portable Float Map                                      | ✔  |  -  | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
| [PSD](https://github.com/haraldk/TwelveMonkeys/wiki/PSD-Plugin)    | **PSD**  | Adobe Photoshop Document                                | ✔  | (✔) | Native, [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|        |  PSB     | Adobe Photoshop Large Document                          | ✔  |  -  | Native, [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
| [SGI](https://github.com/haraldk/TwelveMonkeys/wiki/SGI-Plugin)    | SGI      | Silicon Graphics Image Format                           | ✔  |  -  | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
| [TGA](https://github.com/haraldk/TwelveMonkeys/wiki/TGA-Plugin)    | TGA      | Truevision TGA Image Format                             | ✔  |  ✔  | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|ThumbsDB| Thumbs.db| MS Windows Thumbs DB                                    | ✔  |  -  | - | OLE2 Compound Document based format only |
| [TIFF](https://github.com/haraldk/TwelveMonkeys/wiki/TIFF-Plugin)   | **TIFF** | Aldus/Adobe Tagged Image File Format                    | ✔  |  ✔  | [Native](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/tiff_metadata.html#ImageMetadata), [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|        | BigTIFF  |                                                         | ✔  |  ✔  | [Native](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/tiff_metadata.html#ImageMetadata), [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
| [WebP](https://github.com/haraldk/TwelveMonkeys/wiki/WebP-Plugin)   | **WebP** | Google WebP Format                                      | ✔  |  -  | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
| XWD    | XWD      | X11 Window Dump Format                                  | ✔  |  -  | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |

**Important note on using Batik:** *Please read [The Apache™ XML Graphics Project - Security](https://xmlgraphics.apache.org/security.html),
and make sure you use an updated and secure version.*

Note that GIF, PNG and WBMP formats are already supported through the ImageIO API, using the
[JDK standard plugins](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/package-summary.html).
For BMP, JPEG, and TIFF formats the TwelveMonkeys plugins provides extended format support and additional features.

## Basic usage

Most of the time, all you need to do is simply include the plugins in your project and write:

```java
BufferedImage image = ImageIO.read(file);
```

This will load the first image of the file, entirely into memory.

The basic and simplest form of writing is:

```java
if (!ImageIO.write(image, format, file)) {
   // Handle image not written case
}
```

This will write the entire image into a single file, using the default settings for the given format.

The plugins are discovered automatically at run time. See the [FAQ](#faq) for more info on how this mechanism works.

## Advanced usage

If you need more control of read parameters and the reading process, the common idiom for reading is something like:

```java
// Create input stream (in try-with-resource block to avoid leaks)
try (ImageInputStream input = ImageIO.createImageInputStream(file)) {
    // Get the reader
    Iterator<ImageReader> readers = ImageIO.getImageReaders(input);

    if (!readers.hasNext()) {
        throw new IllegalArgumentException("No reader for: " + file);
    }

    ImageReader reader = readers.next();

    try {
        reader.setInput(input);

        // Optionally, listen for read warnings, progress, etc.
        reader.addIIOReadWarningListener(...);
        reader.addIIOReadProgressListener(...);

        ImageReadParam param = reader.getDefaultReadParam();

        // Optionally, control read settings like sub sampling, source region or destination etc.
        param.setSourceSubsampling(...);
        param.setSourceRegion(...);
        param.setDestination(...);
        // ...

        // Finally read the image, using settings from param
        BufferedImage image = reader.read(0, param);

        // Optionally, read thumbnails, meta data, etc...
        int numThumbs = reader.getNumThumbnails(0);
        // ...
    }
    finally {
        // Dispose reader in finally block to avoid memory leaks
        reader.dispose();
    }
}
```

Query the reader for source image dimensions using `reader.getWidth(n)` and `reader.getHeight(n)` without reading the
entire image into memory first.

It's also possible to read multiple images from the same file in a loop, using `reader.getNumImages()`.

If you need more control of write parameters and the writing process, the common idiom for writing is something like:

```java
// Get the writer
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(format);

if (!writers.hasNext()) {
    throw new IllegalArgumentException("No writer for: " + format);
}

ImageWriter writer = writers.next();

try {
    // Create output stream (in try-with-resource block to avoid leaks)
    try (ImageOutputStream output = ImageIO.createImageOutputStream(file)) {
        writer.setOutput(output);

        // Optionally, listen to progress, warnings, etc.

        ImageWriteParam param = writer.getDefaultWriteParam();

        // Optionally, control format specific settings of param (requires casting), or
        // control generic write settings like sub sampling, source region, output type etc.

        // Optionally, provide thumbnails and image/stream metadata
        writer.write(..., new IIOImage(..., image, ...), param);
    }
}
finally {
    // Dispose writer in finally block to avoid memory leaks
    writer.dispose();
}
```

For more advanced usage, and information on how to use the ImageIO API, I suggest you read the
[Java Image I/O API Guide](https://docs.oracle.com/javase/7/docs/technotes/guides/imageio/spec/imageio_guideTOC.fm.html)
from Oracle.

#### Adobe Clipping Path support

```java
import com.twelvemonkeys.imageio.path.Paths;

...

try (ImageInputStream stream = ImageIO.createImageInputStream(new File("image_with_path.jpg")) {
    BufferedImage image = Paths.readClipped(stream);

    // Do something with the clipped image...
}
```
See [Adobe Clipping Path support on the Wiki](https://github.com/haraldk/TwelveMonkeys/wiki/Photoshop-Clipping-Path-support) for more details and example code.

#### Using the ResampleOp

The library comes with a resampling (image resizing) operation, that contains many different algorithms
to provide excellent results at reasonable speed.

```java
import com.twelvemonkeys.image.ResampleOp;

...

BufferedImage input = ...; // Image to resample
int width, height = ...; // new width/height

BufferedImageOp resampler = new ResampleOp(width, height, ResampleOp.FILTER_LANCZOS); // A good default filter, see class documentation for more info
BufferedImage output = resampler.filter(input, null);
```

#### Using the DiffusionDither

The library comes with a dithering operation, that can be used to convert `BufferedImage`s to `IndexColorModel` using
Floyd-Steinberg error-diffusion dither.

```java
import com.twelvemonkeys.image.DiffusionDither;

...

BufferedImage input = ...; // Image to dither

BufferedImageOp ditherer = new DiffusionDither();
BufferedImage output = ditherer.filter(input, null);
```

## Building

Download the project (using [Git](https://git-scm.com/downloads)):

    $ git clone git@github.com:haraldk/TwelveMonkeys.git

This should create a folder named `TwelveMonkeys` in your current directory. Change directory to the `TwelveMonkeys`
folder, and issue the command below to build.

Build the project (using [Maven](https://maven.apache.org/download.cgi)):

    $ mvn package

Currently, the recommended JDK for making a build is Oracle JDK 8.x.

It's possible to build using OpenJDK, but some tests might fail due to some minor differences between the color management systems used. You will need to either disable the tests in question, or build without tests altogether.

Because the unit tests needs quite a bit of memory to run, you might have to set the environment variable `MAVEN_OPTS`
to give the Java process that runs Maven more memory. I suggest something like `-Xmx512m -XX:MaxPermSize=256m`.

Optionally, you can install the project in your local Maven repository using:

    $ mvn install

## Installing

To install the plug-ins,
either use Maven and add the necessary dependencies to your project,
or manually add the needed JARs along with required dependencies in class-path.

The ImageIO registry and service lookup mechanism will make sure the plugins are available for use.

To verify that the JPEG plugin is installed and used at run-time, you could use the following code:

```java
Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("JPEG");
while (readers.hasNext()) {
    System.out.println("reader: " + readers.next());
}
```

The first line should print:

    reader: com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReader@somehash

#### Maven dependency example

To depend on the JPEG and TIFF plugin using Maven, add the following to your POM:

```xml
...
<dependencies>
    ...
    <dependency>
        <groupId>com.twelvemonkeys.imageio</groupId>
        <artifactId>imageio-jpeg</artifactId>
        <version>3.10.1</version>
    </dependency>
    <dependency>
        <groupId>com.twelvemonkeys.imageio</groupId>
        <artifactId>imageio-tiff</artifactId>
        <version>3.10.1</version>
    </dependency>

    <!--
    Optional dependency. Needed only if you deploy ImageIO plugins as part of a web app.
    Make sure you add the IIOProviderContextListener to your web.xml, see above.
    -->
    <dependency>
        <groupId>com.twelvemonkeys.servlet</groupId>
        <artifactId>servlet</artifactId>
        <version>3.10.1</version>
    </dependency>

    <!--
    Or Jakarta version, for Servlet API 5.0
    -->
    <dependency>
        <groupId>com.twelvemonkeys.servlet</groupId>
        <artifactId>servlet</artifactId>
        <version>3.10.1</version>
        <classifier>jakarta</classifier>
    </dependency>
</dependencies>
```

#### Manual dependency example

To depend on the JPEG and TIFF plugin in your IDE or program, add all of the following JARs to your class path:

    twelvemonkeys-common-lang-3.10.1.jar
    twelvemonkeys-common-io-3.10.1.jar
    twelvemonkeys-common-image-3.10.1.jar
    twelvemonkeys-imageio-core-3.10.1.jar
    twelvemonkeys-imageio-metadata-3.10.1.jar
    twelvemonkeys-imageio-jpeg-3.10.1.jar
    twelvemonkeys-imageio-tiff-3.10.1.jar

#### Deploying the plugins in a web app

Because the `ImageIO` plugin registry (the `IIORegistry`) is "VM global", it does not work well with
servlet contexts as-is. This is especially evident if you load plugins from the `WEB-INF/lib` or `classes` folder.
Unless you add `ImageIO.scanForPlugins()` somewhere in your code, the plugins might never be available at all.

In addition, servlet contexts dynamically loads and unloads classes (using a new class loader per context).
If you restart your application, old classes will by default remain in memory forever (because the next time
`scanForPlugins` is called, it's another `ClassLoader` that scans/loads classes, and thus they will be new instances
in the registry). If a read is attempted using one of the remaining "old" readers, weird exceptions
(like `NullPointerException`s when accessing `static final` initialized fields or `NoClassDefFoundError`s
for uninitialized inner classes) may occur.

To work around both the discovery problem and the resource leak,
it is *strongly recommended* to use the `IIOProviderContextListener` that implements
dynamic loading and unloading of ImageIO plugins for web applications.

```xml
<web-app ...>

...

    <listener>
        <display-name>ImageIO service provider loader/unloader</display-name>
        <listener-class>com.twelvemonkeys.servlet.image.IIOProviderContextListener</listener-class>
    </listener>

...

</web-app>
```

Loading plugins from `WEB-INF/lib` without the context listener installed is unsupported and will not work correctly.

The context listener has no dependencies to the TwelveMonkeys ImageIO plugins, and may be used with JAI ImageIO
or other ImageIO plugins as well.

Another safe option, is to place the JAR files in the application server's shared or common lib folder.

##### Jakarta Servlet Support

For those transitioning from the old `javax.servlet` to the new `jakarta.servlet` package, there is a separate
dependency available. It contains exactly the same servlet classes as mentioned above, but built against the new Jakarta EE
packages. The dependency has the same group name and identifier as before, but a `jakarta` *classifier* appended, to
distinguish it from the non-Jakarta package.

See the [Maven dependency example](#maven-dependency-example) for how to enable it with Maven.
Gradle or other build tools will have similar options.

#### Including the plugins in a "fat" JAR

The recommended way to use the plugins, is just to include the JARs as-is in your project, through a Maven dependency or similar.
Re-packaging is not necessary to use the library, and not recommended.

However, if you like to create a "fat"
JAR, or otherwise like to re-package the JARs for some reason, it's important to remember that automatic discovery of
the plugins by ImageIO depends on the
[Service Provider Interface (SPI)](https://docs.oracle.com/javase/tutorial/sound/SPI-intro.html) mechanism.
In short, each JAR contains a special folder, named `META-INF/services` containing one or more files,
typically `javax.imageio.spi.ImageReaderSpi` and `javax.imageio.spi.ImageWriterSpi`.
These files exist *with the same name in every JAR*,
so if you simply unpack everything to a single folder or create a JAR, files will be overwritten and behavior be
unspecified (most likely you will end up with a single plugin being installed).

The solution is to make sure all files with the same name, are merged to a single file,
containing all the SPI information of each type. If using the Maven Shade plugin, you should use the
[ServicesResourceTransformer](https://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html#ServicesResourceTransformer)
to properly merge these files. You may also want to use the
[ManifestResourceTransforme](https://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html#ManifestResourceTransformer)
to get the correct vendor name, version info etc.
Other "fat" JAR bundlers will probably have similar mechanisms to merge entries with the same name.

### Links to prebuilt binaries

##### Latest version (3.10.1)

The latest version that will run on Java 7 is 3.9.4. Later versions will require Java 8 or later.

Common dependencies
* [common-lang-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-lang/3.10.1/common-lang-3.10.1.jar)
* [common-io-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-io/3.10.1/common-io-3.10.1.jar)
* [common-image-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-image/3.10.1/common-image-3.10.1.jar)

ImageIO dependencies
* [imageio-core-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-core/3.10.1/imageio-core-3.10.1.jar)
* [imageio-metadata-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-metadata/3.10.1/imageio-metadata-3.10.1.jar)

ImageIO plugins
* [imageio-bmp-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-bmp/3.10.1/imageio-bmp-3.10.1.jar)
* [imageio-hdr-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-hdr/3.10.1/imageio-hdr-3.10.1.jar)
* [imageio-icns-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-icns/3.10.1/imageio-icns-3.10.1.jar)
* [imageio-iff-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-iff/3.10.1/imageio-iff-3.10.1.jar)
* [imageio-jpeg-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-jpeg/3.10.1/imageio-jpeg-3.10.1.jar)
* [imageio-pcx-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pcx/3.10.1/imageio-pcx-3.10.1.jar)
* [imageio-pict-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pict/3.10.1/imageio-pict-3.10.1.jar)
* [imageio-pnm-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pnm/3.10.1/imageio-pnm-3.10.1.jar)
* [imageio-psd-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-psd/3.10.1/imageio-psd-3.10.1.jar)
* [imageio-sgi-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-sgi/3.10.1/imageio-sgi-3.10.1.jar)
* [imageio-tga-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-tga/3.10.1/imageio-tga-3.10.1.jar)
* [imageio-thumbsdb-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-thumbsdb/3.10.1/imageio-thumbsdb-3.10.1.jar)
* [imageio-tiff-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-tiff/3.10.1/imageio-tiff-3.10.1.jar)
* [imageio-webp-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-webp/3.10.1/imageio-webp-3.10.1.jar)
* [imageio-xwd-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-xwd/3.10.1/imageio-xwd-3.10.1.jar)

ImageIO plugins requiring 3rd party libs
* [imageio-batik-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-batik/3.10.1/imageio-batik-3.10.1.jar)

Photoshop Path support for ImageIO
* [imageio-clippath-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-clippath/3.10.1/imageio-clippath-3.10.1.jar)

Servlet support
* [servlet-3.10.1.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/servlet/servlet/3.10.1/servlet-3.10.1.jar)

## License

This project is provided under the OSI approved [BSD license](https://opensource.org/licenses/BSD-3-Clause):

    Copyright (c) 2008-2022, Harald Kuhr
    All rights reserved.

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

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

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

    o Neither the name of the copyright holder nor the names of its
      contributors may be used to endorse or promote products derived from
      this software without specific prior written permission.

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

## FAQ

q: How do I use it?

a: The easiest way is to build your own project using Maven, Gradle or other build tool with dependency management,
and just add dependencies to the specific plug-ins you need.
 If you don't use such a build tool, make sure you have all the necessary JARs in classpath. See the Install section above.

q: What changes do I have to make to my code in order to use the plug-ins?

a: The short answer is: None. For basic usage, like `ImageIO.read(...)` or `ImageIO.getImageReaders(...)`, there is no need
to change your code. Most of the functionality is available through standard ImageIO APIs, and great care has been taken
 not to introduce extra API where none is necessary.

Should you want to use very specific/advanced features of some of the formats, you might have to use specific APIs, like
   setting base URL for an SVG image that consists of multiple files,
   or controlling the output compression of a TIFF file.

q: How does it work?

a: The TwelveMonkeys ImageIO project contains plug-ins for ImageIO. ImageIO uses a service lookup mechanism, to discover plug-ins at runtime.

All you have to do, is to make sure you have the TwelveMonkeys ImageIO JARs in your classpath.

You can read more about the registry and the lookup mechanism in the [IIORegistry API doc](https://docs.oracle.com/javase/7/docs/api/javax/imageio/spi/IIORegistry.html).

The fine print: The TwelveMonkeys service providers for JPEG, BMP and TIFF, overrides the onRegistration method, and
utilizes the pairwise partial ordering mechanism of the `IIOServiceRegistry` to make sure it is installed before
the Sun/Oracle provided `JPEGImageReader`, `BMPImageReader` `TIFFImageReader`, and the Apple provided `TIFFImageReader` on OS X,
respectively. Using the pairwise ordering will not remove any functionality form these implementations, but in most
cases you'll end up using the TwelveMonkeys plug-ins instead.

q: Why is there no support for common formats like GIF or PNG?

a: The short answer is simply that the built-in support in ImageIO for these formats are considered good enough as-is.
If you are looking for better PNG write performance on Java 7 and 8, see [JDK9 PNG Writer Backport](https://github.com/gredler/jdk9-png-writer-backport).

q: When is the next release? What is the current release schedule?

a: The goal is to make monthly releases, containing bug fixes and minor new features.
And quarterly releases with more "major" features.

q: I love this project! How can I help?

a: Have a look at the open issues, and see if there are any issues you can help fix, or provide sample file or create test cases for.
It is also possible for you or your organization to become a sponsor, through GitHub Sponsors.
Providing funding will allow us to spend more time on fixing bugs and implementing new features.

q: What about JAI? Several of the formats are already supported by JAI.

a: While JAI (and jai-imageio in particular) have support for some of the same formats, JAI has some major issues.
The most obvious being:
- It's not actively developed. No issue has been fixed for years.
- To get full format support, you need native libs.
Native libs does not exist for several popular platforms/architectures, and further the native libs are not open source.
Some environments may also prevent deployment of native libs, which brings us back to square one.

q: What about JMagick or IM4Java? Can't you just use what's already available?

a: While great libraries with a wide range of formats support, the ImageMagick-based libraries has some disadvantages
compared to ImageIO.
- No real stream support, these libraries only work with files.
- No easy access to pixel data through standard Java2D/BufferedImage API.
- Not a pure Java solution, requires system specific native libs.

-----

We did it


# twilio-java

[![Tests](https://github.com/twilio/twilio-java/actions/workflows/test-and-deploy.yml/badge.svg)](https://github.com/twilio/twilio-java/actions/workflows/test-and-deploy.yml)
[![Maven Central](https://img.shields.io/maven-central/v/com.twilio.sdk/twilio.svg)](https://mvnrepository.com/artifact/com.twilio.sdk/twilio)
[![Learn with TwilioQuest](https://img.shields.io/static/v1?label=TwilioQuest&message=Learn%20to%20contribute%21&color=F22F46&labelColor=1f243c&style=flat-square&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAAASFBMVEUAAAAZGRkcHBwjIyMoKCgAAABgYGBoaGiAgICMjIyzs7PJycnMzMzNzc3UoBfd3d3m5ubqrhfrMEDu7u739/f4vSb/3AD///9tbdyEAAAABXRSTlMAAAAAAMJrBrEAAAKoSURBVHgB7ZrRcuI6EESdyxXGYoNFvMD//+l2bSszRgyUYpFAsXOeiJGmj4NkuWx1Qeh+Ekl9DgEXOBwOx+Px5xyQhDykfgq4wG63MxxaR4ddIkg6Ul3g84vCIcjPBA5gmUMeXESrlukuoK33+33uID8TWeLAdOWsKpJYzwVMB7bOzYSGOciyUlXSn0/ABXTosJ1M1SbypZ4O4MbZuIDMU02PMbauhhHMHXbmebmALIiEbbbbbUrpF1gwE9kFfRNAJaP+FQEXCCTGyJ4ngDrjOFo3jEL5JdqjF/pueR4cCeCGgAtwmuRS6gDwaRiGvu+DMFwSBLTE3+jF8JyuV1okPZ+AC4hDFhCHyHQjdjPHUKFDlHSJkHQXMB3KpSwXNGJPcwwTdZiXlRN0gSp0zpWxNtM0beYE0nRH6QIbO7rawwXaBYz0j78gxjokDuv12gVeUuBD0MDi0OQCLvDaAho4juP1Q/jkAncXqIcCfd+7gAu4QLMACCLxpRsSuQh0igu0C9Svhi7weAGZg50L3IE3cai4IfkNZAC8dfdhsUD3CgKBVC9JE5ABAFzg4QL/taYPAAWrHdYcgfLaIgAXWJ7OV38n1LEF8tt2TH29E+QAoDoO5Ve/LtCQDmKM9kPbvCEBApK+IXzbcSJ0cIGF6e8gpcRhUDogWZ8JnaWjPXc/fNnBBUKRngiHgTUSivSzDRDgHZQOLvBQgf8rRt+VdBUUhwkU6VpJ+xcOwQUqZr+mR0kvBUgv6cB4+37hQAkXqE8PwGisGhJtN4xAHMzrsgvI7rccXqSvKh6jltGlrOHA3Xk1At3LC4QiPdX9/0ndHpGVvTjR4bZA1ypAKgVcwE5vx74ulwIugDt8e/X7JgfkucBMIAr26ndnB4UCLnDOqvteQsHlgX9N4A+c4cW3DXSPbwAAAABJRU5ErkJggg==)](https://twil.io/learn-open-source)

## Documentation

The documentation for the Twilio API can be found [here][apidocs].

The Java library documentation can be found [here][libdocs].

## Versions

`twilio-java` uses a modified version of [Semantic Versioning](https://semver.org) for all changes. [See this document](VERSIONS.md) for details.

### TLS 1.2 Requirements

New accounts and subaccounts are now required to use TLS 1.2 when accessing the REST API. ["Upgrade Required" errors](https://www.twilio.com/docs/api/errors/20426) indicate that TLS 1.0/1.1 is being used.

### Supported Java Versions

This library supports the following Java implementations:

- OpenJDK 8
- OpenJDK 11
- OpenJDK 17
- OracleJDK 8
- OracleJDK 11
- OracleJDK 17

For Java 7 support, use `twilio-java` major version `7.X.X`.

## Installation

`twilio-java` uses Maven. At present the jars _are_ available from a public [maven](https://mvnrepository.com/artifact/com.twilio.sdk/twilio) repository.

Use the following dependency in your project to grab via Maven:

```xml
<dependency>
  <groupId>com.twilio.sdk</groupId>
  <artifactId>twilio</artifactId>
  <version>10.X.X</version>
  <scope>compile</scope>
</dependency>
```

or Gradle:

```groovy
implementation "com.twilio.sdk:twilio:10.X.X"
```

If you want to compile it yourself, here's how:

```shell
git clone git@github.com:twilio/twilio-java
cd twilio-java
mvn install       # Requires maven, download from https://maven.apache.org/download.html
```

If you want to build your own .jar, execute the following from within the cloned directory:

```shell
mvn package
```

If you run into trouble with local tests, use:

```shell
mvn package -Dmaven.test.skip=true
```

### Test your installation

Try sending yourself an SMS message, like this:

```java
import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Message;
import com.twilio.type.PhoneNumber;

public class Example {

  // Find your Account Sid and Token at console.twilio.com
  public static final String ACCOUNT_SID = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
  public static final String AUTH_TOKEN = "your_auth_token";

  public static void main(String[] args) {
    Twilio.init(ACCOUNT_SID, AUTH_TOKEN);

    Message message = Message
      .creator(
        new PhoneNumber("+15558675309"),
        new PhoneNumber("+15017250604"),
        "This is the ship that made the Kessel Run in fourteen parsecs?"
      )
      .create();

    System.out.println(message.getSid());
  }
}
```

> **Warning**
> It's okay to hardcode your credentials when testing locally, but you should use environment variables to keep them secret before committing any code or deploying to production. Check out [How to Set Environment Variables](https://www.twilio.com/blog/2017/01/how-to-set-environment-variables.html) for more information.

## Usage

### Initialize the Client

```java
import com.twilio.Twilio;
import com.twilio.exception.AuthenticationException;

public class Example {

  private static final String ACCOUNT_SID =
    "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
  private static final String AUTH_TOKEN = "your_auth_token";

  public static void main(String[] args) throws AuthenticationException {
    Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
  }
}
```

### Environment Variables

`twilio-java` supports the credentials, region, and edge values stored in the following environment variables:

- `TWILIO_ACCOUNT_SID`
- `TWILIO_AUTH_TOKEN`
- `TWILIO_REGION`
- `TWILIO_EDGE`

If using these variables, the above client initialization can be skipped.

### Make a Call

```java
import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Call;
import com.twilio.type.PhoneNumber;
import java.net.URI;
import java.net.URISyntaxException;

public class Example {

  public static final String ACCOUNT_SID = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
  public static final String AUTH_TOKEN = "your_auth_token";

  public static void main(String[] args) throws URISyntaxException {
    Twilio.init(ACCOUNT_SID, AUTH_TOKEN);

    Call call = Call
      .creator(
        new PhoneNumber("+14155551212"),
        new PhoneNumber("+15017250604"),
        new URI("http://demo.twilio.com/docs/voice.xml")
      )
      .create();

    System.out.println(call.getSid());
  }
}
```

### Get an existing Call

```java
import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Call;

public class Example {

  public static final String ACCOUNT_SID = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
  public static final String AUTH_TOKEN = "your_auth_token";

  public static void main(String[] args) {
    Twilio.init(ACCOUNT_SID, AUTH_TOKEN);

    Call call = Call.fetcher("CA42ed11f93dc08b952027ffbc406d0868").fetch();

    System.out.println(call.getTo());
  }
}
```

### Iterate through records

The library automatically handles paging for you. With the `read` method, you can specify the number of records you want to receive (`limit`) and the maximum size you want each page fetch to be (`pageSize`). The library will then handle the task for you, fetching new pages under the hood as you iterate over the records.

For more information, view the [auto-generated library docs](https://www.twilio.com/docs/libraries/reference/twilio-java/).

#### Use the `read` method

```java
import com.twilio.Twilio;
import com.twilio.base.ResourceSet;
import com.twilio.rest.api.v2010.account.Call;

public class Example {

  public static final String ACCOUNT_SID = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
  public static final String AUTH_TOKEN = "your_auth_token";

  public static void main(String[] args) {
    Twilio.init(ACCOUNT_SID, AUTH_TOKEN);

    ResourceSet<Call> calls = Call.reader().read();

    for (Call call : calls) {
      System.out.println(call.getDirection());
    }
  }
}
```

### Specify Region and/or Edge

To take advantage of Twilio's [Global Infrastructure](https://www.twilio.com/docs/global-infrastructure), specify the target Region and/or Edge for the client:

```java
Twilio.init(accountSid, authToken);
Twilio.setRegion("au1");
Twilio.setEdge("sydney");
```

This will result in the `hostname` transforming from `api.twilio.com` to `api.sydney.au1.twilio.com`.

### Enable Debug Logging

This library uses SLF4J for logging. Consult the [SFL4J documentation](http://slf4j.org/docs.html) for information about logging configuration.

For example, if you are using `log4j`:

- Make sure you have `log4j-slf4j-impl`, `log4j-core` and `log4j-api` in your `pom.xml` file
- Define the logging level for the Twilio HTTP client in your configuration. For example, in `src/main/resources/log4j2.xml`:

  ```xml
  <?xml version="1.0" encoding="UTF-8"?>
  <Configuration status="WARN">
      <Appenders>
          <Console name="Console" target="SYSTEM_OUT">
              <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level - %msg%n"/>
          </Console>
      </Appenders>
      <Loggers>
          <!--Your Twilio logging configuration goes here-->
          <Logger name="com.twilio.http" level="debug" additivity="false">
              <AppenderRef ref="Console"/>
          </Logger>
          <Root level="info">
              <AppenderRef ref="Console"/>
          </Root>
      </Loggers>
  </Configuration>
  ```

### Handle Exceptions

```java
import com.twilio.exception.ApiException;

try {
    Message message = Message.creator(
        new PhoneNumber("+15558881234"),  // To number
        new PhoneNumber("+15559994321"),  // From number
        "Hello world!"                    // SMS body
    ).create();

    System.out.println(message.getSid());
} catch (final ApiException e) {
    System.err.println(e);
}
```

### Use a Client With PKCV Authentication

Additional documentation here: https://twilio.com/docs/iam/pkcv/quickstart

```java
ValidationClient httpClient = new ValidationClient(ACCOUNT_SID, key.getSid(), signingKey.getSid(), pair.getPrivate());
TwilioRestClient client = new TwilioRestClient.Builder(signingKey.getSid(), signingKey.getSecret())
    .accountSid(ACCOUNT_SID)
    .httpClient(httpClient)
    .build();
```

### Generate TwiML

To control phone calls, your application needs to output [TwiML][twiml].

TwiML in twilio-java now use the builder pattern!

```java
TwiML twiml = new VoiceResponse.Builder()
    .say(new Say.Builder("Hello World!").build())
    .play(new Play.Builder("https://api.twilio.com/cowbell.mp3").loop(5).build())
    .build();
```

That will output XML that looks like this:

```xml
<Response>
    <Say>Hello World!</Say>
    <Play loop="5">https://api.twilio.com/cowbell.mp3</Play>
</Response>
```

### Use a custom HTTP Client

To use a custom HTTP client with this helper library, please see the [advanced example of how to do so](./advanced-examples/custom-http-client.md).

## Docker image

The `Dockerfile` present in this repository and its respective `twilio/twilio-java` Docker image are currently used by Twilio for testing purposes only.

## Getting Help

If you need help installing or using the library, please check the [Twilio Support Help Center](https://support.twilio.com) first, and [file a support ticket](https://twilio.com/help/contact) if you don't find an answer to your question.

If you've instead found a bug in the library or would like new features added, go ahead and open issues or pull requests against this repo!

[apidocs]: https://www.twilio.com/docs/api
[twiml]: https://www.twilio.com/docs/api/twiml
[libdocs]: https://twilio.github.io/twilio-java


# jsoup: Java HTML Parser

**jsoup** is a Java library that makes it easy to work with real-world HTML and XML. It offers an easy-to-use API for URL fetching, data parsing, extraction, and manipulation using DOM API methods, CSS, and xpath selectors.

**jsoup** implements the [WHATWG HTML5](https://html.spec.whatwg.org/multipage/) specification, and parses HTML to the same DOM as modern browsers.

* scrape and [parse](https://jsoup.org/cookbook/input/parse-document-from-string) HTML from a URL, file, or string
* find and [extract data](https://jsoup.org/cookbook/extracting-data/selector-syntax), using DOM traversal or CSS selectors
* manipulate the [HTML elements](https://jsoup.org/cookbook/modifying-data/set-html), attributes, and text
* [clean](https://jsoup.org/cookbook/cleaning-html/safelist-sanitizer) user-submitted content against a safe-list, to prevent XSS attacks
* output tidy HTML

jsoup is designed to deal with all varieties of HTML found in the wild; from pristine and validating, to invalid tag-soup; jsoup will create a sensible parse tree.

See [**jsoup.org**](https://jsoup.org/) for downloads and the full [API documentation](https://jsoup.org/apidocs/).

[![Build Status](https://github.com/jhy/jsoup/workflows/Build/badge.svg)](https://github.com/jhy/jsoup/actions?query=workflow%3ABuild)

## Example
Fetch the [Wikipedia](https://en.wikipedia.org/wiki/Main_Page) homepage, parse it to a [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction), and select the headlines from the *In the News* section into a list of [Elements](https://jsoup.org/apidocs/org/jsoup/select/Elements.html):

```java
Document doc = Jsoup.connect("https://en.wikipedia.org/").get();
log(doc.title());
Elements newsHeadlines = doc.select("#mp-itn b a");
for (Element headline : newsHeadlines) {
  log("%s\n\t%s",
    headline.attr("title"), headline.absUrl("href"));
}
```
[Online sample](https://try.jsoup.org/~LGB7rk_atM2roavV0d-czMt3J_g), [full source](https://github.com/jhy/jsoup/blob/master/src/main/java/org/jsoup/examples/Wikipedia.java).

## Open source
jsoup is an open source project distributed under the liberal [MIT license](https://jsoup.org/license). The source code is available on [GitHub](https://github.com/jhy/jsoup).

## Getting started
1. [Download](https://jsoup.org/download) the latest jsoup jar (or add it to your Maven/Gradle build)
2. Read the [cookbook](https://jsoup.org/cookbook/)
3. Enjoy!

### Android support
When used in Android projects, [core library desugaring](https://developer.android.com/studio/write/java8-support#library-desugaring) with the [NIO specification](https://developer.android.com/studio/write/java11-nio-support-table) should be enabled to support Java 8+ features.

## Development and support
If you have any questions on how to use jsoup, or have ideas for future development, please get in touch via [jsoup Discussions](https://github.com/jhy/jsoup/discussions).

If you find any issues, please file a [bug](https://jsoup.org/bugs) after checking for duplicates.

The [colophon](https://jsoup.org/colophon) talks about the history of and tools used to build jsoup.

## Status
jsoup is in general, stable release.


# SMS Backup+  [![Build Status SVG][]][Build Status] [![Open Source Helpers](https://www.codetriage.com/jberkel/sms-backup-plus/badges/users.svg)](https://www.codetriage.com/jberkel/sms-backup-plus)

[][Google Play Store] [][F-Droid]

---------------------
## Reporting bugs

Please read the [known issues](BUGS.md) before reporting any new issues; we already know about several significant issues, including Gmail login failures (for which there is a robust work-around), and problems with logging phone calls into calendars (which we are investigating).

---------------------
## Description

This is a fork of the now-defunct Android backup tool
[SMS Backup](http://code.google.com/p/android-sms). It uses Gmail/IMAP to perform SMS, MMS and call log backups over
the network.

Main features/improvements:

  * Restore. SMS/Call logs stored on Gmail can be transferred back to the phone.
    * ⚠ MMS are not restored.

  * Security. SMS Backup+ does not need your Gmail password.
    * Where possible, SMS Backup+ uses [XOAuth2], including when matching phone numbers against
      contact names, and writing call log records into your calendar. This access can be revoked at any time.
    * ⚠ In June 2019 Google [changed their API policy], introducing [sensitivity scopes], and
      as a result SMS Backup+ [can no longer use XOAuth2] to save messages into your mailbox;
      instead a "password" is required to access Gmail via IMAP, but it can be a generated
      [application password][Sign in using App Passwords]
      (which can be revoked without affecting your real password).

  * MMS backup support (added in version 1.1)

  * Call log backup (version 1.2), with Google Calendar integration
    (1.3) and restore (1.4).

  * Works with any IMAP server (but defaults to Gmail).

Tested with Android 4.x (Ice Cream Sandwich) - 10.x. (Q)

SMS Backup+ is available for free in the [Google Play Store] and on [F-Droid],
there will never be a pro / paid version.

But if you find the app useful and want to support its development you can make a donation
using the secure in-app Play Store payment mechanism.

To get updates more frequently join the [beta programme](#beta) or download the latest beta manually
from [Github releases].

Also make sure to read the [Privacy Policy][].

## Usage

### First steps

You need to have an IMAP account or a Gmail account with IMAP enabled. See
[Use IMAP to check Gmail on other email clients][] to learn how to enable IMAP for your Gmail
account or look at this [screenshot][imapenableshot].

After starting SMS Backup+, tap on "Connect" to start the authorization process.

👉 1.5.11: You will first have give SMS Backup+ the permission to access your account, displayed
as "Allow SMS Backup+ to access your contacts?".

If you consent you have to confirm the Gmail account to be used for the backup.

If you don't have a Google account registered on your device a browser window
will appear to perform a web-based authentication as fallback.

After completing the authorization process the "Connect"
switch should be activated, indicating success. You are now ready to perform
the first backup.

👉 1.5.11: "Connected" changed from checkbox to switch.

### Initial backup

It is important that you perform the first backup manually. SMS Backup+ needs
to know whether you want to upload messages currently stored on your device or
not.

After having connected your Gmail account, SMS Backup+ will ask you to perform
a first backup. If you choose "Backup", SMS Backup+ will start backing up all
your messages to Gmail.

If you choose "Skip", nothing is sent to Gmail and all messages currently
stored on your device are simply marked "backed up". This option is handy if
you previously uninstalled SMS Backup+ and do not want to send your messages
again to Gmail. Please note that any messages arrived after you last
uninstalled SMS Backup and this initial backup won't ever be backed up to
Gmail.

👉 1.5.11: Before the backup starts you will have to grant "send and
view" permissions for SMS.

### Restoring

If you wish to restore messages back to your phone tap "Restore". By default
all messages stored on Gmail will be restored (this can be changed in "Advanced
Settings").

👉 1.5.11: Default changed to 500 messages.

You can safely restore to a phone which has already messages stored
on it, SMS Backup+ will skip the existing messages.

Before the restore can start you will need to confirm the change of the
default SMS app. This step is required to get further permissions to write
messages (see also the corresponding [FAQ entry](#faq-restore-default-app)).

### Call log support

SMS Backup+ can also backup and restore your call logs. It stores all calls using a
separate label (defaults to `Call log`, but can be changed in "Advanced
settings"). If you wish you can set this to the same value as `SMS`, to make all
backups use the same label.

The body of the call log message contains the duration of the
call in seconds followed by the phone number and call type (`incoming` /
`outgoing` / `missed`).

An example:

    267s (00:04:07)
    +44123456789 (incoming call)

You can also add call log entries to a Google calendar. Just select `Calendar
sync` in Advanced settings, and make sure you have selected a calendar to sync
with.

If you only want to backup specific call types (incoming, outgoint etc.) you can
do so as well.

👉 1.5.11: Call log backup is disabled by default. Permissions need to be confirmed
separately for phone and calendar access.

### Rich Communication Services

[Rich Communication Services](https://en.wikipedia.org/wiki/Rich_Communication_Services) is currently not supported, nor are there any plans to support it.
Rich Communication Services is also known as _RCS_, _Advanced Messaging_, _Advanced Communications_, _joyn_ or _Message+_.

### 3rd party app integration

If you want to trigger backups from another app, enable `3rd party integration`
in Advanced Settings and send the broadcast intent
`com.zegoggles.smssync.BACKUP`. This will work even when Auto Backup is
disabled.

### Usage without Gmail (IMAP)

You don't have to use Gmail to backup your text messages - change
Authentication to "Plain text" in "Advanced settings - Custom IMAP server",
then change the server address / user name and password accordingly. Make sure
to set security to "SSL (optional / trust all)" if your IMAP server
has a self-signed certificate ("Unknown certificate" error during
backup).

👉 1.5.11: security settings have been simplified. Select TLS and check
"Trust all certificates" if using a self-signed certificate.

Also note that Gmail labels simply correspond to IMAP folders that will
automatically get created on the first backup.

## FAQ

If you don't find an answer here you can also visit the [Google+ community][] which might be able
to help.

  * [General questions](#faq-general)
    * [I want to file a bug report, what should I do?](#faq-general-file-bug-report)
    * [Can you add feature X?](#faq-general-can-you-add-feature-x)
    * [Why does it need so many permissions?](#faq-general-permissions)
    * [When updating the app I get 'Package file was not signed correctly'](#faq-general-package-not-signed)
  * [Backup questions](#faq-backup)
    * [Automatic backup does not work / stopped working](#faq-backup-automatic-backup)
    * [I get the one of following errors during backup/restore: Command: SELECT "SMS"; response:...](#faq-backup-show-imap)
    * [Only received messages are backed up, not the ones I sent](#faq-backup-only-received)
    * [How can I make the app think that it has to do the backup again?](#faq-backup-reset)
    * [Why do backed up SMS show up in my inbox?](#faq-backup-inbox)
    * [I want the backed up messages to show up in my Gmail inbox!](#faq-backup-to-inbox)
    * [What's the difference between regular and incoming backup schedule?](#faq-backup-schedule)
    * [I'd like SMS Backup+ to schedule a backup only at a given time of the day / when Wifi is available / etc.](#faq-backup-scheduling)
    * [The app saves only 100 SMS/MMS per contact!](#faq-backup-gmail-100)
    * [In Gmail, I'd like to have all messages listed chronologically and not ordered by who sent them.](#faq-backup-threading)
    * [When I delete a text locally, will it delete the saved copy on Gmail?](#faq-backup-does-it-sync)
    * [I get the error "Trust anchor for certification path not found"](#faq-backup-untrusted-certificate)
  * [Restore questions](#faq-restore)
    * [Why does SMS Backup+ ask to become the default SMS app?](#faq-restore-default-app)
    * [Are there any plans to support restoring of MMS?](#faq-restore-MMS)
    * [I'm not able to restore all of my (insert huge number) messages!](#faq-restore-many-messages)
    * [How do I restore the last N weeks / N messages?](#faq-restore-partial)
    * [The timestamps of the restored messages is wrong / the messages are not restored in the right order](#faq-restore-reversed)
  * [Authentication questions](#faq-authentication)
    * [How can I revoke the app's access to my Gmail account?](#faq-authentication-revoke-access)
    * [When connecting, I get 'Could not obtain request token...'](#faq-authentication-request-token)

### General questions

#### I want to file a bug report, what should I do?

First search [Github issues][] to see if the bug has already been reported. If not, create a new
issue and attach the following details:

 * Version of SMS Backup+ used
 * Version of Android / brand of phone used

If it is related to backing up / restoring you should also enable the sync log with
"Extra debug information" enabled (in "Advanced settings") and attach a relevant portion of it.
The sync log is stored as `sms_backup_plus.log` (in the directory `Android/data/com.zegoggles.smssync/files`).

👉 1.5.11: new log file path, was previously on external storage / sdcard.

Rather than including the log in the text of your issue description, please use the "attach
image" feature to attach your logfile _as text_ to your issue.
Alternatively, create a [gist](https://gist.github.com) and link to it from your issue description.

It might also be worth to install the [current beta version](#beta) of SMS Backup+ to
see if the bug is also present in the development version.

#### Can you add feature X?

Over the years a lot of features have been added, often as a result of
requests by users. This has worked great initially but has made the product itself very unfocussed
and generic. It started as a tool to back up text messages (as the name *SMS* Backup implies) but
gradually more and more features were added (call logs, MMS, WhatsApp...). It's now at a point where
it has become too heavy and difficult too maintain or use. The settings screen makes this obvious,
there are just too many things to configure. If anything features should be removed at this point,
not added. A more focussed product would be easier to maintain and use.

Right now, SMS Backup+ is in maintenance mode; no new features will be added. Existing bugs will of
course be addressed.

#### Why does it need so many permissions?

  * Read contacts - Needed to map phone numbers to names and email addresses
  * Your messages (read / write SMS) - Needed for backup+restore
  * Modify calendar events - needed for the call log backup to GCal
  * Send email to guests - this refers to calendar invitations (which are not created by the app)
  * Prevent phone from sleeping - needed to keep network active during a backup
  * Find accounts on the device - used for authentication
  * Use accounts on the device - used for authentication
  * Google Play billing service - used for in-app donations
  * Run at startup - used to enable automatic backups after reboot

👉 1.5.11 introduces runtime permissions (Android 6.0+) which means that you only grant the permissions
for the features you actually use, after installing the application.

#### When updating the app I get 'Package file was not signed correctly'

Try uninstalling the app, then installing the new version. Make sure to select
"Skip" when doing the first backup, otherwise messages will get backed up
twice.

### Backup questions

#### Automatic backup does not work / stopped working

If the automatic backup does not work first make sure that a manually
initiated backup works as expected.

👉 1.5.11 brings many improvements to auto-backup reliability. However some beta users have
still reported problems. If the backups don't run automatically try changing the Android
"Battery optimization" settings for SMS Backup+ to "Don't optimize".

When reporting a bug related to auto backup it is essential to attach a sync log file. See
the [relevant FAQ](#faq-general-file-bug-report) for more information on how to do this.

#### I get the one of following errors during backup/restore: Command: SELECT "SMS"; response: \#6\# \[NO, Unknown, Mailbox; SMS, \[Failure\]\] (or response: \#6\# \[NO, \[NONEXISTENT\], unknown mailbox: SMS (failure)\])

Make sure you have the "Show IMAP" option checked in the Gmail label settings:

![Screenshot][showimap]

If this is the case make sure that the label name is set correctly (capitalization
matters!).

#### How can I make the app think that it has to do the backup again?

Select "Reset" from the menu, and confirm that you want to reset the current
sync state. All messages on the phone will be backed up on the next run.

#### Only received messages are backed up, not the ones I sent

Do you use a non-standard app like Google Voice/Hangouts or Signal to send
messages? It could also be a device specific problem.
Related issues: [516][], [841][].

#### Why do backed up SMS show up in my inbox?

This is probably related to Gmail's automatic priority inbox filing.
A workaround is to set up a filter with "subject: SMS with", let the filter
mark it as not important.

![](https://raw.github.com/jberkel/sms-backup-plus/gh-pages/screenshots/20120106-tymk3rn4i5apshhr6e1hbd17qn.jpg)
![](https://raw.github.com/jberkel/sms-backup-plus/gh-pages/screenshots/20120106-rsg7912rnus5gwe3e572rxwbae.jpg)

#### I want the backed up messages to show up in my Gmail inbox!

Just set the label to "Inbox" instead of the default "SMS" or "Call log".

#### What's the difference between regular and incoming backup schedule?

Incoming backup schedule is used for incoming messages. 3 minutes here means
that any incoming SMS will trigger a backup after 3 minutes. It is a full
backup (including any sent messages). You should set the incoming schedule to a
low value if you want to make sure that incoming SMS show up in
Gmail shortly after arrival.

Regular schedule is used to perform backups in specific intervals. 2 hours here
means that the device will try to backup all messages every 2 hours.

Fewer updates performed by the app means less energy consumed, so there's
a trade-off data protection vs. battery life.

#### I'd like SMS Backup+ to schedule a backup only at a given time of the day / when Wifi is available / etc.

If you require more control over the backup schedule than what SMS Backup+ already
provides you can use a 3rd party app to trigger the backup. [Tasker][] for
example supports SMS Backup+ since version 1.0.14.

#### The app saves only 100 SMS/MMS per contact!

This seems to be a limitation of Gmail. After the first hundred or so SMS being
backed up, Gmail will cease to properly thread many of the conversations.
You will notice that Gmail will eventually treat each SMS (in that initial
backup) as individual conversations and will not longer group/thread them
together.

A way around this is to do a full backup 100 SMS at a time (see `Advanced
settings`).

#### In Gmail, I'd like to have all messages listed chronologically and not ordered by who sent them.

It's a Gmail feature, but you can disable it.
In Gmail settings, set conversation view to `off`
([screenshot][converationviewoff]).

#### When I delete a text locally, will it delete the saved copy on Gmail?

No. SMS Backup+ does not do a "real" sync, once the text has been transferred
to Gmail it won't get modified or deleted by the app.

#### I get the error "Trust anchor for certification path not found"

This means that it is impossible to establish a trusted connection with the IMAP server. A few
reasons why this might happen:

  * You run on an ancient version of Android
  * You use an IMAP server with an expired or self-signed certificate

You can try to set the IMAP Server Setting `Security` to `SSL (optional / trust all)`.

👉 1.5.11: Added "Trust all certificates" option

### Restore questions

#### Why does SMS Backup+ ask to become the default SMS app?

Google has changed the way SMS permissions work starting with Android 4.4
(KitKat). In order to get write access to your messages an app has to be set as
the default system SMS app. Before starting the restore operation SMS Backup+
will request your permission to be set as default app. After restoring you will
be asked to set the previous choice (usually "Messaging") back as default.
⚠ This last step is important, if you don't set the old default back you might
lose new messages.

#### Are there any plans to support restoring of MMS?

No, for a variety of reasons: MMS are highly carrier-dependent, documentation is lacking and the
Android Emulator does not support them.

However SMS Backup+ is open source; patches are more than welcome.

#### I'm not able to restore all of my (insert huge number) messages!

SMS Backup has not been designed to restore many thousands of messages. See the
question "[How do I restore the last N weeks / N messages?](#faq-restore-partial)" for a way around that.

#### How do I restore the last N weeks / N messages?

If you have a lot of messages backed up (let's say over 5000) restoring can be
very slow, especially if you're only interested in the most recent messages.

A workaround is to use the Gmail web interface (or an IMAP email client) to
move the bulk of the messages to another label in Gmail (e.g. SMSARCHIVED), and
only keep a few hundred or so messages in the SMS label.

Next time you restore it will only restore those messages and it will be a lot
faster.

### Authentication questions

#### How can I revoke the app's access to my Gmail account?

Go to [Authorized Access to your Google Account][] and select "Remove Access"
next to "SMS Backup+".

#### When connecting, I get 'Could not obtain request token...'

If you get this error message and your network connection is active
double-check that your time zone settings are correct, and that the local time is
displaying correctly. The authentication process won't work otherwise.

## Beta testing

If you want to help beta testing, visit the [Play Store beta page]. You will be asked to opt in
to the beta program (you can leave it anytime).

Once opted in your device will automatically update to the latest beta which might have bug fixes
and features not found in the currently released version.

Alternatively you can download an APK from [Github releases][] and install it manually
(⚠ you won't get automatic updates this way). You can also install via [F-Droid][]
which often has more recent versions than what is available on the Play Store.

## Contributing

### Installation from source

    $ git clone https://github.com/jberkel/sms-backup-plus.git
    $ cd sms-backup-plus
    $ ./gradlew assembleDebug
    $ adb install app/build/outputs/apk/app-debug.apk

### Translating the UI

If you want to help translating the UI to other languages download and
translate the following file, then send the translated version via email:

  * [strings.xml][]

However, if you're already familiar with Git you can just clone the
repository and submit a [pull request][About pull requests].

## Credits

  * [Christoph Studer](http://studer.tv/) Original author of SMS Backup (2009-2010)
  * [Ben Dodson](https://github.com/bjdodson) - Contacts 2.0 / MMS support
  * [Felix Knecht](https://github.com/dicer) - Call log backup code
  * [Michael Scharfstein](https://github.com/smike) - Call log calendar ICS support
  * [K-9 Mail](https://github.com/k9mail/k-9/) IMAP library, with some modifications ([k-9/sms-backup-plus](https://github.com/jberkel/k-9/tree/sms-backup-plus))
  * [signpost](https://github.com/mttkay/signpost) Matthias Käppler, Signpost OAuth library
  * Shimon Simon (new icon designs)
  * [bbs.goapk.com](http://bbs.goapk.com) / [Chen Ma](https://github.com/marcher233), [Aaron LI](https://github.com/liweitianux) - Chinese translation
  * [Leszek Ciesielski](https://github.com/skolima) - Polish translation
  * Roberto Elena Ormad - Spanish translation
  * Gabriele Ravanetti / [Patryk Rzucidlo](http://www.ptkdev.it/) / [Chiara De Liberato](http://www.chiaradeliberato.it/) - Italian translation
  * Harun Şahin - Turkish translation
  * [Lukas Pribyl](http://www.lukaspribyl.eu) - Czech translation
  * João Pedro Ferreira - Portuguese translation
  * Martijn Brouns, [Niko Strijbol](https://github.com/niknetniko) - Dutch translation
  * [Torbe](https://github.com/Torbe) - Norwegian translation
  * Nemanja Bračko, [Mladen Pejaković](https://github.com/pejakm) - Serbian translation
  * [Markus Osanger](https://github.com/mosanger) - German translation
  * Dimitris / Mazin Hussein - Greek translation
  * [Yunsu Choi](https://github.com/YunsuChoi), [Taegil Bae](https://github.com/demokritos) - Korean translation
  * [Javier Pico](https://github.com/javierpico) - Galician translation
  * [Ferran Rius](https://github.com/Ferri64) - Catalan translation
  * [Mads Andreasen](https://github.com/MadsAndreasen) - Danish translation, initial JobDispatcher code
  * sHa - Ukrainian translation
  * [Erik Eloff](https://github.com/Loffe/) - Swedish translation
  * [Matrix44](https://github.com/Matrix44) - Slovak translation
  * [László Gárdonyi](https://github.com/gLes) - Hungarian translation
  * Petr P. Gornostaev, [saratovout](https://github.com/saratovout) - Russian translation

## Screenshots

### 1.5.11

![SMS Backup+ material][smsbackup_screenshot_material]

### 1.5.10

![SMS Backup+ holo][smsbackup_screenshot_holo]

## License

This application is released under the terms of the [Apache License, Version 2.0][].

[Build Status]: http://travis-ci.com/jberkel/sms-backup-plus
[Build Status SVG]: https://api.travis-ci.com/jberkel/sms-backup-plus.svg?branch=master

[XOAuth2]: https://developers.google.com/gmail/imap/xoauth2-protocol
[changed their API policy]: https://cloud.google.com/blog/products/g-suite/elevating-user-trust-in-our-api-ecosystems
[sensitivity scopes]: https://developers.google.com/gmail/api/auth/scopes
[can no longer use XOAuth2]: https://arstechnica.com/gadgets/2019/06/gmails-api-lockdown-will-kill-some-third-party-app-access-starting-july-15/

[GitHub Community Guidelines]: https://help.github.com/en/articles/github-community-guidelines
[Android Police article]: https://www.androidpolice.com/2019/08/12/sms-backup-is-now-broken-due-to-gmails-api-changes-but-theres-a-workaround/
[Sign in using App Passwords]: https://support.google.com/accounts/answer/185833?hl=en

[Google Play Store]: https://play.google.com/store/apps/details?id=com.zegoggles.smssync
[F-Droid]: https://f-droid.org/packages/com.zegoggles.smssync/

[Use IMAP to check Gmail on other email clients]: https://support.google.com/mail/answer/7126229?hl=en
[converationviewoff]: https://raw.github.com/jberkel/sms-backup-plus/gh-pages/screenshots/soundcloud.com-mail-settings-jan-soundcloud.com.jpg
[imapenableshot]: https://raw.github.com/jberkel/sms-backup-plus/gh-pages/screenshots/enable_imap.png
[showimap]: https://raw.github.com/jberkel/sms-backup-plus/gh-pages/screenshots/show_imap.png
[strings.xml]: https://github.com/jberkel/sms-backup-plus/raw/master/app/src/main/res/values/strings.xml
[Tasker]: https://tasker.joaoapps.com/
[Authorized Access to your Google Account]: https://security.google.com/settings/security/permissions
[Google+ community]: https://plus.google.com/communities/113290889178902750997
[Play Store beta page]: https://play.google.com/apps/testing/com.zegoggles.smssync
[Github releases]: https://github.com/jberkel/sms-backup-plus/releases
[Github issues]: http://github.com/jberkel/sms-backup-plus/issues
[About pull requests]: https://help.github.com/articles/about-pull-requests/

[smsbackup_screenshot_holo]: https://raw.github.com/jberkel/sms-backup-plus/gh-pages/screenshots/smsbackup_holo_cropped.png
[smsbackup_screenshot_material]: https://raw.github.com/jberkel/sms-backup-plus/gh-pages/screenshots/smsbackup_material_cropped.png

[Apache License, Version 2.0]: http://www.apache.org/licenses/LICENSE-2.0.html
[Privacy Policy]: https://jberkel.github.io/sms-backup-plus/privacy-policy/

[516]: https://github.com/jberkel/sms-backup-plus/issues/516
[564]: https://github.com/jberkel/sms-backup-plus/issues/564
[841]: https://github.com/jberkel/sms-backup-plus/issues/841


# ANTLR v4

[![Java 11+](https://img.shields.io/badge/java-11+-4c7e9f.svg)](http://java.oracle.com)
[![License](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/antlr/antlr4/master/LICENSE.txt)

**ANTLR** (ANother Tool for Language Recognition) is a powerful parser generator for reading, processing, executing, or translating structured text or binary files. It's widely used to build languages, tools, and frameworks. From a grammar, ANTLR generates a parser that can build parse trees and also generates a listener interface (or visitor) that makes it easy to respond to the recognition of phrases of interest.

**Dev branch build status**

[![MacOSX, Windows, Linux](https://github.com/antlr/antlr4/actions/workflows/hosted.yml/badge.svg)](https://github.com/antlr/antlr4/actions/workflows/hosted.yml) (github actions)

## Versioning

ANTLR 4 supports 10 target languages
(Cpp, CSharp, Dart, Java, JavaScript, PHP, Python3, Swift, TypeScript, Go),
and ensuring consistency across these targets is a unique and highly valuable feature.
To ensure proper support of this feature, each release of ANTLR is a complete release of the tool and the 10 runtimes, all with the same version.
As such, ANTLR versioning does not strictly follow semver semantics:

* a component may be released with the latest version number even though nothing has changed within that component since the previous release
* major version is bumped only when ANTLR is rewritten for a totally new "generation", such as ANTLR3 -> ANTLR4 (LL(\*) -> ALL(\*) parsing)
* minor version updates may include minor breaking changes, the policy is to regenerate parsers with every release (4.11 -> 4.12)
* backwards compatibility is only guaranteed for patch version bumps (4.11.1 -> 4.11.2)

If you use a semver verifier in your CI, you probably want to apply special rules for ANTLR, such as treating minor change as a major change.

## Repo branch structure

The default branch for this repo is [`master`](https://github.com/antlr/antlr4/tree/master), which is the latest stable release and has tags for the various releases; e.g., see release tag [4.9.3](https://github.com/antlr/antlr4/tree/4.9.3).  Branch [`dev`](https://github.com/antlr/antlr4/tree/dev) is where development occurs between releases and all pull requests should be derived from that branch. The `dev` branch is merged back into `master` to cut a release and the release state is tagged (e.g., with `4.10-rc1` or `4.10`.) Visually our process looks roughly like this:

The Go target now has its own dedicated repo:

```bash
$ go get github.com/antlr4-go/antlr
```
**Note**
The dedicated Go repo is for `go get` and `import` only. Go runtime development is still performed in the main `antlr/antlr4` repo.

## Authors and major contributors

* [Terence Parr](http://www.cs.usfca.edu/~parrt/), parrt@cs.usfca.edu
ANTLR project lead and supreme dictator for life
[University of San Francisco](http://www.usfca.edu/)
* [Sam Harwell](http://tunnelvisionlabs.com/) (Tool co-author, Java and original C# target)
* [Eric Vergnaud](https://github.com/ericvergnaud) (Javascript, TypeScript, Python2, Python3 targets and maintenance of C# target)
* [Peter Boyer](https://github.com/pboyer) (Go target)
* [Mike Lischke](http://www.soft-gems.net/) (C++ completed target)
* Dan McLaughlin (C++ initial target)
* David Sisson (C++ initial target and test)
* [Janyou](https://github.com/janyou) (Swift target)
* [Ewan Mellor](https://github.com/ewanmellor), [Hanzhou Shi](https://github.com/hanjoes) (Swift target merging)
* [Ben Hamilton](https://github.com/bhamiltoncx) (Full Unicode support in serialized ATN and all languages' runtimes for code points > U+FFFF)
* [Marcos Passos](https://github.com/marcospassos) (PHP target)
* [Lingyu Li](https://github.com/lingyv-li) (Dart target)
* [Ivan Kochurkin](https://github.com/KvanTTT) has made major contributions to overall quality, error handling, and Target performance.
* [Justin King](https://github.com/jcking) has done a huge amount of work across multiple targets, but especially for C++.
* [Ken Domino](https://github.com/kaby76) has a knack for finding bugs/issues and analysis; also a major contributor on the [grammars-v4 repo](https://github.com/antlr/grammars-v4).
* [Jim Idle](https://github.com/jimidle) has contributed to previous versions of ANTLR and recently jumped back in to solve a major problem with the Go target.

## Useful information

* [Release notes](https://github.com/antlr/antlr4/releases)
* [Getting started with v4](https://github.com/antlr/antlr4/blob/master/doc/getting-started.md)
* [Official site](http://www.antlr.org/)
* [Documentation](https://github.com/antlr/antlr4/blob/master/doc/index.md)
* [FAQ](https://github.com/antlr/antlr4/blob/master/doc/faq/index.md)
* [ANTLR code generation targets](https://github.com/antlr/antlr4/blob/master/doc/targets.md)
(Currently: Java, C#, Python3, JavaScript, TypeScript, Go, C++, Swift, Dart, PHP)
* _Note: As of version 4.14, we are dropping support for Python 2. We love the Python
community, but Python 2 support was officially halted in Jan 2020. More recently,
GiHub also dropped support for Python 2, which has made it impossible for us to
maintain a consistent level of quality across targets (we use GitHub for our CI).
Long live Python 3!_
* [Java API](http://www.antlr.org/api/Java/index.html)
* [ANTLR v3](http://www.antlr3.org/)
* [v3 to v4 Migration, differences](https://github.com/antlr/antlr4/blob/master/doc/faq/general.md)

You might also find the following pages useful, particularly if you want to mess around with the various target languages.

* [How to build ANTLR itself](https://github.com/antlr/antlr4/blob/master/doc/building-antlr.md)
* [How we create and deploy an ANTLR release](https://github.com/antlr/antlr4/blob/master/doc/releasing-antlr.md)

## The Definitive ANTLR 4 Reference

Programmers run into parsing problems all the time. Whether it’s a data format like JSON, a network protocol like SMTP, a server configuration file for Apache, a PostScript/PDF file, or a simple spreadsheet macro language—ANTLR v4 and this book will demystify the process. ANTLR v4 has been rewritten from scratch to make it easier than ever to build parsers and the language applications built on top. This completely rewritten new edition of the bestselling Definitive ANTLR Reference shows you how to take advantage of these new features.

You can buy the book [The Definitive ANTLR 4 Reference](http://amzn.com/1934356999) at amazon or an [electronic version at the publisher's site](https://pragprog.com/book/tpantlr2/the-definitive-antlr-4-reference).

You will find the [Book source code](http://pragprog.com/titles/tpantlr2/source_code) useful.

## Additional grammars
[This repository](https://github.com/antlr/grammars-v4) is a collection of grammars without actions where the
root directory name is the all-lowercase name of the language parsed
by the grammar. For example, java, cpp, csharp, c, etc...


Java WebSockets
===============
[![Build Status](https://travis-ci.org/marci4/Java-WebSocket-Dev.svg?branch=master)](https://travis-ci.org/marci4/Java-WebSocket-Dev)
[![Javadocs](https://www.javadoc.io/badge/org.java-websocket/Java-WebSocket.svg)](https://www.javadoc.io/doc/org.java-websocket/Java-WebSocket)
[![Maven Central](https://img.shields.io/maven-central/v/org.java-websocket/Java-WebSocket.svg)](https://mvnrepository.com/artifact/org.java-websocket/Java-WebSocket)

This repository contains a barebones WebSocket server and client implementation
written in 100% Java. The underlying classes are implemented `java.nio`, which allows for a
non-blocking event-driven model (similar to the
[WebSocket API](https://html.spec.whatwg.org/multipage/web-sockets.html) for web browsers).

Implemented WebSocket protocol versions are:

 * [RFC 6455](http://tools.ietf.org/html/rfc6455)
 * [RFC 7692](http://tools.ietf.org/html/rfc7692)

[Here](https://github.com/TooTallNate/Java-WebSocket/wiki/Drafts) some more details about protocol versions/drafts.
[PerMessageDeflateExample](https://github.com/TooTallNate/Java-WebSocket/wiki/PerMessageDeflateExample) enable the extension with reference to both a server and client example.

## Getting Started

### Dependency management tools

Below is a brief guide to using dependency management tools like maven or gradle.

#### Maven
To use maven add this dependency to your pom.xml:
```xml
<dependency>
  <groupId>org.java-websocket</groupId>
  <artifactId>Java-WebSocket</artifactId>
  <version>1.5.6</version>
</dependency>
```

#### Gradle
To use Gradle add the maven central repository to your repositories list:
```xml
mavenCentral()
```
Then you can just add the latest version to your build.
```xml
compile "org.java-websocket:Java-WebSocket:1.5.6"
```
Or this option if you use gradle 7.0 and above.
```xml
implementation 'org.java-websocket:Java-WebSocket:1.5.6'
```

#### Logging

This library uses [SLF4J](https://www.slf4j.org/) for logging and does not ship with any default logging implementation.

Exceptions are using the log level `ERROR` and debug logging will be done with log level `TRACE`.

Feel free to use whichever logging framework you desire and use the corresponding [binding](https://mvnrepository.com/artifact/org.slf4j) in your dependency management.

If you want to get started, take a look at the SimpleLogger [example](https://github.com/TooTallNate/Java-WebSocket/wiki/SimpleLogger-example).

### Standalone jar

If you do not use any dependency management tool, you can find the latest standalone jar [here](https://github.com/TooTallNate/Java-WebSocket/releases/latest).

Writing your own WebSocket Server
---------------------------------

The `org.java_websocket.server.WebSocketServer` abstract class implements the
server-side of the
[WebSocket Protocol](http://www.whatwg.org/specs/web-socket-protocol/).
A WebSocket server by itself doesn't do anything except establish socket
connections though HTTP. After that it's up to **your** subclass to add purpose.

An example for a WebSocketServer can be found in both the [wiki](https://github.com/TooTallNate/Java-WebSocket/wiki#server-example) and the [example](https://github.com/TooTallNate/Java-WebSocket/tree/master/src/main/example) folder.

Writing your own WebSocket Client
---------------------------------

The `org.java_websocket.client.WebSocketClient` abstract class can connect to
valid WebSocket servers. The constructor expects a valid `ws://` URI to
connect to. Important events `onOpen`, `onClose`, `onMessage` and `onError`
get fired throughout the life of the WebSocketClient, and must be implemented
in **your** subclass.

An example for a WebSocketClient can be found in both the [wiki](https://github.com/TooTallNate/Java-WebSocket/wiki#client-example) and the [example](https://github.com/TooTallNate/Java-WebSocket/tree/master/src/main/example) folder.

Examples
-------------------

You can find a lot of examples [here](https://github.com/TooTallNate/Java-WebSocket/tree/master/src/main/example).

WSS Support
---------------------------------
This library supports wss.
To see how to use wss please take a look at the examples.

If you do not have a valid **certificate** in place then you will have to create a self signed one.
Browsers will simply refuse the connection in case of a bad certificate and will not ask the user to accept it.
So the first step will be to make a browser to accept your self signed certificate. ( https://bugzilla.mozilla.org/show_bug.cgi?id=594502 ).

If the websocket server url is `wss://localhost:8000` visit the url `https://localhost:8000` with your browser. The browser will recognize the handshake and allow you to accept the certificate.

The vm option `-Djavax.net.debug=all` can help to find out if there is a problem with the certificate.

It is currently not possible to accept ws and wss connections at the same time via the same websocket server instance.

For some reason Firefox does not allow multiple connections to the same wss server if the server uses a different port than the default port (443).

If you want to use `wss` on the android platform you should take a look at [this](https://github.com/TooTallNate/Java-WebSocket/wiki/FAQ:-Secure-WebSockets#wss-on-android).

I ( @Davidiusdadi ) would be glad if you would give some feedback whether wss is working fine for you or not.

Minimum Required JDK
--------------------

`Java-WebSocket` is known to work with:

 * Java 1.7 and higher

Other JRE implementations may work as well, but haven't been tested.

License
-------

Everything found in this repo is licensed under an MIT license. See
the `LICENSE` file for specifics.