Full Code of cloudinary/cloudinary_java for AI

master d836d6ee9a5f cached
199 files
1.2 MB
291.4k tokens
2001 symbols
1 requests
Download .txt
Showing preview only (1,336K chars total). Download the full file or copy to clipboard to get everything.
Repository: cloudinary/cloudinary_java
Branch: master
Commit: d836d6ee9a5f
Files: 199
Total size: 1.2 MB

Directory structure:
gitextract_fmnzldsh/

├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   ├── pull_request_template.md
│   └── workflows/
│       └── build.yml
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── MAVEN_CENTRAL_PUBLISHING_GUIDE.md
├── README.md
├── build.gradle
├── cloudinary-core/
│   ├── build.gradle
│   └── src/
│       ├── main/
│       │   └── java/
│       │       ├── com/
│       │       │   └── cloudinary/
│       │       │       ├── AccessControlRule.java
│       │       │       ├── Api.java
│       │       │       ├── ArchiveParams.java
│       │       │       ├── AuthToken.java
│       │       │       ├── BaseParam.java
│       │       │       ├── Cloudinary.java
│       │       │       ├── Configuration.java
│       │       │       ├── Coordinates.java
│       │       │       ├── CustomFunction.java
│       │       │       ├── EagerTransformation.java
│       │       │       ├── ProgressCallback.java
│       │       │       ├── ResponsiveBreakpoint.java
│       │       │       ├── Search.java
│       │       │       ├── SearchFolders.java
│       │       │       ├── SignatureAlgorithm.java
│       │       │       ├── SmartUrlEncoder.java
│       │       │       ├── StoredFile.java
│       │       │       ├── Transformation.java
│       │       │       ├── Uploader.java
│       │       │       ├── Url.java
│       │       │       ├── Util.java
│       │       │       ├── api/
│       │       │       │   ├── ApiResponse.java
│       │       │       │   ├── AuthorizationRequired.java
│       │       │       │   ├── RateLimit.java
│       │       │       │   ├── exceptions/
│       │       │       │   │   ├── AlreadyExists.java
│       │       │       │   │   ├── ApiException.java
│       │       │       │   │   ├── BadRequest.java
│       │       │       │   │   ├── GeneralError.java
│       │       │       │   │   ├── NotAllowed.java
│       │       │       │   │   ├── NotFound.java
│       │       │       │   │   └── RateLimited.java
│       │       │       │   └── signing/
│       │       │       │       ├── ApiResponseSignatureVerifier.java
│       │       │       │       ├── NotificationRequestSignatureVerifier.java
│       │       │       │       ├── SignedPayloadValidator.java
│       │       │       │       └── package-info.java
│       │       │       ├── metadata/
│       │       │       │   ├── DateMetadataField.java
│       │       │       │   ├── EnumMetadataField.java
│       │       │       │   ├── IntMetadataField.java
│       │       │       │   ├── MetadataDataSource.java
│       │       │       │   ├── MetadataField.java
│       │       │       │   ├── MetadataFieldType.java
│       │       │       │   ├── MetadataRule.java
│       │       │       │   ├── MetadataRuleCondition.java
│       │       │       │   ├── MetadataRuleResult.java
│       │       │       │   ├── MetadataValidation.java
│       │       │       │   ├── Restrictions.java
│       │       │       │   ├── SetMetadataField.java
│       │       │       │   └── StringMetadataField.java
│       │       │       ├── provisioning/
│       │       │       │   ├── Account.java
│       │       │       │   └── AccountConfiguration.java
│       │       │       ├── strategies/
│       │       │       │   ├── AbstractApiStrategy.java
│       │       │       │   ├── AbstractUploaderStrategy.java
│       │       │       │   └── StrategyLoader.java
│       │       │       ├── transformation/
│       │       │       │   ├── AbstractLayer.java
│       │       │       │   ├── BaseExpression.java
│       │       │       │   ├── Condition.java
│       │       │       │   ├── Expression.java
│       │       │       │   ├── FetchLayer.java
│       │       │       │   ├── Layer.java
│       │       │       │   ├── SubtitlesLayer.java
│       │       │       │   └── TextLayer.java
│       │       │       └── utils/
│       │       │           ├── Analytics.java
│       │       │           ├── Base64Coder.java
│       │       │           ├── Base64Map.java
│       │       │           ├── HtmlEscape.java
│       │       │           ├── ObjectUtils.java
│       │       │           ├── Rectangle.java
│       │       │           └── StringUtils.java
│       │       └── org/
│       │           └── cloudinary/
│       │               └── json/
│       │                   ├── JSONArray.java
│       │                   ├── JSONException.java
│       │                   ├── JSONObject.java
│       │                   ├── JSONString.java
│       │                   └── JSONTokener.java
│       └── test/
│           └── java/
│               └── com/
│                   └── cloudinary/
│                       ├── AuthTokenTest.java
│                       ├── TransformationTest.java
│                       ├── UtilTest.java
│                       ├── analytics/
│                       │   └── AnalyticsTest.java
│                       ├── api/
│                       │   └── signing/
│                       │       ├── ApiResponseSignatureVerifierTest.java
│                       │       └── NotificationRequestSignatureVerifierTest.java
│                       ├── test/
│                       │   └── CloudinaryTest.java
│                       └── transformation/
│                           ├── ExpressionTest.java
│                           └── LayerTest.java
├── cloudinary-http5/
│   ├── build.gradle
│   └── src/
│       ├── main/
│       │   └── java/
│       │       └── com/
│       │           └── cloudinary/
│       │               └── http5/
│       │                   ├── ApiStrategy.java
│       │                   ├── ApiUtils.java
│       │                   ├── UploaderStrategy.java
│       │                   └── api/
│       │                       └── Response.java
│       └── test/
│           └── java/
│               └── com/
│                   └── cloudinary/
│                       └── test/
│                           ├── AccountApiTest.java
│                           ├── ApiTest.java
│                           ├── ContextTest.java
│                           ├── FoldersApiTest.java
│                           ├── SearchTest.java
│                           ├── StreamingProfilesApiTest.java
│                           ├── StructuredMetadataTest.java
│                           └── UploaderTest.java
├── cloudinary-taglib/
│   ├── build.gradle
│   └── src/
│       └── main/
│           ├── java/
│           │   └── com/
│           │       └── cloudinary/
│           │           ├── Singleton.java
│           │           ├── SingletonManager.java
│           │           └── taglib/
│           │               ├── CloudinaryImageTag.java
│           │               ├── CloudinaryJsConfigTag.java
│           │               ├── CloudinaryJsIncludeTag.java
│           │               ├── CloudinaryTransformationTag.java
│           │               ├── CloudinaryUnsignedUploadTag.java
│           │               ├── CloudinaryUploadTag.java
│           │               ├── CloudinaryUrl.java
│           │               └── CloudinaryVideoTag.java
│           └── resources/
│               └── META-INF/
│                   └── cloudinary.tld
├── cloudinary-test-common/
│   ├── build.gradle
│   └── src/
│       └── main/
│           ├── java/
│           │   └── com/
│           │       └── cloudinary/
│           │           └── test/
│           │               ├── AbstractAccountApiTest.java
│           │               ├── AbstractApiTest.java
│           │               ├── AbstractContextTest.java
│           │               ├── AbstractFoldersApiTest.java
│           │               ├── AbstractSearchTest.java
│           │               ├── AbstractStreamingProfilesApiTest.java
│           │               ├── AbstractStructuredMetadataTest.java
│           │               ├── AbstractUploaderTest.java
│           │               ├── MetadataTestHelper.java
│           │               ├── MockableTest.java
│           │               ├── TimeoutTest.java
│           │               ├── helpers/
│           │               │   └── Feature.java
│           │               └── rules/
│           │                   └── RetryRule.java
│           └── resources/
│               ├── docx.docx
│               └── אבג.docx
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── java_shared.gradle
├── publish.gradle
├── samples/
│   ├── photo_album/
│   │   ├── META-INF/
│   │   │   └── persistence.xml
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cloudinary/
│   │           │       ├── controllers/
│   │           │       │   └── PhotoController.java
│   │           │       ├── lib/
│   │           │       │   └── PhotoUploadValidator.java
│   │           │       ├── models/
│   │           │       │   ├── Photo.java
│   │           │       │   └── PhotoUpload.java
│   │           │       └── repositories/
│   │           │           └── PhotoRepository.java
│   │           ├── resources/
│   │           │   └── META-INF/
│   │           │       └── persistence.xml
│   │           └── webapp/
│   │               ├── WEB-INF/
│   │               │   ├── messages.properties
│   │               │   ├── mvc-dispatcher-servlet.xml
│   │               │   ├── pages/
│   │               │   │   ├── direct_upload_form.jsp
│   │               │   │   ├── photos.jsp
│   │               │   │   ├── post.jsp
│   │               │   │   ├── pre.jsp
│   │               │   │   ├── upload.jsp
│   │               │   │   └── upload_form.jsp
│   │               │   └── web.xml
│   │               └── assets/
│   │                   ├── cloudinary_cors.html
│   │                   ├── javascripts/
│   │                   │   └── cloudinary/
│   │                   │       ├── jquery.cloudinary.js
│   │                   │       ├── jquery.fileupload-image.js
│   │                   │       ├── jquery.fileupload-process.js
│   │                   │       ├── jquery.fileupload-validate.js
│   │                   │       ├── jquery.fileupload.js
│   │                   │       ├── jquery.iframe-transport.js
│   │                   │       └── jquery.ui.widget.js
│   │                   └── stylesheets/
│   │                       └── application.css
│   └── photo_album_gae/
│       ├── META-INF/
│       │   └── persistence.xml
│       ├── README.md
│       ├── nbactions.xml
│       ├── pom.xml
│       └── src/
│           └── main/
│               ├── java/
│               │   ├── cloudinary/
│               │   │   ├── controllers/
│               │   │   │   └── PhotoController.java
│               │   │   ├── lib/
│               │   │   │   └── PhotoUploadValidator.java
│               │   │   └── models/
│               │   │       └── PhotoUpload.java
│               │   └── org/
│               │       └── esxx/
│               │           └── js/
│               │               └── protocol/
│               │                   ├── GAEClientConnection.java
│               │                   └── GAEConnectionManager.java
│               └── webapp/
│                   ├── WEB-INF/
│                   │   ├── appengine-web.xml.sample
│                   │   ├── logging.properties
│                   │   ├── messages.properties
│                   │   ├── mvc-dispatcher-servlet.xml
│                   │   ├── pages/
│                   │   │   ├── direct_upload_form.jsp
│                   │   │   ├── photos.jsp
│                   │   │   ├── post.jsp
│                   │   │   ├── pre.jsp
│                   │   │   ├── upload.jsp
│                   │   │   └── upload_form.jsp
│                   │   └── web.xml
│                   └── assets/
│                       ├── cloudinary_cors.html
│                       ├── javascripts/
│                       │   └── cloudinary/
│                       │       ├── jquery.cloudinary.js
│                       │       ├── jquery.fileupload-image.js
│                       │       ├── jquery.fileupload-process.js
│                       │       ├── jquery.fileupload-validate.js
│                       │       ├── jquery.fileupload.js
│                       │       ├── jquery.iframe-transport.js
│                       │       └── jquery.ui.widget.js
│                       └── stylesheets/
│                           └── application.css
├── settings.gradle
└── tools/
    └── update_version.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

## Bug report for Cloudinary Java SDK
Before proceeding, please update to latest version and test if the issue persists

## Describe the bug in a sentence or two.
…

## Issue Type (Can be multiple)
[ ] Build - Can’t install or import the SDK
[ ] Performance - Performance issues
[ ] Behaviour - Functions aren’t working as expected (Such as generate URL)
[ ] Documentation - Inconsistency between the docs and behaviour
[ ] Other (Specify)

## Steps to reproduce
… if applicable

## Error screenshots or Stack Trace (if applicable)
…

## Build System
[ ] Maven
[ ] Gradle
[ ] Other (Specify)

## OS (Please specify version)
[ ] Windows
[ ] Linux
[ ] Mac
[ ] Other (specify)

## Versions and Libraries (fill in the version numbers)
Cloudinary Java SDK version - 0.0.0
JVM (dev environment) - 0.0.0
JVM (production environment) - 0.0.0
Maven - 0.0.0 / N/A
Gradle - 0.0.0 / N/A

## Repository
If possible, please provide a link to a reproducible repository that showcases the problem


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''

---

## Feature request for Cloudinary Java SDK
…(If your feature is for other SDKs, please request them there)


## Explain your use case
… (A high level explanation of why you need this feature)

## Describe the problem you’re trying to solve
… (A more technical view of what you’d like to accomplish, and how this feature will help you achieve it)

## Do you have a proposed solution?
… (yes, no? Please elaborate if needed)


================================================
FILE: .github/pull_request_template.md
================================================
### Brief Summary of Changes
<!-- Provide some context as to what was changed, from an implementation standpoint. -->

#### What does this PR address?
- [ ] GitHub issue (Add reference - #XX)
- [ ] Refactoring
- [ ] New feature
- [ ] Bug fix
- [ ] Adds more tests

#### Are tests included?
- [ ] Yes
- [ ] No

#### Reviewer, please note:
<!--
List anything here that the reviewer should pay special attention to. This might
include, for example:
* Dependence on other PRs
* Reference to other Cloudinary SDKs
* Changes that seem arbitrary without further explanations
-->

#### Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
- [ ] My code follows the code style of this project.
- [ ] My change requires a change to the documentation.
- [ ] I ran the full test suite before pushing the changes and all the tests pass.


================================================
FILE: .github/workflows/build.yml
================================================
name: Java SDK Matrix CI

on:
  push:
    branches-ignore:
      - staging-test
  pull_request:

jobs:
  build:
    name: Test ${{ matrix.module }} on JDK ${{ matrix.java }}
    runs-on: ubuntu-latest

    strategy:
      matrix:
        java: ['8']
        module: [ 'core', 'http5', 'taglib' ]

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up JDK ${{ matrix.java }}
        uses: actions/setup-java@v4
        with:
          distribution: 'adopt'
          java-version: ${{ matrix.java }}

      - name: Clean Gradle plugin cache
        run: |
          rm -f  $HOME/.gradle/caches/modules-2/modules-2.lock
          rm -fr $HOME/.gradle/caches/*/plugin-resolution/

      - name: Cache Gradle
        uses: actions/cache@v4
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-${{ matrix.java }}-${{ matrix.module }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: |
            ${{ runner.os }}-gradle-

      - name: Create test subaccount
        run: ./gradlew createTestSubAccount -PmoduleName=${{ matrix.module }}

      - name: Load CLOUDINARY_URL and run ciTest
        run: |
          source tools/cloudinary_url.txt
          ./gradlew -DCLOUDINARY_URL=$CLOUDINARY_URL ciTest -p cloudinary-${{ matrix.module }} -i

================================================
FILE: .gitignore
================================================
## Apple storage files
*.DS_Store

## Android default ignore
# Built application files
*.apk
*.ap_

# Files for the Dalvik VM
*.dex

# Java class files
*.class

# Generated files
bin/
gen/

# Gradle files
.gradle/
build/
/*/build/

# Local configuration file (sdk path, etc)
local.properties

# Proguard folder generated by Eclipse
proguard/

# Log Files
*.log

target/
test-output/
.settings
.classpath
.project

# intellij
.idea/
*.iml

appengine-web.xml
cloudinary-android/src/androidTest/AndroidManifest.xml

##Tools
/tools/cloudinary_url.txt
/tools/History.md



================================================
FILE: CHANGELOG.md
================================================
2.3.1 / 2025-08-13
==================

* Bump dependencies version

2.3.0 / 2025-06-18
==================
* Fix API parameters signature
* Fix build single resource params
* Add skip backup parameter to delete folder api

2.2.0 / 2025-02-02
==================

* Fix Uploader strategy
* Add restore assets by asset ids
* Add allow dynamic list parameter
* Add delete resources by asset ids

2.1.0 / 2025-01-20
==================

* Fix Http client proxy
* Fix Http client system properties support
* Add Cloudinary constructor for `Configuration`
* Fix Register strategy functions

2.0.0 / 2024-09-29
==================

* Bump minimum Java version to 8
* Secure true by default
* Add `auto_chaptering` and `auto_transcription` to upload API
* New Http client
* Add support for update metadata field set default disabled

1.39.0 / 2024-07-14
===================

* Add conditional metadata rules api
* Fix rename folder endpoint
* Add config api call
* Add delete backup asset version support
* Add rename folder api support
* Add analyze api
* Add selective response support
* Add access key management
* Add restrictions field to metadata 

1.38.0 / 2024-02-18
===================

* Add `notification_url` support to rename and destroy

1.37.0 / 2024-01-14
===================

* Update analytics token
* Add missing display name parameter

1.36.0 / 2023-12-04
===================

* Fix encode url for fetch layer
* Add support to use fetch format

1.35.0 / 2023-10-11
===================

  * Update analytics token
  * Add support for `on_success` upload parameter

1.34.0 / 2023-08-08
===================

  * Add visual search support
  * Add `toUrl() to Search API
  * Add Search folders functionality
  * Update Hyper SQL version
  * Add support for `media_metadata` parameter
  * Add support for `clear_invalid` parameter

1.33.0 / 2022-09-12
==================

* Add dynamic folders support
* Fix VideoTag not appending auth token
* Fix upload with Unicode character not appending a file extension
* Bump springboard version


1.32.2 / 2022-05-10
===================

  * Fix nexus publishing script

1.32.1 / 2022-04-25
===================

  * Fix double underscore handling during normalization
  * Update Spring framework version

1.32.0 / 2022-04-05
===================

New functionality
-----------------
  * Add folder decoupling support
  * Support multiple acls in cookies
  * Support structured metadata in `resources` api call
  * Rename API call returns `metadata` and `context` 
  * Support start offset and end offset as expression
  * Get the details of a single resource by asset_id
  * Search by asset id
  * Support metadata fields reordering
Other changes
-------------
  * Fix `verifySignature` timestamp units
  * Fix transformations API call

1.31.0 / 2022-03-21
====================

New functionality
-----------------
  * Get resources by asset id
  * Add `enabled` parameter to `updateUser`, `replaceUser` and `createUser`
  * Add tags as an array
  * Add lowercase support for headers in API responses
  * Allow to disable b-frames
  * Support download backup version api
  * Support `filename_override` upload parameter
  * Add support for single character variable

1.30.0 / 2022-02-02
===================

Other Changes
-------------
  * Update `README.md`
  * Add feature `SDK analytics`
  * Fix a bug where a publicId which contains 'v[num]' is considered to contain a version, therefore the version is skipped. (#242)

1.29.0 / 2021-02-10
===================

New functionality
-----------------
  * Allow setting the user agent (#235)
  * Add support for Apache http-client 4.5 (#234)

Other changes
-------------
  * Fix test name in `ExpressionTest` (#233)


1.28.1 / 2021-02-03
==================

  * Fix `api` reuse bug when calling `cloudinary.search()` (#232)

1.28.0 / 2021-02-01
==================

  * Add `oauth` support to Admin Api calls. (#230)
  * Fix connection reuse when using apache-http-client (versions 4.3 and 4.4) (#231)

1.27.0 / 2020-11-16
===================

New functionality
-----------------
  * Support `type` parameter in `Uploader.updateMetadata()` (#226)
  * Add `downloadFolder` method (#219)
  * Add eval upload parameter (#217)
  * Add support of SHA-256 algorithm in calculation of auth signatures (#215)
  * Support different radius for each corner  (#212)
  * Add support for variables in text style. (#225)
  * Add support for 'accessibility_analysis' parameter (#218)
  * Support new parameter and modes in `generateSprite()` and `multi()` API cals.
  * Add support for `date` param in `Api.usage()` (#210)

  
Other changes
-------------
  * Fix named transformation with spaces (#224)
  * Fix normalize_expression for complex cases (#216)
  * Detect data URLs with suffix in mime type (#213)

1.26.0 / 2020-05-05
===================

New functionality
-----------------

  * Add variable support to `Transformation.opacity()` (#209)
  * Add support for restoring deleted datasource entries (#207)
  * Add support for 32 char SHA-256 URL signatures.
  * Add support for `pow` operator in expressions (#198)
  * Add signature checking methods (#193)
  
Other changes
-------------

  * Fix handling of `max_results` and `next_cursor` parameters for folders api (#203)
  * Fix `normalize_expression` when a keyword is used in a variable name (#205)

1.25.0 / 2020-02-06
===================

New functionality
-----------------
  * Allow generating archive with multiple resource types (#174)
  * Add validation for `CLOUDINARY_URL` scheme (#185)
  * Support create folder API (#188)
  
Other changes
-------------
  * Fix/provisioning api params (#195)
  * Encode URLs in API calls (#186)
  * Improve support for modifying `set` type metadata fields. (#194)
  * Ignore `URL` in AuthToken generation if `ACL` is provided (#184)

1.24.0 / 2019-09-12
===================

  * Add support for `cinemagraph_analysis` parameter. (#182)
  * Rename Account API methods, add convenience overloads. (#181)

1.23.0 / 2019-08-15
===================

New functionality
-----------------
  * Add account API support (user and cloud management) (#176)
  * Add structured metadata APIs and entities (#171)
  * Add duration to conditions in video (#172)
  * Add support for `live` parameter to Upload Preset (#173)
  * Add support for folder deletion (#170)
  * Add support for forcing a version when generating URLs.
  * Add support for custom pre-functions in transformation (wasm/remote). (#162)

Other changes
-------------
  * Fix base64 url validation (accept parameters). (#165)
  * Fix build script and travis.yml to support more java versions.
  * Remove test for similarity search (#163)

1.22.1 / 2019-02-13
===================

  * Fix Java 1.6 support (#161)
  * Fix eager transformation chaining. (#159)

1.22.0 / 2019-01-22
===================

  * Add JVM version to user agent (#157)
  * Add support for range value in `Transformation.fps()` (#155)
  * Add support for google-storage URLs (`gs://`) in uploads (#154)
  * Add `quality_analysis` param in upload, explicit and api.resource calls
  * Add `named` parameter to list-transformations api.

1.21.0 / 2018-11-05
===================

New functionality
-----------------
  * Add support for font antialiasing and font hinting for text overlays

Other changes
-------------
  * Clone configuration in `Url.clone()`

1.20.0 / 2018-10-10
===================

New functionality
-----------------

  * Add support for web assembly and lambda functions in transformations

Other changes
-------------

  * Improve performance of `url.generate()` method.
  * Fix url encoding for AuthToken generation

1.19.0 / 2018-07-22
===================

New functionality
-----------------

  * Add support of `auto` value for `start_offset` transformation parameter
  * Feature/keyframe interval support

Other changes
-------------

  * Fix content range header in chunked upload (force US locale)
  * Keep original filename in `uploadLarge` before sending the InputStream
  * Update gradle for java 7 TLS fix (https://github.com/gradle/gradle/issues/5740)
  * Fix Api list tags test - verify the list instead of specific tags
  * Cleanup upload preset from `testGetUploadPreset` (#129)
  * Add int overload to `TextLayer.letterSpacing()`
  * Fix responsive breakpoint format field implementation
  * Separate modules to run on different travis jobs.
  * Remove `test02Resources` test (broken and unnecessary).
  * Fix raw convert error message test

1.18.0 / 2018-03-15
===================

New functionality
-----------------

  * Add access control parameter to upload and update calls

Other changes
-------------

  * Fix authToken generation when using acl
  * Fix `testOcrUpdate()` test case (#119)
  * Configure .travis.yml to show more test information.
  * Verify `testDeleteByToken` takes all original config into account (#116)
  * Replace `pom.xml` link with `build.gradle` in README.md

1.17.0 / 2017-11-26
===================

  * Add missing params to `explicit` and `upload` api
  * Remove Android from Travis configuration and add JDK versions

1.16.0 / 2017-09-26
===================

  * Change url suffix and root path limitations
  * Add update_version.sh
  * Update Readme to point to HTTPS URLs of cloudinary.com
  * Fix android repository link

1.15.0 / 2017-09-05
===================

New functionality
-----------------

  * Add format field to `ResponsiveBreakpoint`.
  * The Android SDK has been moved to https://github.com/cloudinary/cloudinary_android

Other changes
-------------

  * Add badges to README
  * Create LICENSE
  * Centralize response handling and respect `returnError` param.
  * Fix boolean config values in tag generation
  * Fix project for java8, update cloudinary dependencies.

1.14.0 / 2017-07-20
===================

New functionality
-----------------

  * Add support for uploading remote urls through `Uploader.uploadLarge()`
  * Support resuming `uploadLarge`
  * Streaming profile support.
  * Update TravisCI to explicitly set distribution
  * Allow deleteByToken to pass through when there's no api secret in config.

Other changes
-------------

  * Add test for listing transformations with cursor.
  * Merge branch 'master' into patch-1
  * Make restore test run in parallel
  * Set javadoc encoding to UTF-8.
  * Update gradle to 4.0.1.
  * Fix test to run in parallel.
  * Remove use of `DatatypeConverter` which is not supported in Android
  * Update Cloudinary dependencies version for java sample project.
  * Merge pull request #84 from elevenfive/master
    * Close responsestream
  * Merge pull request #83 from theel0ja/patch-1
    * Improved formatting of markdown

1.13.0 / 2017-06-12
===================

New functionality
-----------------

  * Add support for `format` in Responsive breakpoints transformation. (#78)
  * Add `url_suffix` support for private images. (#76)
  * Add `type` parameter to `Api.publishResource()` (#73)
  * Add support for fetch overlay/underlay (#69)
  * Add `deleteByToken` to `Uploader`.
  * Rename `deleteDerivedResourcesByTransformations` to `deleteDerivedByTransformation`
  * Fix `deleteStreamProfile` no-options overload.
  * Add support for *TravisCI* tests
  * Replace Maven with Gradle as build tool

Other changes
-------------

  * Parallelize tests.

1.12.0 / 2017-05-01
===================

New functionality
-----------------

  * Add Search API

1.11.0 / 2017-04-25
===================

New functionality
-----------------

  * Add `fps` transformation parameter.

1.10.0 / 2017-04-02
===================

New functionality
-----------------

  * Add upload progress callback for Android
  * Add support for notification_url param in `Api.update`
  * Add support for `allowMissing` parameter in archive creation.
  * Add `videoTag(String source)` overload to `Url`.
  * Add `deleteDerivedResourcesByTransformations` to Admin Api
  * Add `ocr` to explicit API

Other changes
-------------

  * Add `ocr` gravity value tests
  * Fix ParseException when accessing `Response.rateLimits` with default locale set to non-english.
  * Add javaDoc for `MultipartUtility.close()`
  * Merge pull request #46 Close streams in UploaderStrategy 
  * Add javaDoc for `MultipartCallback`
  * Add `progressCallback` test cases.
  * Add test for `generate_archive` of raw resources.
  * Fix `MultipartUtility` - Verify inner stream is closed if an exception is thrown somewhere along the way.

1.9.1 / 2017-03-14
==================

  * Add expires at to generate archive (#68)
  * Add `skip_transformation_name` parameter to generate archive. (#67)
  * Fix variables.
    * Fix variable regex.
    * Make Expression.serialize return normalized expression
    * Fix variable sorting.
    * Add tests for variable order.
  * Avoid normalizing negative numbers.
  * Normalize effect parameter
  * Remove duplicate quality parameter line.

1.9.0 / 2017-03-08
==================

New functionality
-----------------

  * Support **User defined variables** and **expressions**.
  * Add `async` parameter to upload params(#63)
  * Add `expired_at` parameter to private download. (#60)
  * Add `moderation` parameter in explicit call (#59)

Other changes
-------------

  * Fix double encoding for commas and slashes in text layers (#66)
  * Add artistic filter test (#65)
  * Add gravity-auto test (#64)
  * Fix `OutOfMemoryError` when uploading large files in android. Fixes #55 (#57)
  * Fix encoding error in api update resource (#61)

1.8.1 / 2017-02-22
==================

  * Add support for URL authorization token.
  * Refactor AuthToken.
  * Refactor tests for stability
  * Support nested objects in CLOUDINARY_URL. e.g. foo[bar]=100.
  * Add maven items to `.gitignore`.

1.8.0 / 2017-02-08
==================

New functionality
-----------------

  * Access mode API

Other changes
-------------

  * Fix listing direction test.
  * Refactor `multi` test

1.7.0 / 2017-01-30
==================

New functionality
-----------------

  * Add Akamai token generator

Other changes
-------------

  * Fix "multi" test

1.6.0 / 2017-01-08
==================

  * Add Search by context API

1.5.0 / 2016-11-19
==================

New functionality
-----------------

  * Add context API
  * Escape `\` and `=` in context
  * Add `removeAllTags` API

1.4.6 / 2016-10-27
====================================

  * Add streaming profiles API

1.4.5 / 2016-09-16
====================================
  * Better handling of missing/unreadable local files

1.4.4 / 2016-09-15
====================================
  * Fix issue when uploading URL with \n

1.4.3 / 2016-09-09
====================================

New functionality
-----------------

  * New Admin API `Publish`.
  * Support `to_type` in `rename`.
  * Add `skip_transformation_name` and `expires_at` to archive parameters.
  * Support Client Hints.

Other changes
-------------

  * Add deprecation message to `Layer` classes.
  * Define `MockableTest`
  * Add static import of `asMap` and `emptyMap`. Suppress deprecation warnings for backward compatibility tests.
  * Refactor Quality and Width tests.
  * Update Junit version and add JUnitParams.
  * Add Hamcrest tests.
  * Add tests for auto width and original width and height ( `ow`, `oh`) values
  * Add `timeout`, `connect_timeout` and `connection_request_timeout` to HTTP43 and HTTP44 Api.

1.4.2 / 2016-05-16
====================================

  * Sent params as entities for PUT, POST
  * Use "_method" with "delete" instead of HttpDelete.
  * Add `next_cursor` to `Api#transformation()`
  * Update Google App Engine demo
  * Add script to create unsigned upload preset for the Android test
  * Use dynamic tag in sprites test
  * Add SDK_TEST_TAG to all resources being created.
  * Remove API limits test

1.4.1 / 2016-03-23
====================================
  * Rename conditional parameters `faces` and `pages` to `faceCount` and `pageCount`


1.4.0 / 2016-03-19
====================================
  * Add Condition builder for faces
  * Modify explicit test - don't use twitter
  * Modify categorization test result value
  * Add Conditional Transformations
  * Cleanup Whitespace 
  * Use variables for public_id's in rename tests
  * Fix uploadLarge to use X-Unique-Upload-Id instead of updating params. Solves #18
  * Fix support for non-ascii chars in upload URL

1.3.0 / 2016-01-19
====================================

  * Add `responsive_breakpoints` paramater
  * Use `TextLayer` instead of `TextLayerBuilder`. Use `getThis()` instead of `self()`.
  * Use constant and meaningful name for upload preset. Rearrange imports.
  * Update SDK versions in Android projects.
  * Support cloudinary credentials URL that has an API_KEY but no API_SECRET
  * Remove redundant `deleteConflictingFiles`.
  * Merge branch 'master' of github.com:cloudinary/cloudinary_java
  * support createArchive
  * line spacng support in text overlay
  * Create separate test class for Layer
  * Rename Layer classes. Rename self() to getThis() to match the pattern.
  * Merge branch 'master' of github.com:cloudinary/cloudinary_java
  * change user agent - remove spaces. stricter layer parameter check. fix underlay method signature
  * Merge branch 'master' of github.com:cloudinary/cloudinary_java
  * Fix Android complex filename test

cloudinary-parent-1.2.2 / 2016-01-19
====================================

  * Fix Android tests
  * Enable apache http 4.3 strategy
  * Support easy overlay/underlay construction
  * Support upload mappings api. add missing restore test
  * Support the restore api
  * Normalize user agent
  * Add invalidate flag to rename and explicit
  * Support aspect ratio transformation param
  * Add filename and complex filename test
  * Fix encoding issues when JVM default encoding is not UTF-8
  * Revent timeout exception change
  * Support filename in upload options. close response objects in http44
  * Update README. Fixes #28
  * Merge pull request #26 from wagaun/master
  * Fixing typo on exception
  * Update README.md

cloudinary-parent-1.2.1 / 2015-06-18
====================================

  * Disable java8 doclint
  * Fix references to 1.1.4-SNAPSHOT. Fix wrong URLs in README.md
  * Fix documentation and imports
  * Modify exception message to say that Admin API is not supported.
  * Fix HTML escaping (fixes upload tags)
  * Allow android unsigned upload without api_key
  * Fix http44 response closing.

cloudinary-parent-1.2.2 / 2015-10-11
====================================

  * Support apache http 4.3 strategy
  * Support easy overlay/underlay construction
  * Support upload mappings api
  * Support the restore api
  * Normalize user agent
  * Add invalidate flag to rename and explicit
  * Support aspect ratio transformation param
  * Fix encoding issues when JVM default encoding is not UTF-8
  * Support filename in upload options
  * Close response objects in http44.

cloudinary-parent-1.2.0 / 2015-04-13
====================================

  * Support httpcomponents 4.4
  * Support for video tag and transformations
  * Add video transformation parameters and zoom transformation
  * Support ftp url upload
  * Support eager_async in explicit
  * Fix UTF-8 issues in API
  * Add support for video tag. refactor Url based tags
  * Scrub UrlBuilderStrategy
  * Enable crippled core mode without loading strategies
  * Move core test to core
  * Use URLEncoder instead of AbstractUrlBuilderStrategy. 
  * Use upload_chuncked endpoint for upload large
  * Improved parameter support for upload_large.
  * support byte[] file input for upload

cloudinary-parent-1.1.3 / 2015-02-24
====================================

  * Fix test after file name change
  * Added timeout parameter to admin api and Fixed test and configuration issues

cloudinary-parent-1.1.2 / 2015-01-15
====================================

  * Fix support for string eager parameters e.g. for safe mobile flow
  * Merge pull request #17 from cloudinary/eager_upload_params
  * merged android signature fix
  * eager upload params can be both string or List<Transformation>

cloudinary-parent-1.1.1 / 2014-12-22
====================================

  * Support secure domain sharding
  * Don't sign version component
  * Support url suffix and use root path
    * renamed urlSuffix to suffix
  * Support tags in upload large.
  * Change log and version update
  * added new options to url tag
  * added invalidate to bulk deletes
  * Add missing tests in adnroid-test. fix signing tests in android-test. be more specific with exception class in http42 Cloudinary tests.
  * updated Url.generate method (b4 tests)
  * bug fixes

cloudinary-parent-1.1.0 / 2014-11-18
====================================

  * Merge branch 'globalize' of github.com:codeinvain/cloudinary_java
  * Remove redundant depndencies
  * - changed org.json to org.cloudinary.json due to Android optimization issues . - removed dependency on SimpleJSON from tablib
  * Update CHANGES.txt
  * Merge branch 'globalize'
  * Fix documentation. Fix dependencies
  * Fix modules artifactId
  * promoted minor version (1.0.x -> 1.1.x) & fixed documentation external links
  * added deprecated asMap method to Cloudinary (support old api)
  * updated documentation , fixed sample projects
  * promoted minor version (1.0.x -> 1.1.x) & fixed documentation external links
  * added deprecated asMap method to Cloudinary (support old api)
  * updated documentation , fixed sample projects
  * add support for signed urls in tag helpers (image and url)
  * Git ignore cloudinary-android-test/src/main/AndroidManifest.xml. Fix tag lib dependency
  * Remove httpclient dependencies from cloudinary-core. Use main version in both http42 and android versions. Remove getRawResponse from ApiResponse
  * Merge branch 'globalize' of github.com:codeinvain/cloudinary_java
  * merged config & builder
  * Update README.md
  * cloudinary credentials removed
  * http42 + android tests pass
  * changed architecture to core + strategies
  * removed shared classes
  * android jar
  * maven build , project dependency core -> http42 -> taglib
  * unified Java API and created basic implementation
  * custom StringUtils
  * support folder listing API

cloudinary-parent-1.0.14 / 2014-07-29
=====================================

  * Add background_removal
  * Support return_delete_token in upload/update params
  * Support responsive and hidpi
  * Support custom coordinates.

cloudinary-parent-1.0.13 / 2014-04-29
=====================================

  * Add support for opacity
  * Support upload_presets
  * Support unsigned uploads
  * Support start_at for resource listing
  * Support phash for upload and resource details
  * Support rate limit header in Api calls
  * Initial commit Google App engine sample
  * Merge remote master
  * Allow passing ClientConnectionManager

cloudinary-parent-1.0.12 / 2014-03-04
=====================================

  * Increment version to 1.0.12
  * Fix uploader API calls handling of non-string parameters e.g. Booleans

cloudinary-parent-1.0.11 / 2014-03-04
=====================================

  * Document releases in CHANGES.txt
  * Fix test - raw upload parts must be > 5m
  * better large raw upload support
  * Merge branch 'master' of https://github.com/cloudinary/cloudinary_java
  * new update method
  * Add listing by moderation kind and status
  * Add moderation status in listing
  * Add moderation flag in upload
  * Add moderation_status in update
  * Add ocr, raw_conversion, categorization, detection, similarity_search and auto_tagging parameters in update and upload
  * Add support for uploading large raw files

cloudinary-parent-1.0.10 / 2014-01-27
=====================================

  * add discard_original_filename upload flag. Formatting in tests
  * support setting context in explicit
  * Add direction support to resource listing.

cloudinary-parent-1.0.9 / 2014-01-10
====================================

  * remove delete_all from tests. fix face coordinates in explicit
  * Merge branch 'master' of https://github.com/cloudinary/cloudinary_java
  * add user agent. fix api test
  * refactor Map encoding for upload
  * Merge branch 'signedurl'
  * Update README.md
  * Merge branch 'master' of https://github.com/cloudinary/cloudinary_java
  * support multiple face coordinates in upload and explicit. optionaly use Coordinates as a wrapper of multiple rectangles
  * add support for overwrite in taglib
  * add support for overwrite boolean in upload
  * support signed urls
  * delete all + cursors, tag and context flags in lists, list by public ids, add support in upload for: face_coordinates, alowed_formats, context
  * change dependency to published 1.0.8 and change installation instructions accordingly

cloudinary-parent-1.0.8 / 2013-12-20
====================================

  * Fix implementation of SmartUrlEncoder in case of non-ascii characters
  * fix callback when servlet is not at root
  * better handling of raw files
  * add subsections in README. Add this to memeber assignments
  * move most of stored file logic to core. support stored file in url and url and image tags. add a readme to the sample project
  * add support for named transformations as tag attribute
  * add support for local secure (and implicit from request)  and cdn_subdomain
  * cleanup and upload parameters completeness
  * change images to use inline transformations when possible. fix image link in list
  * fix inline transformation in image. add inline trnaformation in url
  * initial commit of photo album sample. added additional or modified existing tag helpers to taglib to enable more robust transformations and to allow cloufdinary URLs outside of images and to allow specifying images from facebook/twitter and support jQuery direct upload.

cloudinary-parent-1.0.7 / 2013-11-02
====================================

  * Support the color parameter
  * Merge branch 'master' of https://github.com/cloudinary/cloudinary_java
  * add support for unique_filename and added a test for use_filename
  * Merge pull request #9 from AssuredLabor/transformationAttr
  * add transformation attribute to cloudinary upload tag
  * Fix handling of boolean parameters on upload

cloudinary-parent-1.0.6 / 2013-08-07
====================================

  * Rename prepareUploadTagParams to uploadTagParams
  * Escape all public_ids including non-http ones.
  * Merge pull request #7 from AssuredLabor/extractUploadParams
  * Updated so we don't escapeHTML unless necessary for the server side. This allows the client-side to receive a JS hash / object directly. This is useful, depending on how the input is rendered.
  * Extracted upload tagParams and upload url functionality into their functions, this will facilitate frameworks like Angular fetching the server-side params

cloudinary-parent-1.0.5 / 2013-07-31
====================================

  * Support folder and proxy upload parameters
  * Fix string comparison of secureDistribution
  * Change secure urls to use *res.cloudinary.com
  * Support Admin API ping
  * Support generateSpriteCss

cloudinary-parent-1.0.4 / 2013-07-15
====================================

  * Issue #6 - add instructions on using as a maven dependency
  * Support raw data URI
  * Support zipDownload. Cleanup signing code
  * Support s3 and data:uri urls

cloudinary-parent-1.0.3 / 2013-06-04
====================================

  * Cleanup pom.xml, Fix imageUploadTag test, Fix imports
  * Introduced a new image tag for jsps, you can use it like this:
  * don't track eclipse resources
  * Add the callback and the signature to the image tag
  * In the tag lib, use the Uploader's tag generator * Allow null file parameters
  * enhancements to the HTML processing
  * cleaned up the tag rendering. There is some more flexibility that needs to be added to the tag, but it looks like the core of it is working ok.
  * correctly located the cloudinary tld and updated to use the new classname of the tag Added a singleton manager to ease spring support.
  * renamed tag to make more sense
  * First pass at an upload tag and support code
  * Refactored Cloudinary Java into multiple modules without breaking the module naming convention already established. * Created a -taglib module to support constructing file input tags on the server side, since it requires some server side API signing. * Separate modules allow users who are writing stand-alone applications (not depending on the Servlet API) not to have a dependency on it.
  * Fixing code sample, referencing Android

cloudinary-1.0.2 / 2013-04-08
=============================

  * Upgrade version to 1.0.2-SNAPSHOT
  * Don't fail api tests if api_secret is not given
  * Don't fail api tests if api_secret is not given
  * pom fixes
  * Preparation for Maven repository submission
  * Merge Maven preperation by shakiba
  * Missing file for rename test
  * Invalidate flags in upload and destroy
  * Private download link generator
  * Support for short urls for image/upload
  * Support for folders
  * Support rename
  * Support unsafe transformation update
  * Fix tags api support of multiple public ids
  * ready for maven central
  * Fixing URLs in readme
  * Support akamai
  * Support for sprite genreation, multi and explode. Support new async/notification flags
  * Merge git://github.com/andershedstrom/cloudinary_java
  * Support for usage API call
  * Support image_metadata flag in upload and API
  * Update README.md
  * fixed regexp bug, regexp didn't work
  * Updated pom.xml to handle custom src and test-src directories
  * Allow giving pages flag to resource details API
  * Fix check for limit. Fix htmlWidth visibility
  * Support for info flags in upload
  * Support for transformation flags
  * Support deleteResourcesByTag Support keep_original in resource deletion
  * Uploader.imageUploadTag - helper for create input tag for direct upload to Cloudinary via JS
  * Added README
  * Java naming conventions. Map utility methods
  * Initial commit


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2017 Cloudinary

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: MAVEN_CENTRAL_PUBLISHING_GUIDE.md
================================================
# Maven Central Publishing Guide - Cloudinary Java SDK

This guide documents the complete process for publishing the Cloudinary Java SDK to Maven Central using the new Central Portal (central.sonatype.com), replacing the deprecated OSSRH system.

## 🎯 **Overview**

- **Old System:** `oss.sonatype.org` (dead, returns 401 errors)
- **New System:** `central.sonatype.com` with manual bundle upload
- **Method:** Manual bundle creation and upload (not automated plugin publishing)
- **Requirements:** Complete artifacts with checksums and GPG signatures
- **Current Version:** 2.3.1 → Next version (e.g., 2.3.2)

## 📋 **Prerequisites**

1. **Credentials:**
   - `centralUsername` and `centralPassword` for central.sonatype.com
   - Legacy `ossrhToken` and `ossrhTokenPassword` (if available)

2. **GPG Setup:**
   - GPG key imported: `6B42474E50D0D89A01B40AC225FE63F85DCB788F`
   - Private key available in repository: `private-key.asc`
   - Password: `nwov0aaStnO4`

3. **Java Version:**
   - **Java 8+** (current project targets Java 8)
   - Verify with: `java -version`

## 🔧 **Configuration Changes Required**

### 1. Update Root `build.gradle`

```gradle
plugins {
    id 'maven-publish'
    // Remove the old nexus plugin: id 'io.github.gradle-nexus.publish-plugin' version '1.0.0'
}

allprojects {
    repositories {
        mavenCentral()
    }
    project.ext.set("publishGroupId", group)
}

// Remove the old nexusPublishing block - we'll create bundles manually for Central Portal

tasks.create('createTestSubAccount') {
    doFirst {
        println("Task createTestSubAccount called with module $moduleName")
        def cloudinaryUrl = ""
        
        // core does not use test clouds, skip (keep empty file for a more readable generic travis test script)
        if (moduleName != "core") {
            println "Creating test cloud..."
            def baseUrl = new URL('https://sub-account-testing.cloudinary.com/create_sub_account')
            def connection = baseUrl.openConnection()
            connection.with {
                doOutput = true
                requestMethod = 'POST'
                def json = new JsonSlurper().parseText(content.text)
                def cloud = json["payload"]["cloudName"]
                def key = json["payload"]["cloudApiKey"]
                def secret = json["payload"]["cloudApiSecret"]
                cloudinaryUrl = "CLOUDINARY_URL=cloudinary://$key:$secret@$cloud"
            }
        }

        def dir = new File("${projectDir.path}${File.separator}tools")
        dir.mkdir()
        def file = new File(dir, "cloudinary_url.txt")
        file.createNewFile()
        file.text = cloudinaryUrl

        println("Test sub-account created successfully!")
    }
}
```

### 2. Create New `publish.gradle` for Modules

```gradle
apply plugin: 'maven-publish'
apply plugin: 'signing'

// Simple module-level publishing for manual upload to Central Portal
if (hasProperty("ossrhTokenPassword") || hasProperty("centralPassword")) {
    
    publishing {
        publications {
            mavenJava(MavenPublication) {
                // Set coordinates from gradle.properties
                groupId = project.ext.publishGroupId
                artifactId = project.name
                version = project.version
                
                // Include JAR artifacts and components for Java
                from components.java
                artifact sourcesJar
                artifact javadocJar
                
                pom {
                    name = getModuleName(project.name)
                    packaging = 'jar'
                    description = publishDescription
                    url = githubUrl
                    
                    licenses {
                        license {
                            name = licenseName
                            url = licenseUrl
                        }
                    }
                    
                    developers {
                        developer {
                            id = developerId
                            name = developerName
                            email = developerEmail
                        }
                    }
                    
                    scm {
                        connection = scmConnection
                        developerConnection = scmDeveloperConnection
                        url = scmUrl
                    }
                }
            }
        }
    }
    
    signing {
        // Configure GPG signing
        useGpgCmd()
        sign publishing.publications.mavenJava
    }
}

// Helper function to get proper module names
def getModuleName(artifactId) {
    switch(artifactId) {
        case 'cloudinary-core':
            return 'Cloudinary Core Library'
        case 'cloudinary-http5':
            return 'Cloudinary Apache HTTP 5 Library'
        case 'cloudinary-taglib':
            return 'Cloudinary Taglib Library'
        case 'cloudinary-test-common':
            return 'Cloudinary Test Common Library'
        default:
            return 'Cloudinary Java Library'
    }
}
```

### 3. Update Module `build.gradle` Files

For each module (cloudinary-core, cloudinary-http5, cloudinary-taglib, cloudinary-test-common), replace the publishing section:

```gradle
plugins {
    id 'java-library'
    // Remove: id 'signing'
    // Remove: id 'maven-publish' 
    // Remove: id 'io.codearte.nexus-staging' version '0.21.1'
}

apply from: "../java_shared.gradle"
apply from: "../publish.gradle"  // Apply our new simplified publishing

// Remove the entire old publishing block with nexusStaging
// The new publish.gradle handles everything
```

### 4. Update `gradle.properties`

```properties
# Update URLs to point to new system (for documentation)
publishRepo=https://central.sonatype.com/
snapshotRepo=https://central.sonatype.com/
publishDescription=Cloudinary is a cloud service that offers a solution to a web application's entire image management pipeline. Upload images to the cloud. Automatically perform smart image resizing, cropping and conversion without installing any complex software. Integrate Facebook or Twitter profile image extraction in a snap, in any dimension and style to match your website's graphics requirements. Images are seamlessly delivered through a fast CDN, and much much more. This Java library allows to easily integrate with Cloudinary in Java applications.
githubUrl=http://github.com/cloudinary/cloudinary_java
scmConnection=scm:git:git://github.com/cloudinary/cloudinary_java.git
scmDeveloperConnection=scm:git:git@github.com:cloudinary/cloudinary_java.git
scmUrl=http://github.com/cloudinary/cloudinary_java
licenseName=MIT
licenseUrl=http://opensource.org/licenses/MIT
developerId=cloudinary
developerName=Cloudinary
developerEmail=info@cloudinary.com

# Update version for next release
group=com.cloudinary
version=2.3.2

gnsp.disableApplyOnlyOnRootProjectEnforcement=true

# see https://github.com/gradle/gradle/issues/11308
systemProp.org.gradle.internal.publish.checksums.insecure=true
```

## 🚀 **Step-by-Step Publishing Process**

### Step 1: Environment Setup

```bash
# Navigate to project
cd /Users/adimizrahi/Development/Java/cloudinary_java

# Verify Java version (should be Java 8+)
java -version
javac -version

# Set GPG environment for batch signing
export GPG_TTY=$(tty)
```

### Step 2: Clean and Build All Artifacts

```bash
# Clean previous builds and generate all artifacts
./gradlew clean publishToMavenLocal
```

**Expected Output:** 
- JAR files for each module (cloudinary-core, cloudinary-http5, cloudinary-taglib, cloudinary-test-common)
- Sources JARs (`-sources.jar`)
- Javadoc JARs (`-javadoc.jar`)  
- POM files with correct XML structure
- All artifacts signed with GPG (`.asc` files)

### Step 3: Verify Artifacts Generated

```bash
# Check that all 4 modules have complete artifacts (should be 7 files each)
for module in ~/.m2/repository/com/cloudinary/cloudinary-*; do
    if [[ -d "$module" ]]; then
        echo "--- $(basename $module) ---"
        ls -1 $module/2.3.2/ 2>/dev/null | grep -E "\.(jar|pom|asc)$" | wc -l
    fi
done
```

**Expected:** Each module should show `7` files:
- `cloudinary-module-2.3.2.jar` + `.asc`
- `cloudinary-module-2.3.2-sources.jar` + `.asc` 
- `cloudinary-module-2.3.2-javadoc.jar` + `.asc`
- `cloudinary-module-2.3.2.pom` + `.asc`

### Step 4: Verify POM Files Are Valid

```bash
# Check that POM files have proper metadata
for pom in ~/.m2/repository/com/cloudinary/cloudinary-*/2.3.2/*.pom; do
    if [[ -f "$pom" ]]; then
        echo "--- $(basename $pom) ---"
        echo "Name tags: $(grep -c "<name>" "$pom")"
        echo "Description: $(grep -c "<description>" "$pom")"
        echo "License: $(grep -c "<license>" "$pom")"
        echo "Developer: $(grep -c "<developer>" "$pom")"
        echo "SCM: $(grep -c "<scm>" "$pom")"
    fi
done
```

**Expected:** Each POM should have all required metadata elements.

### Step 5: Generate Additional Checksums

```bash
cd ~/.m2/repository

# Generate MD5 and SHA1 checksums for all artifacts (Central Portal requires these)
find com/cloudinary/cloudinary-* -name "*.jar" -o -name "*.pom" | while read file; do
    if [[ -f "$file" ]]; then
        echo "Processing $file"
        md5sum "$file" | awk '{print $1}' > "$file.md5"
        sha1sum "$file" | awk '{print $1}' > "$file.sha1"
    fi
done
```

### Step 6: Verify Complete File Set

```bash
cd ~/.m2/repository

echo "=== FINAL FILE COUNT CHECK ==="
echo "JAR/POM files:" && find com/cloudinary/cloudinary-* -name "*.jar" -o -name "*.pom" | wc -l
echo "GPG signatures:" && find com/cloudinary/cloudinary-* -name "*.asc" | wc -l
echo "MD5 checksums:" && find com/cloudinary/cloudinary-* -name "*.md5" | wc -l  
echo "SHA1 checksums:" && find com/cloudinary/cloudinary-* -name "*.sha1" | wc -l
```

**Expected File Count:**
- 4 modules × 4 artifacts each = **16 original files**
- **16 GPG signatures** (`.asc`)
- **16 MD5 checksums** (`.md5`)
- **16 SHA1 checksums** (`.sha1`)
- **Total: 64 files**

### Step 7: Create Final Bundle

```bash
cd ~/.m2/repository

# Create the complete bundle for Central Portal upload
BUNDLE_NAME="cloudinary-java-$(grep '^version=' ~/Development/Java/cloudinary_java/gradle.properties | cut -d'=' -f2)-bundle-COMPLETE.tar.gz"

tar -czf ~/"$BUNDLE_NAME" \
$(find com/cloudinary/cloudinary-* \
  -name "*.pom" -o -name "*.jar" \
  -o -name "*.md5" -o -name "*.sha1" -o -name "*.asc" | \
  grep -v maven-metadata | sort)
```

### Step 8: Verify Final Bundle

```bash
cd ~/

# Check bundle size and contents
ls -lh cloudinary-java-*-bundle-COMPLETE.tar.gz
echo "--- File count ---"
tar -tzf cloudinary-java-*-bundle-COMPLETE.tar.gz | wc -l
echo "--- Sample contents ---" 
tar -tzf cloudinary-java-*-bundle-COMPLETE.tar.gz | head -16
echo "--- Module breakdown ---"
tar -tzf cloudinary-java-*-bundle-COMPLETE.tar.gz | grep -E "(core|http5|taglib|test-common)" | cut -d'/' -f3 | sort | uniq -c
```

**Expected:**
- **Size:** ~1-2MB (smaller than Android due to fewer dependencies)
- **Files:** 64 total
- **Modules:** 4 modules with 16 files each
- **Contents:** Each module should have JARs, POMs, and all checksums/signatures

## 📤 **Upload to Central Portal**

### Manual Upload Process

1. **Login:** Go to https://central.sonatype.com/
2. **Credentials:** Use `centralUsername` and `centralPassword`
3. **Upload:** Navigate to "Upload Component" or "Publish"
4. **Bundle:** Select the `.tar.gz` file created in Step 7
5. **Publishing Type:** Choose "USER_MANAGED"
6. **Publication Name:** "Cloudinary Java SDK v{version}"

### Expected Validation

The Central Portal will validate:
- ✅ **POM structure** (proper XML with required metadata)
- ✅ **Artifact integrity** (MD5/SHA1 checksums match)
- ✅ **Signatures** (GPG signatures valid)
- ✅ **Completeness** (all required files present)
- ✅ **Java compatibility** (JAR files are valid)

## 🛠 **Troubleshooting**

### Common Issues & Solutions

1. **GPG Signing Issues:**
   - **Cause:** TTY or batch mode problems
   - **Solution:** `export GPG_TTY=$(tty)` and use `--batch --yes` flags
   - **Alternative:** Use `signing { useGpgCmd() }` in Gradle

2. **Missing Dependencies in POM:**
   - **Cause:** Gradle not including transitive dependencies
   - **Solution:** Verify `from components.java` includes dependencies
   - **Check:** Examine generated POM files for `<dependencies>` section

3. **Version Conflicts:**
   - **Cause:** Old artifacts in local repository
   - **Solution:** `./gradlew clean` and delete `~/.m2/repository/com/cloudinary/`

4. **Module Configuration Issues:**
   - **Cause:** Inconsistent `build.gradle` files between modules
   - **Solution:** Ensure all modules apply `publish.gradle` consistently

5. **Bundle Upload Failures:**
   - **Cause:** Missing or corrupted files in bundle
   - **Solution:** Verify all 64 files present and re-create bundle

## 📋 **Module-Specific Information**

### Cloudinary Core (`cloudinary-core`)
- **Artifact ID:** `cloudinary-core`
- **Description:** Core Cloudinary functionality
- **Dependencies:** Minimal (mostly standard Java libraries)

### Cloudinary HTTP5 (`cloudinary-http5`)
- **Artifact ID:** `cloudinary-http5`
- **Description:** Apache HTTP Client 5 implementation
- **Dependencies:** `cloudinary-core`, Apache HTTP Components

### Cloudinary Taglib (`cloudinary-taglib`)
- **Artifact ID:** `cloudinary-taglib`
- **Description:** JSP Taglib for Cloudinary
- **Dependencies:** `cloudinary-core`, Servlet API

### Cloudinary Test Common (`cloudinary-test-common`)
- **Artifact ID:** `cloudinary-test-common`  
- **Description:** Shared test utilities
- **Dependencies:** `cloudinary-core`, JUnit, test frameworks

## 📝 **Version Update Checklist**

For publishing a new version:

- [ ] Update `version` in `gradle.properties`
- [ ] Update this guide with new version number
- [ ] Run complete publishing process (Steps 1-8)
- [ ] Verify all 64 files in final bundle (4 modules × 16 files)
- [ ] Upload to Central Portal
- [ ] Verify publication appears on Maven Central
- [ ] Update GitHub releases and tags
- [ ] Test artifacts can be consumed by dependent projects

## 🔗 **References**

- **Central Portal:** https://central.sonatype.com/
- **Migration Guide:** https://central.sonatype.org/publish/publish-guide/
- **Gradle Publishing:** https://docs.gradle.org/current/userguide/publishing_maven.html

---

**Last Updated:** [Current Date]  
**Tested Version:** 2.3.2  
**Success Rate:** ✅ To be tested with this process 

## 🚨 **Key Differences from Android SDK**

1. **No AAR files** - Uses JAR files instead
2. **Java components** - Uses `components.java` instead of `components.release`
3. **Simpler setup** - No Android-specific build tools required
4. **Standard Maven structure** - Follows typical Java library patterns
5. **Fewer files per module** - 16 files per module vs 24 for Android modules


================================================
FILE: README.md
================================================
[![Build Status](https://travis-ci.org/cloudinary/cloudinary_java.svg?branch=master)](https://travis-ci.org/cloudinary/cloudinary_java)

Cloudinary
==========

## About
The Cloudinary Java SDK allows you to quickly and easily integrate your application with Cloudinary.
Effortlessly optimize and transform your cloud's assets.

### Additional documentation
This Readme provides basic installation and usage information.
For the complete documentation, see the [Java SDK Guide](https://cloudinary.com/documentation/java_integration).

## Table of Contents
- [Key Features](#key-features)
- [Version Support](#Version-Support)
- [Installation](#installation)
- [Usage](#usage)
    - [Setup](#Setup)
    - [Transform and Optimize Assets](#Transform-and-Optimize-Assets)
    - [File upload](#File-upload)

## Key Features
- [Transform](https://cloudinary.com/documentation/java_video_manipulation) and [optimize](https://cloudinary.com/documentation/java_image_manipulation#image_optimizations) assets (links to docs).
- [Upload assets to cloud](https://cloudinary.com/documentation/java_image_and_video_upload)

## Version Support
| SDK Version    | Java 6+ | Java 8 |
|----------------|---------|--------|
| 1.1.0 - 1.39.0 | V       |        |
| 2.0.0+         |         | V      |

  

## Installation
The cloudinary_java library is available in [Maven Central](https://mvnrepository.com/artifact/com.cloudinary/cloudinary-core). To use it, add the following dependency to your pom.xml :

```xml
<dependency>
    <groupId>com.cloudinary</groupId>
    <artifactId>cloudinary-http45</artifactId>
    <version>2.3.1</version>
</dependency>
```

## Usage
### Setup

Each request for building a URL of a remote cloud resource must have the `cloud_name` parameter set.
Each request to our secure APIs (e.g., image uploads, eager sprite generation) must have the `api_key` and `api_secret` parameters set.
See [API, URLs and access identifiers](https://cloudinary.com/documentation/solution_overview#account_and_api_setup) for more details.

Setting the `cloud_name`, `api_key` and `api_secret` parameters can be done either directly in each call to a Cloudinary method,
by when initializing the Cloudinary object, or by using the CLOUDINARY_URL environment variable / system property.

The entry point of the library is the Cloudinary object.
```java
Cloudinary cloudinary = new Cloudinary();
```

Here's an example of setting the configuration parameters programatically:

```java
Map config = new HashMap();
config.put("cloud_name", "n07t21i7");
config.put("api_key", "123456789012345");
config.put("api_secret", "abcdeghijklmnopqrstuvwxyz12");
Cloudinary cloudinary = new Cloudinary(config);
```

Another example of setting the configuration parameters by providing the CLOUDINARY_URL value to the constructor:

    Cloudinary cloudinary = new Cloudinary("cloudinary://123456789012345:abcdeghijklmnopqrstuvwxyz12@n07t21i7");

### Transform and Optimize Assets
- [See full documentation](https://cloudinary.com/documentation/java_image_manipulation)
Any image uploaded to Cloudinary can be transformed and embedded using powerful view helper methods:

The following example generates the url for accessing an uploaded `sample` image while transforming it to fill a 100x150 rectangle:

```java
cloudinary.url().transformation(new Transformation().width(100).height(150).crop("fill")).generate("sample.jpg");
```

Another example, emedding a smaller version of an uploaded image while generating a 90x90 face detection based thumbnail:

```java
cloudinary.url().transformation(new Transformation().width(90).height(90).crop("thumb").gravity("face")).generate("woman.jpg");
```

You can provide either a Facebook name or a numeric ID of a Facebook profile or a fan page.

Embedding a Facebook profile to match your graphic design is very simple:

```java
cloudinary.url().type("facebook").transformation(new Transformation().width(130).height(130).crop("fill").gravity("north_west")).generate("billclinton.jpg");
```

### File upload
Assuming you have your Cloudinary configuration parameters defined (`cloud_name`, `api_key`, `api_secret`), uploading to Cloudinary is very simple.

The following example uploads a local JPG to the cloud:

```java
cloudinary.uploader().upload("my_picture.jpg", ObjectUtils.emptyMap());
```

The uploaded image is assigned a randomly generated public ID. The image is immediately available for download through a CDN:

```java
cloudinary.url().generate("abcfrmo8zul1mafopawefg.jpg");

# http://res.cloudinary.com/demo/image/upload/abcfrmo8zul1mafopawefg.jpg
```

You can also specify your own public ID:

```java
cloudinary.uploader().upload("http://www.example.com/image.jpg", ObjectUtils.asMap("public_id", "sample_remote"));

cloudinary.url().generate("sample_remote.jpg");

# http://res.cloudinary.com/demo/image/upload/sample_remote.jpg
```

## Contributions
See [contributing guidelines](/CONTRIBUTING.md).

## Get Help
- [Open a Github issue](https://github.com/CloudinaryLtd/cloudinary_java/issues) (for issues related to the SDK)
- [Open a support ticket](https://cloudinary.com/contact) (for issues related to your account)

## About Cloudinary
Cloudinary is a powerful media API for websites and mobile apps alike, Cloudinary enables developers to efficiently manage, transform, optimize, and deliver images and videos through multiple CDNs. Ultimately, viewers enjoy responsive and personalized visual-media experiences—irrespective of the viewing device.

## Additional Resources
- [Cloudinary Transformation and REST API References](https://cloudinary.com/documentation/cloudinary_references): Comprehensive references, including syntax and examples for all SDKs.
- [MediaJams.dev](https://mediajams.dev/): Bite-size use-case tutorials written by and for Cloudinary Developers
- [DevJams](https://www.youtube.com/playlist?list=PL8dVGjLA2oMr09amgERARsZyrOz_sPvqw): Cloudinary developer podcasts on YouTube.
- [Cloudinary Academy](https://training.cloudinary.com/): Free self-paced courses, instructor-led virtual courses, and on-site courses.
- [Code Explorers and Feature Demos](https://cloudinary.com/documentation/code_explorers_demos_index): A one-stop shop for all code explorers, Postman collections, and feature demos found in the docs.
- [Cloudinary Roadmap](https://cloudinary.com/roadmap): Your chance to follow, vote, or suggest what Cloudinary should develop next.
- [Cloudinary Facebook Community](https://www.facebook.com/groups/CloudinaryCommunity): Learn from and offer help to other Cloudinary developers.
- [Cloudinary Account Registration](https://cloudinary.com/users/register/free): Free Cloudinary account registration.
- [Cloudinary Website](https://cloudinary.com)

## Licence
Released under the MIT license.


================================================
FILE: build.gradle
================================================
import groovy.json.JsonSlurper

plugins {
    id 'maven-publish'
    // Removed old nexus plugin - we'll create bundles manually for Central Portal
}

allprojects {
    repositories {
        mavenCentral()
    }
    project.ext.set("publishGroupId", group)
}

// Removed nexusPublishing block - we'll create bundles manually for Central Portal upload

tasks.create('createTestSubAccount') {
    doFirst {
        println("Task createTestSubAccount called with module $moduleName")

        def cloudinaryUrl = ""

        // core does not use test clouds, skip (keep empty file for a more readable generic travis test script)
        if (moduleName != "core") {
            println "Creating test cloud..."
            def baseUrl = new URL('https://sub-account-testing.cloudinary.com/create_sub_account')
            def connection = baseUrl.openConnection()
            connection.with {
                doOutput = true
                requestMethod = 'POST'
                def json = new JsonSlurper().parseText(content.text)
                def cloud = json["payload"]["cloudName"]
                def key = json["payload"]["cloudApiKey"]
                def secret = json["payload"]["cloudApiSecret"]
                cloudinaryUrl = "CLOUDINARY_URL=cloudinary://$key:$secret@$cloud"
            }

        }

        def dir = new File("${projectDir.path}${File.separator}tools")
        dir.mkdir()
        def file = new File(dir, "cloudinary_url.txt")
        file.createNewFile()
        file.text = cloudinaryUrl

        println("Test sub-account created succesfully!")
    }
}


================================================
FILE: cloudinary-core/build.gradle
================================================
plugins {
    id 'java-library'
}

task ciTest( type: Test )

dependencies {
    testImplementation "org.hamcrest:java-hamcrest:2.0.0.0"
    testImplementation group: 'pl.pragmatists', name: 'JUnitParams', version: '1.0.5'
    testImplementation group: 'junit', name: 'junit', version: '4.12'
}

apply from: "../java_shared.gradle"
apply from: "../publish.gradle"

// Publishing configuration moved to ../publish.gradle

================================================
FILE: cloudinary-core/src/main/java/com/cloudinary/AccessControlRule.java
================================================
package com.cloudinary;

import com.cloudinary.utils.ObjectUtils;
import org.cloudinary.json.JSONObject;

import java.util.Date;

/**
 * A class representing a single access control rule for a resource. Used as a parameter for {@link Api#update} and {@link Uploader#upload}
 */
public class AccessControlRule extends JSONObject {

    /**
     * Construct a new token access rule
     * @return The access rule instance
     */
    public static AccessControlRule token(){
        return new AccessControlRule(AccessType.token, null, null);
    }

    /**
     * Construct a new anonymous access rule
     * @param start The start date for the rule
     * @return The access rule instance
     */
    public static AccessControlRule anonymousFrom(Date start){
        return new AccessControlRule(AccessType.anonymous, start, null);
    }

    /**
     * Construct a new anonymous access rule
     * @param end The end date for the rule
     * @return The access rule instance
     */
    public static AccessControlRule anonymousUntil(Date end){
        return new AccessControlRule(AccessType.anonymous, null, end);
    }

    /**
     * Construct a new anonymous access rule
     * @param start The start date for the rule
     * @param end The end date for the rule
     * @return The access rule instance
     */
    public static AccessControlRule anonymous(Date start, Date end){
        return new AccessControlRule(AccessType.anonymous, start, end);
    }

    private AccessControlRule(AccessType accessType, Date start, Date end) {
        put("access_type", accessType.name());
        if (start != null) {
            put("start", ObjectUtils.toISO8601(start));
        }

        if (end != null) {
            put("end", ObjectUtils.toISO8601(end));
        }
    }

    /**
     * Access type for an access rule
     */
    public enum AccessType {
        anonymous, token
    }
}


================================================
FILE: cloudinary-core/src/main/java/com/cloudinary/Api.java
================================================
package com.cloudinary;

import java.util.*;

import com.cloudinary.api.ApiResponse;
import com.cloudinary.api.AuthorizationRequired;
import com.cloudinary.api.exceptions.*;
import com.cloudinary.metadata.MetadataField;
import com.cloudinary.metadata.MetadataDataSource;
import com.cloudinary.metadata.MetadataRule;
import com.cloudinary.strategies.AbstractApiStrategy;
import com.cloudinary.utils.Base64Coder;
import com.cloudinary.utils.ObjectUtils;
import com.cloudinary.utils.StringUtils;
import org.cloudinary.json.JSONArray;

@SuppressWarnings({"rawtypes", "unchecked"})
public class Api {


    public AbstractApiStrategy getStrategy() {
        return strategy;
    }

    public enum HttpMethod {GET, POST, PUT, DELETE;}

    public final static Map<Integer, Class<? extends Exception>> CLOUDINARY_API_ERROR_CLASSES = new HashMap<Integer, Class<? extends Exception>>();

    static {
        CLOUDINARY_API_ERROR_CLASSES.put(400, BadRequest.class);
        CLOUDINARY_API_ERROR_CLASSES.put(401, AuthorizationRequired.class);
        CLOUDINARY_API_ERROR_CLASSES.put(403, NotAllowed.class);
        CLOUDINARY_API_ERROR_CLASSES.put(404, NotFound.class);
        CLOUDINARY_API_ERROR_CLASSES.put(409, AlreadyExists.class);
        CLOUDINARY_API_ERROR_CLASSES.put(420, RateLimited.class);
        CLOUDINARY_API_ERROR_CLASSES.put(500, GeneralError.class);
    }

    public final Cloudinary cloudinary;

    private AbstractApiStrategy strategy;

    protected ApiResponse callApi(HttpMethod method, Iterable<String> uri, Map<String, ? extends Object> params, Map options) throws Exception {
        if (options == null)
            options = ObjectUtils.emptyMap();

        String apiKey = ObjectUtils.asString(options.get("api_key"), this.cloudinary.config.apiKey);
        String apiSecret = ObjectUtils.asString(options.get("api_secret"), this.cloudinary.config.apiSecret);
        String oauthToken = ObjectUtils.asString(options.get("oauth_token"), this.cloudinary.config.oauthToken);

        validateAuthorization(apiKey, apiSecret, oauthToken);


        String authorizationHeader = getAuthorizationHeaderValue(apiKey, apiSecret, oauthToken);
        String apiUrl = createApiUrl(uri, options);
        return this.strategy.callApi(method, apiUrl, params, options, authorizationHeader);
    }

    public Api(Cloudinary cloudinary, AbstractApiStrategy strategy) {
        this.cloudinary = cloudinary;
        this.strategy = strategy;
        this.strategy.init(this);
    }

    public ApiResponse ping(Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        return callApi(HttpMethod.GET, Arrays.asList("ping"), ObjectUtils.emptyMap(), options);
    }

    public ApiResponse usage(Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();

        final List<String> uri = new ArrayList<String>();
        uri.add("usage");

        Object date = options.get("date");

        if (date != null) {
            if (date instanceof Date) {
                date = ObjectUtils.toUsageApiDateFormat((Date) date);
            }

            uri.add(date.toString());
        }

        return callApi(HttpMethod.GET, uri, ObjectUtils.emptyMap(), options);
    }

    public ApiResponse configuration(Map options) throws  Exception {
        if(options == null) options = ObjectUtils.emptyMap();

        final List<String> uri = new ArrayList<String>();
        uri.add("config");

        Map params = ObjectUtils.only(options, "settings");

        return callApi(HttpMethod.GET, uri, params, options);
    }

    public ApiResponse resourceTypes(Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        return callApi(HttpMethod.GET, Arrays.asList("resources"), ObjectUtils.emptyMap(), options);
    }

    public ApiResponse resources(Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
        String type = ObjectUtils.asString(options.get("type"));
        List<String> uri = new ArrayList<String>();
        uri.add("resources");
        uri.add(resourceType);
        if (type != null)
            uri.add(type);
        if(options.get("fields") != null) {
            options.put("fields", StringUtils.join(ObjectUtils.asArray(options.get("fields")), ","));
        }
        ApiResponse response = callApi(HttpMethod.GET, uri, ObjectUtils.only(options, "next_cursor", "direction", "max_results", "prefix", "tags", "context", "moderations", "start_at", "metadata", "fields"), options);
        return response;
    }

    public ApiResponse visualSearch(Map options) throws Exception {
        List<String> uri = new ArrayList<String>();
        uri.add("resources/visual_search");
        uri.add("image");
        if (options.get("text") == null && options.get("image_asset_id") == null && options.get("image_url") == null) {
            throw new IllegalArgumentException("Must supply image file, image url, image asset id or text");
        }
        ApiResponse response = callApi(HttpMethod.GET, uri, options, options);
        return response;
    }

    public ApiResponse resourcesByTag(String tag, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
        if(options.get("fields") != null) {
            options.put("fields", StringUtils.join(ObjectUtils.asArray(options.get("fields")), ","));
        }
        ApiResponse response = callApi(HttpMethod.GET, Arrays.asList("resources", resourceType, "tags", tag), ObjectUtils.only(options, "next_cursor", "direction", "max_results", "tags", "context", "moderations", "metadata", "fields"), options);
        return response;
    }

    public ApiResponse resourcesByContext(String key, Map options) throws Exception {
        return resourcesByContext(key, null, options);
    }

    public ApiResponse resourcesByContext(String key, String value, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
        if(options.get("fields") != null) {
            options.put("fields", StringUtils.join(ObjectUtils.asArray(options.get("fields")), ","));
        }
        Map params = ObjectUtils.only(options, "next_cursor", "direction", "max_results", "tags", "context", "moderations", "metadata", "fields");
        params.put("key", key);
        if (StringUtils.isNotBlank(value)) {
            params.put("value", value);
        }
        return callApi(HttpMethod.GET, Arrays.asList("resources", resourceType, "context"), params, options);
    }

    public ApiResponse resourceByAssetID(String assetId, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        if(options.get("fields") != null) {
            options.put("fields", StringUtils.join(ObjectUtils.asArray(options.get("fields")), ","));
        }
        Map params = buildResourceDetailParams(options);
        ApiResponse response = callApi(HttpMethod.GET, Arrays.asList("resources", assetId), params, options);
        return response;
    }
    public ApiResponse resourcesByAssetIDs(Iterable<String> assetIds, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        Map params = ObjectUtils.only(options, "public_ids", "tags", "context", "moderations");
        params.put("asset_ids", assetIds);
        ApiResponse response = callApi(HttpMethod.GET, Arrays.asList("resources", "by_asset_ids"), params, options);
        return response;
    }

    public ApiResponse resourcesByAssetFolder(String assetFolder, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        if(options.get("fields") != null) {
            options.put("fields", StringUtils.join(ObjectUtils.asArray(options.get("fields")), ","));
        }
        Map params = ObjectUtils.only(options, "next_cursor", "direction", "max_results", "tags", "context", "moderations", "fields");
        params.put("asset_folder", assetFolder);
        ApiResponse response = callApi(HttpMethod.GET, Arrays.asList("resources/by_asset_folder"), params, options);
        return response;
    }

    public ApiResponse resourcesByIds(Iterable<String> publicIds, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
        String type = ObjectUtils.asString(options.get("type"), "upload");
        Map params = ObjectUtils.only(options, "tags", "context", "moderations");
        params.put("public_ids", publicIds);
        ApiResponse response = callApi(HttpMethod.GET, Arrays.asList("resources", resourceType, type), params, options);
        return response;
    }

    public ApiResponse resourcesByModeration(String kind, String status, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
        if(options.get("fields") != null) {
            options.put("fields", StringUtils.join(ObjectUtils.asArray(options.get("fields")), ","));
        }
        ApiResponse response = callApi(HttpMethod.GET, Arrays.asList("resources", resourceType, "moderations", kind, status), ObjectUtils.only(options, "next_cursor", "direction", "max_results", "tags", "context", "moderations", "metadata", "fields"), options);
        return response;
    }

    public ApiResponse resource(String public_id, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
        String type = ObjectUtils.asString(options.get("type"), "upload");
        Map params = buildResourceDetailParams(options);

        ApiResponse response = callApi(HttpMethod.GET, Arrays.asList("resources", resourceType, type, public_id), params, options);

        return response;
    }

    private Map buildResourceDetailParams(Map options) {
        return ObjectUtils.only(options, "exif", "colors", "faces", "coordinates",
                        "image_metadata", "pages", "phash", "max_results", "quality_analysis", "cinemagraph_analysis",
                        "accessibility_analysis", "versions", "media_metadata", "derived_next_cursor");
    }

    public ApiResponse update(String public_id, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
        String type = ObjectUtils.asString(options.get("type"), "upload");
        Map params = new HashMap<String, Object>();
        Util.processWriteParameters(options, params);
        params.put("moderation_status", options.get("moderation_status"));
        params.put("notification_url", options.get("notification_url"));
        ApiResponse response = callApi(HttpMethod.POST, Arrays.asList("resources", resourceType, type, public_id),
                params, options);
        return response;
    }

    public ApiResponse deleteResources(Iterable<String> publicIds, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
        String type = ObjectUtils.asString(options.get("type"), "upload");
        Map params = ObjectUtils.only(options, "keep_original", "invalidate", "next_cursor", "transformations");
        params.put("public_ids", publicIds);
        return callApi(HttpMethod.DELETE, Arrays.asList("resources", resourceType, type), params, options);
    }

    public ApiResponse deleteResourcesByAssetIds(Iterable<String> assetIds, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        Map params = ObjectUtils.only(options, "keep_original", "invalidate", "next_cursor", "transformations");
        params.put("asset_ids", assetIds);
        return callApi(HttpMethod.DELETE, Arrays.asList("resources"), params, options);
    }

    public ApiResponse deleteDerivedByTransformation(Iterable<String> publicIds, List<Transformation> transformations, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
        String type = ObjectUtils.asString(options.get("type"), "upload");
        Map params = ObjectUtils.only(options, "invalidate", "next_cursor");
        params.put("keep_original", true);
        params.put("public_ids", publicIds);
        params.put("transformations", Util.buildEager(transformations));
        return callApi(HttpMethod.DELETE, Arrays.asList("resources", resourceType, type), params, options);
    }

    public ApiResponse deleteResourcesByPrefix(String prefix, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
        String type = ObjectUtils.asString(options.get("type"), "upload");
        Map params = ObjectUtils.only(options, "keep_original", "invalidate", "next_cursor");
        params.put("prefix", prefix);
        return callApi(HttpMethod.DELETE, Arrays.asList("resources", resourceType, type), params, options);
    }

    public ApiResponse deleteResourcesByTag(String tag, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
        return callApi(HttpMethod.DELETE, Arrays.asList("resources", resourceType, "tags", tag), ObjectUtils.only(options, "keep_original", "invalidate", "next_cursor"), options);
    }

    public ApiResponse deleteAllResources(Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
        String type = ObjectUtils.asString(options.get("type"), "upload");
        Map filtered = ObjectUtils.only(options, "keep_original", "invalidate", "next_cursor");
        filtered.put("all", true);
        return callApi(HttpMethod.DELETE, Arrays.asList("resources", resourceType, type), filtered, options);
    }

    public ApiResponse deleteDerivedResources(Iterable<String> derivedResourceIds, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        return callApi(HttpMethod.DELETE, Arrays.asList("derived_resources"), ObjectUtils.asMap("derived_resource_ids", derivedResourceIds), options);
    }

    public ApiResponse tags(Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
        return callApi(HttpMethod.GET, Arrays.asList("tags", resourceType), ObjectUtils.only(options, "next_cursor", "max_results", "prefix"), options);
    }

    public ApiResponse transformations(Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        return callApi(HttpMethod.GET, Arrays.asList("transformations"), ObjectUtils.only(options, "next_cursor", "max_results", "named"), options);
    }

    public ApiResponse transformation(String transformation, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        Map map = ObjectUtils.only(options, "next_cursor", "max_results");
        map.put("transformation", transformation);
        return callApi(HttpMethod.GET, Arrays.asList("transformations"), map, options);
    }

    public ApiResponse deleteTransformation(String transformation, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        Map updates = ObjectUtils.asMap("transformation", transformation);
        return callApi(HttpMethod.DELETE, Arrays.asList("transformations"), updates, options);
    }

    // updates - currently only supported update are:
    // "allowed_for_strict": boolean flag
    // "unsafe_update": transformation string
    public ApiResponse updateTransformation(String transformation, Map updates, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        updates.put("transformation", transformation);
        return callApi(HttpMethod.PUT, Arrays.asList("transformations"), updates, options);
    }

    public ApiResponse createTransformation(String name, String definition, Map options) throws Exception {
        return callApi(HttpMethod.POST, 
                Arrays.asList("transformations"), 
                ObjectUtils.asMap("transformation", definition, "name", name), options);
    }

    public ApiResponse uploadPresets(Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        return callApi(HttpMethod.GET, Arrays.asList("upload_presets"), ObjectUtils.only(options, "next_cursor", "max_results"), options);
    }

    public ApiResponse uploadPreset(String name, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        return callApi(HttpMethod.GET, Arrays.asList("upload_presets", name), ObjectUtils.only(options, "max_results"), options);
    }

    public ApiResponse deleteUploadPreset(String name, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        return callApi(HttpMethod.DELETE, Arrays.asList("upload_presets", name), ObjectUtils.emptyMap(), options);
    }

    public ApiResponse updateUploadPreset(String name, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        Map params = Util.buildUploadParams(options);
        Util.clearEmpty(params);
        params.putAll(ObjectUtils.only(options, "unsigned", "disallow_public_id"));
        return callApi(HttpMethod.PUT, Arrays.asList("upload_presets", name), params, options);
    }

    public ApiResponse createUploadPreset(Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        Map params = Util.buildUploadParams(options);
        Util.clearEmpty(params);
        params.putAll(ObjectUtils.only(options, "name", "unsigned", "disallow_public_id"));
        return callApi(HttpMethod.POST, Arrays.asList("upload_presets"), params, options);
    }

    public ApiResponse rootFolders(Map options) throws Exception {
        if (options == null)
            options = ObjectUtils.emptyMap();
        return callApi(HttpMethod.GET, Arrays.asList("folders"),
                extractParams(options, Arrays.asList("max_results", "next_cursor")),
                options);
    }

    public ApiResponse subFolders(String ofFolderPath, Map options) throws Exception {
        if (options == null)
            options = ObjectUtils.emptyMap();
        return callApi(HttpMethod.GET, Arrays.asList("folders", ofFolderPath),
                extractParams(options, Arrays.asList("max_results", "next_cursor")),
                options);
    }

    //Creates an empty folder
    public ApiResponse createFolder(String folderName, Map options) throws Exception {
        if (options == null)
            options = ObjectUtils.emptyMap();
        return callApi(HttpMethod.POST, Arrays.asList("folders", folderName), ObjectUtils.emptyMap(), options);
    }

    public ApiResponse restore(Iterable<String> publicIds, Map options) throws Exception {
        if (options == null)
            options = ObjectUtils.emptyMap();
        String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
        String type = ObjectUtils.asString(options.get("type"), "upload");
        Map params = new HashMap<String, Object>();
        params.put("public_ids", publicIds);
        params.put("versions", options.get("versions"));

        ApiResponse response = callApi(HttpMethod.POST, Arrays.asList("resources", resourceType, type, "restore"), params, options);
        return response;
    }

    public ApiResponse restoreByAssetIds(Iterable<String> assetIds, Map options) throws Exception {
        if (options == null)
            options = ObjectUtils.emptyMap();
        Map params = new HashMap<String, Object>();
        params.put("asset_ids", assetIds);
        return callApi(HttpMethod.POST, Arrays.asList("resources", "restore"), params, options);
    }

    public ApiResponse uploadMappings(Map options) throws Exception {
        if (options == null)
            options = ObjectUtils.emptyMap();
        return callApi(HttpMethod.GET, Arrays.asList("upload_mappings"),
                ObjectUtils.only(options, "next_cursor", "max_results"), options);
    }

    public ApiResponse uploadMapping(String name, Map options) throws Exception {
        if (options == null)
            options = ObjectUtils.emptyMap();
        return callApi(HttpMethod.GET, Arrays.asList("upload_mappings"), ObjectUtils.asMap("folder", name), options);
    }

    public ApiResponse deleteUploadMapping(String name, Map options) throws Exception {
        if (options == null)
            options = ObjectUtils.emptyMap();
        return callApi(HttpMethod.DELETE, Arrays.asList("upload_mappings"), ObjectUtils.asMap("folder", name), options);
    }

    public ApiResponse updateUploadMapping(String name, Map options) throws Exception {
        if (options == null)
            options = ObjectUtils.emptyMap();
        Map params = new HashMap<String, Object>();
        params.put("folder", name);
        params.putAll(ObjectUtils.only(options, "template"));
        return callApi(HttpMethod.PUT, Arrays.asList("upload_mappings"), params, options);
    }

    public ApiResponse createUploadMapping(String name, Map options) throws Exception {
        if (options == null)
            options = ObjectUtils.emptyMap();
        Map params = new HashMap<String, Object>();
        params.put("folder", name);
        params.putAll(ObjectUtils.only(options, "template"));
        return callApi(HttpMethod.POST, Arrays.asList("upload_mappings"), params, options);
    }

    public ApiResponse publishByPrefix(String prefix, Map options) throws Exception {
        return publishResource("prefix", prefix, options);
    }

    public ApiResponse publishByTag(String tag, Map options) throws Exception {
        return publishResource("tag", tag, options);
    }

    public ApiResponse publishByIds(Iterable<String> publicIds, Map options) throws Exception {
        return publishResource("public_ids", publicIds, options);
    }

    private ApiResponse publishResource(String byKey, Object value, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
        List<String> uri = new ArrayList<String>();
        uri.add("resources");
        uri.add(resourceType);
        uri.add("publish_resources");
        Map params = new HashMap<String, Object>();
        params.put(byKey, value);
        params.putAll(ObjectUtils.only(options, "invalidate", "overwrite", "type"));
        return callApi(HttpMethod.POST, uri, params, options);
    }

    /**
     * Create a new streaming profile
     *
     * @param name            the of the profile
     * @param displayName     the display name of the profile
     * @param representations a collection of Maps with a transformation key
     * @param options         additional options
     * @return the new streaming profile
     * @throws Exception an exception
     */
    public ApiResponse createStreamingProfile(String name, String displayName, List<Map> representations, Map options) throws Exception {
        if (options == null)
            options = ObjectUtils.emptyMap();
        List<Map> serializedRepresentations = new ArrayList<Map>(representations.size());
        for (Map t : representations) {
            final Object transformation = t.get("transformation");
            serializedRepresentations.add(ObjectUtils.asMap("transformation", transformation.toString()));
        }
        List<String> uri = Collections.singletonList("streaming_profiles");
        final Map params = ObjectUtils.asMap(
                "name", name,
                "representations", new JSONArray(serializedRepresentations.toArray())
        );
        if (displayName != null) {
            params.put("display_name", displayName);
        }
        return callApi(HttpMethod.POST, uri, params, options);
    }

    /**
     * @see Api#createStreamingProfile(String, String, List, Map)
     */
    public ApiResponse createStreamingProfile(String name, String displayName, List<Map> representations) throws Exception {
        return createStreamingProfile(name, displayName, representations, null);
    }

    /**
     * Get a streaming profile information
     *
     * @param name    the name of the profile to fetch
     * @param options additional options
     * @return a streaming profile
     * @throws Exception an exception
     */
    public ApiResponse getStreamingProfile(String name, Map options) throws Exception {
        if (options == null)
            options = ObjectUtils.emptyMap();
        List<String> uri = Arrays.asList("streaming_profiles", name);

        return callApi(HttpMethod.GET, uri, ObjectUtils.emptyMap(), options);

    }

    /**
     * @see Api#getStreamingProfile(String, Map)
     */
    public ApiResponse getStreamingProfile(String name) throws Exception {
        return getStreamingProfile(name, null);
    }

    /**
     * List Streaming profiles
     *
     * @param options additional options
     * @return a list of all streaming profiles defined for the current cloud
     * @throws Exception an exception
     */
    public ApiResponse listStreamingProfiles(Map options) throws Exception {
        if (options == null)
            options = ObjectUtils.emptyMap();
        List<String> uri = Collections.singletonList("streaming_profiles");
        return callApi(HttpMethod.GET, uri, ObjectUtils.emptyMap(), options);

    }

    /**
     * @see Api#listStreamingProfiles(Map)
     */
    public ApiResponse listStreamingProfiles() throws Exception {
        return listStreamingProfiles(null);
    }

    /**
     * Delete a streaming profile information. Predefined profiles are restored to the default setting.
     *
     * @param name    the name of the profile to delete
     * @param options additional options
     * @return a streaming profile
     * @throws Exception an exception
     */
    public ApiResponse deleteStreamingProfile(String name, Map options) throws Exception {
        if (options == null)
            options = ObjectUtils.emptyMap();
        List<String> uri = Arrays.asList("streaming_profiles", name);

        return callApi(HttpMethod.DELETE, uri, ObjectUtils.emptyMap(), options);

    }

    /**
     * @see Api#deleteStreamingProfile(String, Map)
     */
    public ApiResponse deleteStreamingProfile(String name) throws Exception {
        return deleteStreamingProfile(name, null);
    }

    /**
     * Create a new streaming profile
     *
     * @param name            the of the profile
     * @param displayName     the display name of the profile
     * @param representations a collection of Maps with a transformation key
     * @param options         additional options
     * @return the new streaming profile
     * @throws Exception an exception
     */
    public ApiResponse updateStreamingProfile(String name, String displayName, List<Map> representations, Map options) throws Exception {
        if (options == null)
            options = ObjectUtils.emptyMap();
        List<Map> serializedRepresentations;
        final Map params = new HashMap();
        List<String> uri = Arrays.asList("streaming_profiles", name);

        if (representations != null) {
            serializedRepresentations = new ArrayList<Map>(representations.size());
            for (Map t : representations) {
                final Object transformation = t.get("transformation");
                serializedRepresentations.add(ObjectUtils.asMap("transformation", transformation.toString()));
            }
            params.put("representations", new JSONArray(serializedRepresentations.toArray()));
        }
        if (displayName != null) {
            params.put("display_name", displayName);
        }
        return callApi(HttpMethod.PUT, uri, params, options);
    }

    /**
     * @see Api#updateStreamingProfile(String, String, List, Map)
     */
    public ApiResponse updateStreamingProfile(String name, String displayName, List<Map> representations) throws Exception {
        return createStreamingProfile(name, displayName, representations);
    }

    /**
     * Update access mode of one or more resources by prefix
     *
     * @param accessMode The new access mode, "public" or  "authenticated"
     * @param prefix     The prefix by which to filter applicable resources
     * @param options    additional options
     *                   <ul>
     *                   <li>resource_type - (default "image") - the type of resources to modify</li>
     *                   <li>max_results - optional - the maximum resources to process in a single invocation</li>
     *                   <li>next_cursor - optional - provided by a previous call to the method</li>
     *                   </ul>
     * @return a map of the returned values
     * <ul>
     * <li>updated - an array of resources</li>
     * <li>next_cursor - optional - provided if more resources can be processed</li>
     * </ul>
     * @throws ApiException an API exception
     */
    public ApiResponse updateResourcesAccessModeByPrefix(String accessMode, String prefix, Map options) throws Exception {
        return updateResourcesAccessMode(accessMode, "prefix", prefix, options);
    }

    /**
     * Update access mode of one or more resources by tag
     *
     * @param accessMode The new access mode, "public" or  "authenticated"
     * @param tag        The tag by which to filter applicable resources
     * @param options    additional options
     *                   <ul>
     *                   <li>resource_type - (default "image") - the type of resources to modify</li>
     *                   <li>max_results - optional - the maximum resources to process in a single invocation</li>
     *                   <li>next_cursor - optional - provided by a previous call to the method</li>
     *                   </ul>
     * @return a map of the returned values
     * <ul>
     * <li>updated - an array of resources</li>
     * <li>next_cursor - optional - provided if more resources can be processed</li>
     * </ul>
     * @throws ApiException an API exception
     */
    public ApiResponse updateResourcesAccessModeByTag(String accessMode, String tag, Map options) throws Exception {
        return updateResourcesAccessMode(accessMode, "tag", tag, options);
    }

    /**
     * Delete a folder (must be empty).
     *
     * @param folder  The full path of the folder to delete
     * @param options additional options.
     * @return The operation result.
     * @throws Exception When the folder isn't empty or doesn't exist.
     */
    public ApiResponse deleteFolder(String folder, Map options) throws Exception {
        if (options == null || options.isEmpty()) options = ObjectUtils.asMap();
        List<String> uri = Arrays.asList("folders", folder);
        Map params = ObjectUtils.only(options, "skip_backup");
        return callApi(HttpMethod.DELETE, uri, params, options);
    }

    /**
     * Update access mode of one or more resources by publicIds
     *
     * @param accessMode The new access mode, "public" or  "authenticated"
     * @param publicIds  A list of public ids of resources to be updated
     * @param options    additional options
     *                   <ul>
     *                   <li>resource_type - (default "image") - the type of resources to modify</li>
     *                   <li>max_results - optional - the maximum resources to process in a single invocation</li>
     *                   <li>next_cursor - optional - provided by a previous call to the method</li>
     *                   </ul>
     * @return a map of the returned values
     * <ul>
     * <li>updated - an array of resources</li>
     * <li>next_cursor - optional - provided if more resources can be processed</li>
     * </ul>
     * @throws ApiException an API exception
     */
    public ApiResponse updateResourcesAccessModeByIds(String accessMode, Iterable<String> publicIds, Map options) throws Exception {
        return updateResourcesAccessMode(accessMode, "public_ids", publicIds, options);
    }

    private ApiResponse updateResourcesAccessMode(String accessMode, String byKey, Object value, Map options) throws Exception {
        if (options == null) options = ObjectUtils.emptyMap();
        String resourceType = ObjectUtils.asString(options.get("resource_type"), "image");
        String type = ObjectUtils.asString(options.get("type"), "upload");
        List<String> uri = Arrays.asList("resources", resourceType, type, "update_access_mode");
        Map params = ObjectUtils.only(options, "next_cursor", "max_results");
        params.put("access_mode", accessMode);
        params.put(byKey, value);
        return callApi(HttpMethod.POST, uri, params, options);
    }

    /**
     * Add a new metadata field definition
     *
     * @param field The field to add.
     * @return A map representing the newly added field.
     * @throws Exception
     */
    public ApiResponse addMetadataField(MetadataField field) throws Exception {
        return callApi(HttpMethod.POST, Collections.singletonList("metadata_fields"),
                ObjectUtils.toMap(field), ObjectUtils.asMap("content_type", "json"));
    }

    /**
     * List all the metadata field definitions (structure, not values)
     *
     * @return A map containing the list of field definitions maps.
     * @throws Exception
     */
    public ApiResponse listMetadataFields() throws Exception {
        return callApi(HttpMethod.GET, Collections.singletonList("metadata_fields"), Collections.<String, Object>emptyMap(), Collections.emptyMap());
    }

    /**
     * Get a metadata field definition by id
     *
     * @param fieldExternalId The id of the field to retrieve
     * @return The fields definitions.
     * @throws Exception
     */
    public ApiResponse metadataFieldByFieldId(String fieldExternalId) throws Exception {
        return callApi(HttpMethod.GET, Arrays.asList("metadata_fields", fieldExternalId), Collections.<String, Object>emptyMap(), Collections.emptyMap());
    }

    /**
     * Update the definitions of a single metadata field.
     *
     * @param fieldExternalId The id of the field to update
     * @param field           The field definition
     * @return The updated fields definition.
     * @throws Exception
     */
    public ApiResponse updateMetadataField(String fieldExternalId, MetadataField field) throws Exception {
        List<String> uri = Arrays.asList("metadata_fields", fieldExternalId);
        return callApi(HttpMethod.PUT, uri, ObjectUtils.toMap(field), Collections.singletonMap("content_type", "json"));
    }

    /**
     * Update the datasource entries for a given field
     *
     * @param fieldExternalId The id of the field to update
     * @param entries         A list of datasource entries. Existing entries (according to entry id) will be updated,
     *                        new entries will be added.
     * @return The updated field definition.
     * @throws Exception
     */
    public ApiResponse updateMetadataFieldDatasource(String fieldExternalId, List<MetadataDataSource.Entry> entries) throws Exception {
        List<String> uri = Arrays.asList("metadata_fields", fieldExternalId, "datasource");
        return callApi(HttpMethod.PUT, uri, Collections.singletonMap("values", entries), Collections.singletonMap("content_type", "json"));
    }

    /**
     * Delete data source entries for a given field
     *
     * @param fieldExternalId   The id of the field to update
     * @param entriesExternalId The ids of all the entries to delete from the data source
     * @return The remaining datasource entries.
     * @throws Exception
     */
    public ApiResponse deleteDatasourceEntries(String fieldExternalId, List<String> entriesExternalId) throws Exception {
        List<String> uri = Arrays.asList("metadata_fields", fieldExternalId, "datasource");
        return callApi(HttpMethod.DELETE, uri, Collections.singletonMap("external_ids", entriesExternalId), Collections.emptyMap());
    }

    /**
     * Restore deleted data source entries for a given field
     *
     * @param fieldExternalId   The id of the field to operate
     * @param entriesExternalId The ids of all the entries to restore from the data source
     * @return The datasource entries state after restore
     * @throws Exception
     */
    public ApiResponse restoreDatasourceEntries(String fieldExternalId, List<String> entriesExternalId) throws Exception {
        List<String> uri = Arrays.asList("metadata_fields", fieldExternalId, "datasource_restore");
        return callApi(HttpMethod.POST, uri, Collections.singletonMap("external_ids", entriesExternalId), Collections.singletonMap("content_type", "json"));
    }

    /**
     * Delete a field definition.
     *
     * @param fieldExternalId The id of the field to delete
     * @return A map with a "message" key. "ok" value indicates a successful deletion.
     * @throws Exception
     */
    public ApiResponse deleteMetadataField(String fieldExternalId) throws Exception {
        List<String> uri = Arrays.asList("metadata_fields", fieldExternalId);
        return callApi(HttpMethod.DELETE, uri, Collections.<String, Object>emptyMap(), Collections.emptyMap());
    }

    /**
     * Reorders metadata fields.
     *
     * @param orderBy Criteria for the order (one of the fields 'label', 'external_id', 'created_at')
     * @param direction Optional (gets either asc or desc)
     * @param options Additional options
     * @return List of metadata fields in their new order
     * @throws Exception
     */
    public ApiResponse reorderMetadataFields(String orderBy, String direction, Map options) throws Exception {
        if (orderBy == null) {
            throw new IllegalArgumentException("Must supply orderBy");
        }

        List<String> uri = Arrays.asList("metadata_fields", "order");
        Map<String, Object> map = ObjectUtils.asMap("order_by", orderBy);
        if (direction != null) {
            map.put("direction", direction);
        }

        return callApi(HttpMethod.PUT, uri, map, options);
    }

    public ApiResponse listMetadataRules(Map options) throws Exception {
        if (options == null || options.isEmpty()) options = ObjectUtils.asMap();
        final Map params = new HashMap();
        List<String> uri = Arrays.asList("metadata_rules");
        return callApi(HttpMethod.GET, uri, params, options);
    }

    public ApiResponse addMetadataRule(MetadataRule rule, Map options) throws Exception {
        if (options == null || options.isEmpty()) options = ObjectUtils.asMap();
        options.put("content_type", "json");
        final Map params = rule.asMap();
        List<String> uri = Arrays.asList("metadata_rules");
        return callApi(HttpMethod.POST, uri, params, options);
    }

    public ApiResponse updateMetadataRule(String externalId, MetadataRule rule, Map options) throws Exception {
        if (options == null || options.isEmpty()) options = ObjectUtils.asMap();
        options.put("content_type", "json");
        final Map params = rule.asMap();
        List<String> uri = Arrays.asList("metadata_rules", externalId);
        return callApi(HttpMethod.PUT, uri, params, options);
    }

    public ApiResponse deleteMetadataRule(String externalId, Map options) throws Exception {
        if (options == null || options.isEmpty()) options = ObjectUtils.asMap();
        List<String> uri = Arrays.asList("metadata_rules", externalId);
        return callApi(HttpMethod.DELETE, uri, ObjectUtils.emptyMap(), options);
    }

    public ApiResponse analyze(String inputType, String analysisType, String uri, Map options) throws Exception {
        if (options == null || options.isEmpty()) options = ObjectUtils.asMap();
        List<String> url = Arrays.asList("analysis", "analyze", inputType);
        options.put("api_version", "v2");
        options.put("content_type", "json");
        final Map params = new HashMap();
        params.put("analysis_type", analysisType);
        params.put("uri", uri);
        return callApi(HttpMethod.POST, url, params, options);
    }

    public ApiResponse renameFolder(String path, String toPath, Map options) throws Exception {
        if (options == null || options.isEmpty()) options = ObjectUtils.asMap();
        List<String> url = Arrays.asList("folders", path);

        final Map params = new HashMap();
        params.put("to_folder", toPath);

        return callApi(HttpMethod.PUT, url, params, options);

    }

    public ApiResponse deleteBackedUpAssets(String assetId, String[] versionIds, Map options) throws Exception {
        if (options == null || options.isEmpty()) options = ObjectUtils.asMap();
        if (StringUtils.isEmpty(assetId)) {
            throw new IllegalArgumentException("AssetId parameter is required");
        }

        if (versionIds == null || versionIds.length == 0) {
            throw new IllegalArgumentException("VersionIds parameter is required");
        }

        List<String> url = Arrays.asList("resources", "backup", assetId);

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("version_ids[]", StringUtils.join(versionIds, "&"));

        return callApi(HttpMethod.DELETE, url, params, options);

    }

    private Map<String, ?> extractParams(Map options, List<String> keys) {
        Map<String, Object> result = new HashMap<String, Object>();
        for (String key : keys) {
            Object option = options.get(key);

            if (option != null) {
                result.put(key, option);
            }
        }
        return result;
    }

    protected void validateAuthorization(String apiKey, String apiSecret, String oauthToken) {
        if (oauthToken == null) {
            if (apiKey == null) throw new IllegalArgumentException("Must supply api_key");
            if (apiSecret == null) throw new IllegalArgumentException("Must supply api_secret");
        }
    }

    protected String getAuthorizationHeaderValue(String apiKey, String apiSecret, String oauthToken) {
        if (oauthToken != null){
            return "Bearer " + oauthToken;
        } else {
            return "Basic " + Base64Coder.encodeString(apiKey + ":" + apiSecret);
        }
    }

    protected String createApiUrl (Iterable<String> uri, Map options){
        String version = ObjectUtils.asString(options.get("api_version"), "v1_1");
        String prefix = ObjectUtils.asString(options.get("upload_prefix"), ObjectUtils.asString(this.cloudinary.config.uploadPrefix, "https://api.cloudinary.com"));
        String cloudName = ObjectUtils.asString(options.get("cloud_name"), this.cloudinary.config.cloudName);
        if (cloudName == null) throw new IllegalArgumentException("Must supply cloud_name");
        String apiUrl = StringUtils.join(Arrays.asList(prefix, version, cloudName), "/");
        for (String component : uri) {
            component = SmartUrlEncoder.encode(component);
            apiUrl = apiUrl + "/" + component;

        }
        return apiUrl;
    }
}


================================================
FILE: cloudinary-core/src/main/java/com/cloudinary/ArchiveParams.java
================================================
package com.cloudinary;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class ArchiveParams {
    public static final String FORMAT_ZIP = "zip";

    public static final String MODE_DOWNLOAD = "download";
    public static final String MODE_CREATE = "create";

    private String resourceType = "image";
    private String type = null;
    private String mode = MODE_CREATE;
    private String targetFormat = null;
    private String targetPublicId = null;
    private boolean flattenFolders = false;
    private boolean flattenTransformations = false;
    private boolean useOriginalFilename = false;
    private boolean async = false;
    private boolean keepDerived = false;
    private boolean skipTransformationName = false;
    private boolean allowMissing = false;
    private String notificationUrl = null;
    private String[] targetTags = null;
    private String[] tags = null;
    private String[] publicIds = null;
    private String[] fullyQualifiedPublicIds = null;
    private String[] prefixes = null;
    private Transformation[] transformations = null;
    private Long expiresAt = null;

    public String resourceType() {
        return resourceType;
    }

    public ArchiveParams resourceType(String resourceType) {
        if (resourceType == null)
            throw new IllegalArgumentException("resource type must be non-null");
        this.resourceType = resourceType;
        return this;
    }

    public String type() {
        return type;
    }

    public ArchiveParams type(String type) {
        this.type = type;
        return this;
    }

    public String mode() {
        return mode;
    }

    public ArchiveParams mode(String mode) {
        this.mode = mode;
        return this;
    }

    public String targetFormat() {
        return targetFormat;
    }

    public ArchiveParams targetFormat(String targetFormat) {
        this.targetFormat = targetFormat;
        return this;
    }

    public String targetPublicId() {
        return targetPublicId;
    }

    public ArchiveParams targetPublicId(String targetPublicId) {
        this.targetPublicId = targetPublicId;
        return this;
    }

    public boolean isFlattenFolders() {
        return flattenFolders;
    }

    public ArchiveParams flattenFolders(boolean flattenFolders) {
        this.flattenFolders = flattenFolders;
        return this;
    }

    public boolean isFlattenTransformations() {
        return flattenTransformations;
    }

    public ArchiveParams flattenTransformations(boolean flattenTransformations) {
        this.flattenTransformations = flattenTransformations;
        return this;
    }

    public boolean isUseOriginalFilename() {
        return useOriginalFilename;
    }

    public ArchiveParams useOriginalFilename(boolean useOriginalFilename) {
        this.useOriginalFilename = useOriginalFilename;
        return this;
    }

    public boolean isAsync() {
        return async;
    }

    public ArchiveParams async(boolean async) {
        this.async = async;
        return this;
    }

    public boolean isSkipTransformationName() {
        return skipTransformationName;
    }

    public ArchiveParams skipTransformationName(boolean skipTransformationName) {
        this.skipTransformationName = skipTransformationName;
        return this;
    }

    public boolean isAllowMissing(){
        return allowMissing;
    }

    public ArchiveParams allowMissing(boolean allowMissing){
        this.allowMissing = allowMissing;
        return this;
    }

    public boolean isKeepDerived() {
        return keepDerived;
    }

    public ArchiveParams keepDerived(boolean keepDerived) {
        this.keepDerived = keepDerived;
        return this;
    }

    public String notificationUrl() {
        return notificationUrl;
    }

    public ArchiveParams notificationUrl(String notificationUrl) {
        this.notificationUrl = notificationUrl;
        return this;
    }

    public String[] targetTags() {
        return targetTags;
    }

    public ArchiveParams targetTags(String[] targetTags) {
        this.targetTags = targetTags;
        return this;
    }

    public String[] tags() {
        return tags;
    }

    public ArchiveParams tags(String[] tags) {
        this.tags = tags;
        return this;
    }

    public String[] publicIds() {
        return publicIds;
    }

    public ArchiveParams publicIds(String[] publicIds) {
        this.publicIds = publicIds;
        return this;
    }

    public String[] fully_qualified_public_ids() {
        return fullyQualifiedPublicIds;
    }

    public ArchiveParams fullyQualifiedPublicIds(String[] fullyQualifiedPublicIds) {
        this.fullyQualifiedPublicIds = fullyQualifiedPublicIds;
        return this;
    }

    public String[] prefixes() {
        return prefixes;
    }

    public ArchiveParams prefixes(String[] prefixes) {
        this.prefixes = prefixes;
        return this;
    }

    public Transformation[] transformations() {
        return transformations;
    }

    public ArchiveParams transformations(Transformation[] transformations) {
        this.transformations = transformations;
        return this;
    }

    public ArchiveParams expiresAt(Long expiresAt) {
        this.expiresAt = expiresAt;
        return this;
    }

    public Long expiresAt(){
        return expiresAt;
    }

    public Map<String, Object> toMap() {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("resource_type", resourceType);
        params.put("type", type);
        params.put("mode", mode);
        if (targetPublicId != null)
            params.put("target_public_id", targetPublicId);
        params.put("flatten_folders", flattenFolders);
        params.put("flatten_transformations", flattenTransformations);
        params.put("use_original_filename", useOriginalFilename);
        params.put("async", async);
        params.put("keep_derived", keepDerived);
        params.put("skip_transformation_name", skipTransformationName);
        params.put("allow_missing", allowMissing);
        if (notificationUrl != null)
            params.put("notification_url", notificationUrl);
        if (targetTags != null)
            params.put("target_tags", targetTags);
        if (tags != null)
            params.put("tags", tags);
        if (publicIds != null)
            params.put("public_ids", publicIds);
        if(fullyQualifiedPublicIds !=null){
            params.put("fully_qualified_public_ids", fullyQualifiedPublicIds);
        }
        if (prefixes != null)
            params.put("prefixes", prefixes);
        if (transformations != null) {
            params.put("transformations", Arrays.asList(transformations));
        }
        if (expiresAt != null){
            params.put("expires_at", expiresAt);
        }
        return params;
    }
}


================================================
FILE: cloudinary-core/src/main/java/com/cloudinary/AuthToken.java
================================================
package com.cloudinary;

import com.cloudinary.utils.ObjectUtils;
import com.cloudinary.utils.StringUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.regex.Pattern;

/**
 * Authentication Token generator
 */
public class AuthToken {
    /**
     * A null AuthToken, which can be passed to a method to override global settings.
     */
    public static final AuthToken NULL_AUTH_TOKEN = new AuthToken().setNull();
    private static final String AUTH_TOKEN_NAME = "__cld_token__";

    private String tokenName = AUTH_TOKEN_NAME;
    private String key;
    private long startTime;
    private long expiration;
    private String ip;
    private List<String> acl = new ArrayList<>();
    private long duration;
    private boolean isNullToken = false;
    private static final Pattern UNSAFE_URL_CHARS_PATTERN = Pattern.compile("[ \"#%&'/:;<=>?@\\[\\\\\\]^`{|}~]");

    public AuthToken() {
    }

    public AuthToken(String key) {
        this.key = key;
    }

    /**
     * Create a new AuthToken configuration.
     *
     * @param options The following keys may be used in the options: key, startTime, expiration, ip, acl, duration.
     */
    public AuthToken(Map options) {
        if (options != null) {
            this.tokenName = ObjectUtils.asString(options.get("tokenName"), this.tokenName);
            this.key = (String) options.get("key");
            this.startTime = ObjectUtils.asLong(options.get("startTime"), 0L);
            this.expiration = ObjectUtils.asLong(options.get("expiration"), 0L);
            this.ip = (String) options.get("ip");

            Object acl = options.get("acl");
            if (acl != null) {
                if (acl instanceof String) {
                    this.acl = Collections.singletonList(acl.toString());
                } else if (Collection.class.isAssignableFrom(acl.getClass())) {
                    this.acl = new ArrayList<String>((Collection<String>)acl);
                }
            }

            this.duration = ObjectUtils.asLong(options.get("duration"), 0L);
        }
    }

    public Map<String,Object> asMap(){
        Map<String,Object> result = new HashMap<String, Object>();

        result.put("tokenName", this.tokenName);
        result.put("key", this.key);
        result.put("startTime", this.startTime);
        result.put("expiration", this.expiration);
        result.put("ip", this.ip);
        result.put("acl", this.acl);
        result.put("duration", this.duration);

        return result;
    }

    /**
     * Create a new AuthToken configuration overriding the default token name.
     *
     * @param tokenName the name of the token. must be supported by the server.
     * @return this
     */
    public AuthToken tokenName(String tokenName) {
        this.tokenName = tokenName;
        return this;
    }

    /**
     * Set the start time of the token. Defaults to now.
     *
     * @param startTime in seconds since epoch
     * @return this
     */
    public AuthToken startTime(long startTime) {
        this.startTime = startTime;
        return this;
    }

    /**
     * Set the end time (expiration) of the token
     *
     * @param expiration in seconds since epoch
     * @return this
     */
    public AuthToken expiration(long expiration) {
        this.expiration = expiration;
        return this;
    }

    /**
     * Set the ip of the client
     *
     * @param ip
     * @return this
     */
    public AuthToken ip(String ip) {
        this.ip = ip;
        return this;
    }

    /**
     * Define an ACL for a cookie token
     *
     * @param acl
     * @return this
     */
    public AuthToken acl(String... acl) {
        this.acl = Arrays.asList(acl);
        return this;
    }

    /**
     * The duration of the token in seconds. This value is used to calculate the expiration of the token.
     * It is ignored if expiration is provided.
     *
     * @param duration in seconds
     * @return this
     */
    public AuthToken duration(long duration) {
        this.duration = duration;
        return this;
    }

    /**
     * Generate the authentication token
     *
     * @return a signed token
     */
    public String generate() {
        return generate(null);
    }

    /**
     * Generate a URL token for the given URL.
     *
     * @param url the URL to be authorized
     * @return a URL token
     */
    public String generate(String url) {

        if (url == null && (acl == null || acl.size() == 0)) {
            throw new IllegalArgumentException("Must provide acl or url");
        }

        long expiration = this.expiration;
        if (expiration == 0) {
            if (duration > 0) {
                final long start = startTime > 0 ? startTime : Calendar.getInstance(TimeZone.getTimeZone("UTC")).getTimeInMillis() / 1000L;
                expiration = start + duration;
            } else {
                throw new IllegalArgumentException("Must provide either expiration or duration");
            }
        }
        ArrayList<String> tokenParts = new ArrayList<String>();
        if (ip != null) {
            tokenParts.add("ip=" + ip);
        }
        if (startTime > 0) {
            tokenParts.add("st=" + startTime);
        }
        tokenParts.add("exp=" + expiration);
        if (acl != null && acl.size() > 0) {
            tokenParts.add("acl=" + escapeToLower(String.join("!", acl)));
        }
        ArrayList<String> toSign = new ArrayList<String>(tokenParts);
        if (url != null && (acl == null || acl.size() == 0)) {
            toSign.add("url=" + escapeToLower(url));
        }
        String auth = digest(StringUtils.join(toSign, "~"));
        tokenParts.add("hmac=" + auth);
        return tokenName + "=" + StringUtils.join(tokenParts, "~");

    }

    /**
     * Escape url using lowercase hex code
     *
     * @param url a url string
     * @return escaped url
     */
    private String escapeToLower(String url) {
        String encodedUrl = StringUtils.urlEncode(url, UNSAFE_URL_CHARS_PATTERN, Charset.forName("UTF-8"));
        return encodedUrl;
    }

    /**
     * Create a copy of this AuthToken
     *
     * @return a new AuthToken object
     */
    public AuthToken copy() {
        final AuthToken authToken = new AuthToken(key);
        authToken.tokenName = tokenName;
        authToken.startTime = startTime;
        authToken.expiration = expiration;
        authToken.ip = ip;
        authToken.acl = acl;
        authToken.duration = duration;
        return authToken;
    }

    /**
     * Merge this token with another, creating a new token. Other's members who are not <code>null</code> or <code>0</code> will override this object's members.
     *
     * @param other the token to merge from
     * @return a new token
     */
    public AuthToken merge(AuthToken other) {
        if (other.equals(NULL_AUTH_TOKEN)) {
            // NULL_AUTH_TOKEN can't merge
            return other;
        }
        AuthToken merged = new AuthToken();
        merged.key = other.key != null ? other.key : this.key;
        merged.tokenName = other.tokenName != null ? other.tokenName : this.tokenName;
        merged.startTime = other.startTime != 0 ? other.startTime : this.startTime;
        merged.expiration = other.expiration != 0 ? other.expiration : this.expiration;
        merged.ip = other.ip != null ? other.ip : this.ip;
        merged.acl = other.acl != null ? other.acl : this.acl;
        merged.duration = other.duration != 0 ? other.duration : this.duration;
        return merged;
    }

    private String digest(String message) {
        byte[] binKey = StringUtils.hexStringToByteArray(key);
        try {
            Mac hmac = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret = new SecretKeySpec(binKey, "HmacSHA256");
            hmac.init(secret);
            final byte[] bytes = message.getBytes();
            return StringUtils.encodeHexString(hmac.doFinal(bytes)).toLowerCase();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Cannot create authorization token.", e);
        } catch (InvalidKeyException e) {
            throw new RuntimeException("Cannot create authorization token.", e);
        }
    }

    private AuthToken setNull() {
        isNullToken = true;
        return this;
    }

    @Override
    public boolean equals(Object o) {
        if (o instanceof AuthToken) {
            AuthToken other = (AuthToken) o;
            return (isNullToken && other.isNullToken) ||
                    (key == null ? other.key == null : key.equals(other.key)) &&
                            tokenName.equals(other.tokenName) &&
                            startTime == other.startTime &&
                            expiration == other.expiration &&
                            duration == other.duration &&
                            (ip == null ? other.ip == null : ip.equals(other.ip)) &&
                            (acl == null ? other.acl == null : acl.equals(other.acl));
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        if (isNullToken) {
            return 0;
        } else {
            return Arrays.asList(tokenName, startTime, expiration, duration, ip, acl).hashCode();
        }
    }
}


================================================
FILE: cloudinary-core/src/main/java/com/cloudinary/BaseParam.java
================================================
package com.cloudinary;

import com.cloudinary.utils.StringUtils;

import java.util.List;

public class BaseParam {
    private String param;

    protected BaseParam(List<String> components) {
        this.param = StringUtils.join(components, ":");
    }

    protected BaseParam(String... components) {
        this.param = StringUtils.join(components, ":");
    }

    @Override
    public String toString() {
        return param;
    }
}


================================================
FILE: cloudinary-core/src/main/java/com/cloudinary/Cloudinary.java
================================================
package com.cloudinary;

import com.cloudinary.api.signing.ApiResponseSignatureVerifier;
import com.cloudinary.api.signing.NotificationRequestSignatureVerifier;
import com.cloudinary.strategies.AbstractApiStrategy;
import com.cloudinary.strategies.AbstractUploaderStrategy;
import com.cloudinary.strategies.StrategyLoader;
import com.cloudinary.utils.Analytics;
import com.cloudinary.utils.ObjectUtils;
import com.cloudinary.utils.StringUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.util.*;

import static com.cloudinary.Util.buildMultiParams;

@SuppressWarnings({"rawtypes", "unchecked"})
public class Cloudinary {

    public static List<String> UPLOAD_STRATEGIES = new ArrayList<String>(Arrays.asList(
            "com.cloudinary.android.UploaderStrategy",
            "com.cloudinary.http5.UploaderStrategy"));
    public static List<String> API_STRATEGIES = new ArrayList<String>(Arrays.asList(
            "com.cloudinary.android.ApiStrategy",
            "com.cloudinary.http5.ApiStrategy"));

    public final static String CF_SHARED_CDN = "d3jpl91pxevbkh.cloudfront.net";
    public final static String OLD_AKAMAI_SHARED_CDN = "cloudinary-a.akamaihd.net";
    public final static String AKAMAI_SHARED_CDN = "res.cloudinary.com";
    public final static String SHARED_CDN = AKAMAI_SHARED_CDN;

    public final static String VERSION = "2.3.1";
    static String USER_AGENT_PREFIX = "CloudinaryJava";
    public final static String USER_AGENT_JAVA_VERSION = "(Java " + System.getProperty("java.version") + ")";

    public final Configuration config;
    private AbstractUploaderStrategy uploaderStrategy;
    private AbstractApiStrategy apiStrategy;
    private String userAgent = USER_AGENT_PREFIX+"/"+ VERSION + " "+USER_AGENT_JAVA_VERSION;
    public Analytics analytics = new Analytics();
    public Uploader uploader() {
        return new Uploader(this, uploaderStrategy);
    }

    public Api api() {
        return new Api(this, apiStrategy);
    }

    public Search search() {
        return new Search(this);
    }

    public SearchFolders searchFolders() {
        return new SearchFolders(this);
    }

    public static void registerUploaderStrategy(String className) {
        if (!UPLOAD_STRATEGIES.contains(className)) {
            UPLOAD_STRATEGIES.add(0, className);
        }

    }

    public static void registerAPIStrategy(String className) {
        if (!API_STRATEGIES.contains(className)) {
            API_STRATEGIES.add(0, className);
        }
    }

    private void loadStrategies() {
        if (!this.config.loadStrategies) return;
        uploaderStrategy = StrategyLoader.find(UPLOAD_STRATEGIES);

        if (uploaderStrategy == null) {
            throw new UnknownError("Can't find Cloudinary platform adapter [" + StringUtils.join(UPLOAD_STRATEGIES, ",") + "]");
        }

        apiStrategy = StrategyLoader.find(API_STRATEGIES);
        if (apiStrategy == null) {
            throw new UnknownError("Can't find Cloudinary platform adapter [" + StringUtils.join(API_STRATEGIES, ",") + "]");
        }
    }

    public Cloudinary(Map config) {
        this(new Configuration(config));
    }

    public Cloudinary(String cloudinaryUrl) {
        this(Configuration.from(cloudinaryUrl));
    }

    public Cloudinary() {
        this(System.getProperty("CLOUDINARY_URL", System.getenv("CLOUDINARY_URL")) != null
                ? Configuration.from(System.getProperty("CLOUDINARY_URL", System.getenv("CLOUDINARY_URL")))
                : new Configuration());
    }

    public Cloudinary(Configuration config) {
        this.config = config;
        loadStrategies();
    }

    public Url url() {
        return new Url(this);
    }

    public String cloudinaryApiUrl(String action, Map options) {
        String cloudinary = ObjectUtils.asString(options.get("upload_prefix"),
                ObjectUtils.asString(this.config.uploadPrefix, "https://api.cloudinary.com"));
        String cloud_name = ObjectUtils.asString(options.get("cloud_name"), ObjectUtils.asString(this.config.cloudName));
        if (cloud_name == null)
            throw new IllegalArgumentException("Must supply cloud_name in tag or in configuration");
        String resource_type = ObjectUtils.asString(options.get("resource_type"), "image");
        return StringUtils.join(new String[]{cloudinary, "v1_1", cloud_name, resource_type, action}, "/");
    }

    private final static SecureRandom RND = new SecureRandom();

    public String randomPublicId() {
        byte[] bytes = new byte[8];
        RND.nextBytes(bytes);
        return StringUtils.encodeHexString(bytes);
    }

    public String signedPreloadedImage(Map result) {
        return result.get("resource_type") + "/upload/v" + result.get("version") + "/" + result.get("public_id")
                + (result.containsKey("format") ? "." + result.get("format") : "") + "#" + result.get("signature");
    }

    public String apiSignRequest(Map<String, Object> paramsToSign, String apiSecret, int signatureVersion) {
        return Util.produceSignature(paramsToSign, apiSecret, config.signatureAlgorithm, signatureVersion);
    }

    /**
     * @return the userAgent that will be sent with every API call.
     */
    public String getUserAgent(){
        return userAgent;
    }

    /**
     * Set the prefix and version for the user agent that will be sent with every API call
     * a userAgent is built from `prefix/version (additional data)`
     * @param prefix - the prefix of the userAgent to be set
     * @param version - the version of the userAgent to be set
     */
    public void setUserAgent(String prefix, String version){
        userAgent = prefix+"/"+ version + " ("+USER_AGENT_PREFIX+ " "+VERSION+") " + USER_AGENT_JAVA_VERSION;
    }

    /**
     * Set the analytics object that will be sent with every URL generation call.
     * @param analytics - the analytics object to set
     */
    public void setAnalytics(Analytics analytics) {
        this.analytics = analytics;
    }

    /**
     * Verifies that Cloudinary notification request is genuine by checking its signature.
     *
     * Cloudinary can asynchronously process your e.g. image uploads requests. This is achieved by calling back API you
     * specified during preparing of upload request as soon as it has been processed. See Upload Notifications in
     * Cloudinary documentation for more details. In order to make sure it is Cloudinary calling your API back, hashed
     * message authentication codes (HMAC's) based on agreed hashing function and configured Cloudinary API secret key
     * are used for signing the requests.
     *
     * The following method serves as a convenient utility to perform the verification procedure.
     *
     * @param body Cloudinary Notification request body represented as string
     * @param timestamp Cloudinary Notification request custom X-Cld-Timestamp HTTP header value
     * @param signature Cloudinary Notification request custom X-Cld-Signature HTTP header value, i.e. the HMAC
     * @param validFor desired period of request validity since issued, in seconds, for protection against replay attacks
     * @return whether request signature is valid or not
     */
    public boolean verifyNotificationSignature(String body, String timestamp, String signature, long validFor) {
        return new NotificationRequestSignatureVerifier(config.apiSecret, config.signatureAlgorithm).verifySignature(body, timestamp, signature, validFor);
    }

    /**
     * Verifies that Cloudinary API response is genuine by checking its signature.
     *
     * Cloudinary can add a signature value in the response to API methods returning public id's and versions. In order
     * to make sure it is genuine Cloudinary response, hashed message authentication codes (HMAC's) based on agreed hashing
     * function and configured Cloudinary API secret key are used for signing the responses.
     *
     * The following method serves as a convenient utility to perform the verification procedure.
     *
     * @param publicId publicId response field value
     * @param version version response field value
     * @param signature signature response field value, i.e. the HMAC
     * @return whether response signature is valid or not
     */
    public boolean verifyApiResponseSignature(String publicId, String version, String signature) {
        return new ApiResponseSignatureVerifier(config.apiSecret, config.signatureAlgorithm).verifySignature(publicId, version, signature);
    }

    public void signRequest(Map<String, Object> params, Map<String, Object> options) {
        String apiKey = ObjectUtils.asString(options.get("api_key"), this.config.apiKey);
        if (apiKey == null)
            throw new IllegalArgumentException("Must supply api_key");
        String apiSecret = ObjectUtils.asString(options.get("api_secret"), this.config.apiSecret);
        if (apiSecret == null)
            throw new IllegalArgumentException("Must supply api_secret");
        Util.clearEmpty(params);
        params.put("signature", this.apiSignRequest(params, apiSecret, this.config.signatureVersion));
        params.put("api_key", apiKey);
    }

    public String privateDownload(String publicId, String format, Map<String, Object> options) throws Exception {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("public_id", publicId);
        params.put("format", format);
        params.put("attachment", options.get("attachment"));
        params.put("type", options.get("type"));
        params.put("expires_at", options.get("expires_at"));
        params.put("timestamp", Util.timestamp());
        signRequest(params, options);
        return buildUrl(cloudinaryApiUrl("download", options), params);
    }

    public String zipDownload(String tag, Map<String, Object> options) throws Exception {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("timestamp", Util.timestamp());
        params.put("tag", tag);
        Object transformation = options.get("transformation");
        if (transformation != null) {
            if (transformation instanceof Transformation) {
                transformation = ((Transformation) transformation).generate();
            }
            params.put("transformation", transformation.toString());
        }
        params.put("transformation", transformation);
        signRequest(params, options);
        return buildUrl(cloudinaryApiUrl("download_tag.zip", options), params);
    }

    public String downloadArchive(Map<String, Object> options, String targetFormat) throws UnsupportedEncodingException {
        Map params = Util.buildArchiveParams(options, targetFormat);
        params.put("mode", ArchiveParams.MODE_DOWNLOAD);
        signRequest(params, options);
        return buildUrl(cloudinaryApiUrl("generate_archive", options), params);
    }

    public String downloadArchive(ArchiveParams params) throws UnsupportedEncodingException {
        return downloadArchive(params.toMap(), params.targetFormat());
    }

    public String downloadZip(Map<String, Object> options) throws UnsupportedEncodingException {
        return downloadArchive(options, "zip");
    }

    public String downloadGeneratedSprite(String tag, Map options) throws IOException {
        if (StringUtils.isEmpty(tag)) throw new IllegalArgumentException("Tag cannot be empty");

        if (options == null)
            options = new HashMap();

        options.put("tag", tag);
        options.put("mode", ArchiveParams.MODE_DOWNLOAD);

        Map params = Util.buildGenerateSpriteParams(options);
        signRequest(params, options);

        return buildUrl(cloudinaryApiUrl("sprite", options), params);
    }

    public String downloadGeneratedSprite(String[] urls, Map options) throws IOException {
        if (urls.length < 1) throw new IllegalArgumentException("Request must contain at least one URL.");
        if (options == null)
            options = new HashMap();

        options.put("urls", urls);
        options.put("mode", ArchiveParams.MODE_DOWNLOAD);

        Map params = Util.buildGenerateSpriteParams(options);
        signRequest(params, options);

        return buildUrl(cloudinaryApiUrl("sprite", options), params);
    }

    public String downloadMulti(String tag, Map options) throws IOException {
        if (StringUtils.isEmpty(tag)) throw new IllegalArgumentException("Tag cannot be empty");
        if (options == null)
            options = new HashMap();

        options.put("tag", tag);
        options.put("mode", ArchiveParams.MODE_DOWNLOAD);

        Map params = buildMultiParams(options);
        signRequest(params, options);

        return buildUrl(cloudinaryApiUrl("multi", options), params);
    }

    public String downloadMulti(String[] urls, Map options) throws IOException {
        if (urls.length < 1) throw new IllegalArgumentException("Request must contain at least one URL.");
        if (options == null)
            options = new HashMap();

        options.put("urls", urls);
        options.put("mode", ArchiveParams.MODE_DOWNLOAD);

        Map params = buildMultiParams(options);
        signRequest(params, options);

        return buildUrl(cloudinaryApiUrl("multi", options), params);
    }

    /**
     * Generates URL for executing "Download Folder" operation on Cloudinary site.
     * 
     * @param folderPath path of folder to generate download URL for
     * @param options    optional, holds hints for URL generation procedure, see documentation for full list
     * @return generated URL for downloading specified folder as ZIP archive
     */
    public String downloadFolder(String folderPath, Map options) throws UnsupportedEncodingException {
        if (StringUtils.isEmpty(folderPath)) {
            throw new IllegalArgumentException("Folder path parameter value is required");
        }

        Map adjustedOptions = new HashMap();
        if (options != null) {
            adjustedOptions.putAll(options);
        }

        adjustedOptions.put("prefixes", folderPath);

        final Object resourceType = adjustedOptions.get("resource_type");
        adjustedOptions.put("resource_type", resourceType != null ? resourceType : "all");

        return downloadArchive(adjustedOptions, (String) adjustedOptions.get("target_format"));
    }

    /**
     * Returns an URL of a specific version of a backed up asset that can be used to download that
     * version of the asset (within an hour of the request).
     *
     * @param assetId   The identifier of the uploaded asset.
     * @param versionId The identifier of a backed up version of the asset.
     * @param options   Optional, holds hints for URL generation procedure, see documentation for
     *                  full list
     * @return          The download URL of the asset
     */
    public String downloadBackedupAsset(String assetId, String versionId, Map options) throws UnsupportedEncodingException {
        if (StringUtils.isEmpty(assetId)) {
            throw new IllegalArgumentException("AssetId parameter is required");
        }

        if (StringUtils.isEmpty(versionId)) {
            throw new IllegalArgumentException("VersionId parameter is required");
        }

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("asset_id", assetId);
        params.put("version_id", versionId);
        params.put("timestamp", Util.timestamp());

        signRequest(params, options);
        return buildUrl(cloudinaryApiUrl("download_backup", options), params);
    }

    private String buildUrl(String base, Map<String, Object> params) throws UnsupportedEncodingException {
        StringBuilder urlBuilder = new StringBuilder();
        urlBuilder.append(base);
        if (!params.isEmpty()) {
            urlBuilder.append("?");
        }
        boolean first = true;
        for (Map.Entry<String, Object> param : params.entrySet()) {
            if (param.getValue() == null) continue;

            String keyValue = null;
            Object value = param.getValue();
            if (!first) urlBuilder.append("&");
            if (value instanceof Object[])
                value = Arrays.asList(value);
            if (value instanceof Collection) {
                String key = param.getKey() + "[]=";
                Collection<Object> items = (Collection) value;
                List<String> encodedItems = new ArrayList<String>();
                for (Object item : items)
                    encodedItems.add(URLEncoder.encode(item.toString(), "UTF-8"));
                keyValue = key + StringUtils.join(encodedItems, "&" + key);
            } else {
                keyValue = param.getKey() + "=" +
                        URLEncoder.encode(value.toString(), "UTF-8");
            }
            urlBuilder.append(keyValue);
            first = false;
        }
        return urlBuilder.toString();
    }
}


================================================
FILE: cloudinary-core/src/main/java/com/cloudinary/Configuration.java
================================================
package com.cloudinary;

import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

import com.cloudinary.utils.ObjectUtils;
import com.cloudinary.utils.StringUtils;

/**
 * Configuration object for a {@link Cloudinary} instance
 */
public class Configuration {
    public final static String CF_SHARED_CDN = "d3jpl91pxevbkh.cloudfront.net";
    public final static String OLD_AKAMAI_SHARED_CDN = "cloudinary-a.akamaihd.net";
    public final static String AKAMAI_SHARED_CDN = "res.cloudinary.com";
    public final static String SHARED_CDN = AKAMAI_SHARED_CDN;
    public final static String VERSION = "1.0.2";
    public final static String USER_AGENT = "cld-android-" + VERSION;
    public static final boolean DEFAULT_IS_LONG_SIGNATURE = false;
    public static final SignatureAlgorithm DEFAULT_SIGNATURE_ALGORITHM = SignatureAlgorithm.SHA1;
    public static final int DEFAULT_SIGNATURE_VERSION = 2;

    private static final String CONFIG_PROP_SIGNATURE_ALGORITHM = "signature_algorithm";

    public String cloudName;
    public String apiKey;
    public String apiSecret;
    public String secureDistribution;
    public String cname;
    public String uploadPrefix;
    public boolean secure;
    public boolean privateCdn;
    public boolean cdnSubdomain;
    public boolean shorten;
    public String callback;
    public String proxyHost;
    public int proxyPort;
    public Map<String, Object> properties = new HashMap<String, Object>();
    public Boolean secureCdnSubdomain;
    public boolean useRootPath;
    public boolean useFetchFormat;
    public int timeout;
    public boolean loadStrategies = true;
    public boolean clientHints = false;
    public AuthToken authToken;
    public boolean forceVersion = true;
    public boolean longUrlSignature = DEFAULT_IS_LONG_SIGNATURE;
    public SignatureAlgorithm signatureAlgorithm = DEFAULT_SIGNATURE_ALGORITHM;
    public int signatureVersion = DEFAULT_SIGNATURE_VERSION;
    public String oauthToken = null;
    public Boolean analytics;
    public Configuration() {
    }

    private Configuration(
            String cloudName,
            String apiKey,
            String apiSecret,
            String secureDistribution,
            String cname,
            String uploadPrefix,
            boolean secure,
            boolean privateCdn,
            boolean cdnSubdomain,
            boolean shorten,
            String callback,
            String proxyHost,
            int proxyPort,
            Boolean secureCdnSubdomain,
            boolean useRootPath,
            boolean useFetchFormat,
            int timeout,
            boolean loadStrategies,
            boolean forceVersion,
            boolean longUrlSignature,
            SignatureAlgorithm signatureAlgorithm,
            int signatureVersion,
            String oauthToken,
            boolean analytics) {
        this.cloudName = cloudName;
        this.apiKey = apiKey;
        this.apiSecret = apiSecret;
        this.secureDistribution = secureDistribution;
        this.cname = cname;
        this.uploadPrefix = uploadPrefix;
        this.secure = secure;
        this.privateCdn = privateCdn;
        this.cdnSubdomain = cdnSubdomain;
        this.shorten = shorten;
        this.callback = callback;
        this.proxyHost = proxyHost;
        this.proxyPort = proxyPort;
        this.secureCdnSubdomain = secureCdnSubdomain;
        this.useRootPath = useRootPath;
        this.useFetchFormat = useFetchFormat;
        this.timeout = timeout;
        this.loadStrategies = loadStrategies;
        this.forceVersion = forceVersion;
        this.longUrlSignature = longUrlSignature;
        this.signatureAlgorithm = signatureAlgorithm;
        this.signatureVersion = signatureVersion;
        this.oauthToken = oauthToken;
        this.analytics = analytics;
    }

    @SuppressWarnings("rawtypes")
    public Configuration(Map config) {
        update(config);
    }

    @SuppressWarnings("rawtypes")
    public void update(Map config) {
        this.cloudName = (String) config.get("cloud_name");
        this.apiKey = (String) config.get("api_key");
        this.apiSecret = (String) config.get("api_secret");
        this.secureDistribution = (String) config.get("secure_distribution");
        this.cname = (String) config.get("cname");
        this.secure = ObjectUtils.asBoolean(config.get("secure"), true);
        this.privateCdn = ObjectUtils.asBoolean(config.get("private_cdn"), false);
        this.cdnSubdomain = ObjectUtils.asBoolean(config.get("cdn_subdomain"), false);
        this.shorten = ObjectUtils.asBoolean(config.get("shorten"), false);
        this.uploadPrefix = (String) config.get("upload_prefix");
        this.callback = (String) config.get("callback");
        this.proxyHost = (String) config.get("proxy_host");
        this.proxyPort = ObjectUtils.asInteger(config.get("proxy_port"), 0);
        this.secureCdnSubdomain = ObjectUtils.asBoolean(config.get("secure_cdn_subdomain"), null);
        this.useRootPath = ObjectUtils.asBoolean(config.get("use_root_path"), false);
        this.useFetchFormat = ObjectUtils.asBoolean(config.get("use_fetch_format"), false);
        this.loadStrategies = ObjectUtils.asBoolean(config.get("load_strategies"), true);
        this.timeout = ObjectUtils.asInteger(config.get("timeout"), 0);
        this.clientHints = ObjectUtils.asBoolean(config.get("client_hints"), false);
        this.analytics = ObjectUtils.asBoolean(config.get("analytics"), true);
        Map tokenMap = (Map) config.get("auth_token");
        if (tokenMap != null) {
            this.authToken = new AuthToken(tokenMap);
        }
        this.forceVersion = ObjectUtils.asBoolean(config.get("force_version"), true);
        Map properties = (Map) config.get("properties");
        if (properties != null) {
            this.properties.putAll(properties);
        }
        this.longUrlSignature = ObjectUtils.asBoolean(config.get("long_url_signature"), DEFAULT_IS_LONG_SIGNATURE);
        this.signatureAlgorithm = SignatureAlgorithm.valueOf(ObjectUtils.asString(config.get(CONFIG_PROP_SIGNATURE_ALGORITHM), DEFAULT_SIGNATURE_ALGORITHM.name()));
        this.signatureVersion = ObjectUtils.asInteger(config.get("signature_version"), DEFAULT_SIGNATURE_VERSION);
        this.oauthToken = (String) config.get("oauth_token");

    }

    @SuppressWarnings("rawtypes")
    public Map<String, Object> asMap() {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("cloud_name", cloudName);
        map.put("api_key", apiKey);
        map.put("api_secret", apiSecret);
        map.put("secure_distribution", secureDistribution);
        map.put("cname", cname);
        map.put("secure", secure);
        map.put("private_cdn", privateCdn);
        map.put("cdn_subdomain", cdnSubdomain);
        map.put("shorten", shorten);
        map.put("upload_prefix", uploadPrefix);
        map.put("callback", callback);
        map.put("proxy_host", proxyHost);
        map.put("proxy_port", proxyPort);
        map.put("secure_cdn_subdomain", secureCdnSubdomain);
        map.put("use_root_path", useRootPath);
        map.put("use_fetch_format", useFetchFormat);
        map.put("load_strategies", loadStrategies);
        map.put("timeout", timeout);
        map.put("client_hints", clientHints);
        if (authToken != null) {
            map.put("auth_token", authToken.asMap());
        }
        map.put("force_version", forceVersion);
        map.put("properties", new HashMap<String,Object>(properties));
        map.put("long_url_signature", longUrlSignature);
        map.put(CONFIG_PROP_SIGNATURE_ALGORITHM, signatureAlgorithm.toString());
        map.put("signature_version", signatureVersion);
        map.put("oauth_token", oauthToken);
        map.put("analytics", analytics);
        return map;
    }


    public Configuration(Configuration other) {
        this.cloudName = other.cloudName;
        this.apiKey = other.apiKey;
        this.apiSecret = other.apiSecret;
        this.secureDistribution = other.secureDistribution;
        this.cname = other.cname;
        this.uploadPrefix = other.uploadPrefix;
        this.secure = other.secure;
        this.privateCdn = other.privateCdn;
        this.cdnSubdomain = other.cdnSubdomain;
        this.shorten = other.shorten;
        this.callback = other.callback;
        this.proxyHost = other.proxyHost;
        this.proxyPort = other.proxyPort;
        this.secureCdnSubdomain = other.secureCdnSubdomain;
        this.useRootPath = other.useRootPath;
        this.useFetchFormat = other.useFetchFormat;
        this.timeout = other.timeout;
        this.clientHints = other.clientHints;
        if (other.authToken != null) {
            this.authToken = other.authToken.copy();
        }
        this.forceVersion = other.forceVersion;
        this.loadStrategies = other.loadStrategies;
        this.properties.putAll(other.properties);
        this.longUrlSignature = other.longUrlSignature;
        this.signatureAlgorithm = other.signatureAlgorithm;
        this.signatureVersion = other.signatureVersion;
        this.oauthToken = other.oauthToken;
        this.analytics = other.analytics;
    }

    /**
     * Create a new Configuration from an existing one
     *
     * @param other
     * @return a new configuration with the arguments supplied by another configuration object
     */
    public static Configuration from(Configuration other) {
        return new Builder().from(other).build();
    }

    /**
     * Create a Configuration from a cloudinary url
     * <p>
     * Example url: cloudinary://123456789012345:abcdeghijklmnopqrstuvwxyz12@n07t21i7
     *
     * @param cloudinaryUrl configuration url
     * @return a new configuration with the arguments supplied by the url
     */
    public static Configuration from(String cloudinaryUrl) {
        Configuration config = new Configuration();
        config.update(parseConfigUrl(cloudinaryUrl));
        return config;
    }


    static protected Map parseConfigUrl(String cloudinaryUrl) {
        Map params = new HashMap();
        URI cloudinaryUri = URI.create(cloudinaryUrl);
        if (cloudinaryUri.getScheme() == null || !cloudinaryUri.getScheme().equalsIgnoreCase("cloudinary")){
            throw new IllegalArgumentException("Invalid CLOUDINARY_URL scheme. Expecting to start with 'cloudinary://'");
        }
        params.put("cloud_name", cloudinaryUri.getHost());
        if (cloudinaryUri.getUserInfo() != null) {
            String[] creds = cloudinaryUri.getUserInfo().split(":");
            params.put("api_key", creds[0]);
            if (creds.length > 1) {
                params.put("api_secret", creds[1]);
            }
        }
        params.put("private_cdn", !StringUtils.isEmpty(cloudinaryUri.getPath()));
        params.put("secure_distribution", cloudinaryUri.getPath());
        updateMapfromURI(params, cloudinaryUri);
        return params;
    }

    static private void updateMapfromURI(Map params, URI cloudinaryUri) {
        if (cloudinaryUri.getQuery() != null) {
            for (String param : cloudinaryUri.getQuery().split("&")) {
                String[] keyValue = param.split("=");
                try {
                    final String value = URLDecoder.decode(keyValue[1], "ASCII");
                    final String key = keyValue[0];
                    if(isNestedKey(key)) {
                        putNestedValue(params, key, value);
                    } else {
                        params.put(key, value);
                    }
                } catch (UnsupportedEncodingException e) {
                    throw new RuntimeException("Unexpected exception", e);
                }
            }
        }
    }

    static private void putNestedValue(Map params, String key, String value) {
        String[] chain = key.split("[\\[\\]]+");
        Map outer = params;
        String innerKey = chain[0];
        for (int i = 0; i < chain.length -1; i++, innerKey = chain[i]) {
            Map inner = (Map) outer.get(innerKey);
            if (inner == null) {
                inner = new HashMap();
                outer.put(innerKey, inner);
            }
            outer = inner;
        }
        outer.put(innerKey, value);
    }

    static private boolean isNestedKey(String key) {
        return key.matches("\\w+\\[\\w+\\]");
    }

    /**
     * Build a new {@link Configuration}
     */
    public static class Builder {
        private String cloudName;
        private String apiKey;
        private String apiSecret;
        private String secureDistribution;
        private String cname;
        private String uploadPrefix;
        private boolean secure;
        private boolean privateCdn;
        private boolean cdnSubdomain;
        private boolean shorten;
        private String callback;
        private String proxyHost;
        private int proxyPort;
        private Boolean secureCdnSubdomain;
        private boolean useRootPath;
        private boolean useFetchFormat;
        private boolean loadStrategies = true;
        private int timeout;
        private boolean clientHints = false;
        private AuthToken authToken;
        private boolean forceVersion = true;
        private boolean longUrlSignature = DEFAULT_IS_LONG_SIGNATURE;
        private SignatureAlgorithm signatureAlgorithm = DEFAULT_SIGNATURE_ALGORITHM;
        private int signatureVersion = DEFAULT_SIGNATURE_VERSION;
        private String oauthToken = null;
        private boolean analytics;

        /**
         * Set the HTTP connection timeout.
         *
         * @param timeout time in seconds, or 0 to use the default platform value
         * @return builder for chaining
         */
        public Builder setTimeout(int timeout) {
            this.timeout = timeout;
            return this;
        }

        /**
         * Creates a {@link Configuration} with the arguments supplied to this builder
         */
        public Configuration build() {
            final Configuration configuration = new Configuration(
                            cloudName,
                            apiKey,
                            apiSecret,
                            secureDistribution,
                            cname,
                            uploadPrefix,
                            secure,
                            privateCdn,
                            cdnSubdomain,
                            shorten,
                            callback,
                            proxyHost,
                            proxyPort,
                            secureCdnSubdomain,
                            useRootPath,
                            useFetchFormat,
                            timeout,
                            loadStrategies,
                            forceVersion,
                            longUrlSignature,
                            signatureAlgorithm,
                            signatureVersion,
                            oauthToken,
                            analytics);
            configuration.clientHints = clientHints;
            return configuration;
        }

        /**
         * The unique name of your cloud at Cloudinary
         * You can find your cloud name in the Account Details section in the dashboard of Cloudinary Management Console.
         */
        public Builder setCloudName(String cloudName) {
            this.cloudName = cloudName;
            return this;
        }

        /**
         * API Key
         * You can find API Key in the Account Details section in the dashboard of Cloudinary Management Console.
         */
        public Builder setApiKey(String apiKey) {
            this.apiKey = apiKey;
            return this;
        }

        /**
         * API Secret
         * You can find API Secret in the Account Details section in the dashboard of Cloudinary Management Console.
         */
        public Builder setApiSecret(String apiSecret) {
            this.apiSecret = apiSecret;
            return this;
        }

        /**
         * The domain name of the CDN distribution to use for building HTTPS URLs.
         * Relevant only for Advanced plan's users that have a private CDN distribution.
         */
        public Builder setSecureDistribution(String secureDistribution) {
            this.secureDistribution = secureDistribution;
            return this;
        }

        /**
         * Custom domain name to use for building HTTP URLs.
         * Relevant only for Advanced plan's users that have a private CDN distribution and a custom CNAME.
         */
        public Builder setCname(String cname) {
            this.cname = cname;
            return this;
        }

        /**
         * Force HTTPS URLs of images even if embedded in non-secure HTTP pages.
         */
        public Builder setSecure(boolean secure) {
            this.secure = secure;
            return this;
        }

        /**
         * Should be set to true for Advanced plan's users that have a private CDN distribution.
         */
        public Builder setPrivateCdn(boolean privateCdn) {
            this.privateCdn = privateCdn;
            return this;
        }

        public Builder setSecureCdnSubdomain(Boolean secureCdnSubdomain) {
            this.secureCdnSubdomain = secureCdnSubdomain;
            return this;
        }


        /**
         * Whether to automatically build URLs with multiple CDN sub-domains.
         */
        public Builder setCdnSubdomain(boolean cdnSubdomain) {
            this.cdnSubdomain = cdnSubdomain;
            return this;
        }

        public Builder setShorten(boolean shorten) {
            this.shorten = shorten;
            return this;
        }

        public Builder setCallback(String callback) {
            this.callback = callback;
            return this;
        }

        public Builder setUploadPrefix(String uploadPrefix) {
            this.uploadPrefix = uploadPrefix;
            return this;
        }

        public Builder setUseRootPath(boolean useRootPath) {
            this.useRootPath = useRootPath;
            return this;
        }

        public Builder setUseFetchFormat(boolean useFetchFormat) {
            this.useFetchFormat = useFetchFormat;
            return this;
        }

        public Builder setLoadStrategies(boolean loadStrategies) {
            this.loadStrategies = loadStrategies;
            return this;
        }

        public Builder setAnalytics(boolean analytics) {
            this.analytics = analytics;
            return this;
        }

        public Builder setClientHints(boolean clientHints) {
            this.clientHints = clientHints;
            return this;
        }

        public Builder setAuthToken(AuthToken authToken) {
            this.authToken = authToken;
            return this;
        }
        public Builder setForceVersion(boolean forceVersion) {
            this.forceVersion = forceVersion;
            return this;
        }

        public Builder setIsLongUrlSignature(boolean isLong) {
            this.longUrlSignature = isLong;
            return this;
        }

        public Builder setSignatureAlgorithm(SignatureAlgorithm signatureAlgorithm) {
            this.signatureAlgorithm = signatureAlgorithm;
            return this;
        }

        public Builder setSignatureVersion(int signatureVersion) {
            this.signatureVersion = signatureVersion;
            return this;
        }

        public Builder setOAuthToken(String oauthToken) {
            this.oauthToken = oauthToken;
            return this;
        }

        /**
         * Initialize builder from existing {@link Configuration}
         *
         * @param other a different configuration object
         * @return an initialized builder configured with <code>other</code>
         */
        public Builder from(Configuration other) {
            this.cloudName = other.cloudName;
            this.apiKey = other.apiKey;
            this.apiSecret = other.apiSecret;
            this.secureDistribution = other.secureDistribution;
            this.cname = other.cname;
            this.uploadPrefix = other.uploadPrefix;
            this.secure = other.secure;
            this.privateCdn = other.privateCdn;
            this.cdnSubdomain = other.cdnSubdomain;
            this.shorten = other.shorten;
            this.callback = other.callback;
            this.proxyHost = other.proxyHost;
            this.proxyPort = other.proxyPort;
            this.secureCdnSubdomain = other.secureCdnSubdomain;
            this.useRootPath = other.useRootPath;
            this.useFetchFormat = other.useFetchFormat;
            this.loadStrategies = other.loadStrategies;
            this.timeout = other.timeout;
            this.clientHints = other.clientHints;
            this.authToken = other.authToken == null ? null : other.authToken.copy();
            this.forceVersion = other.forceVersion;
            this.longUrlSignature = other.longUrlSignature;
            this.signatureAlgorithm = other.signatureAlgorithm;
            this.signatureVersion = other.signatureVersion;
            this.oauthToken = other.oauthToken;
            this.analytics = other.analytics;
            return this;
        }
    }
}


================================================
FILE: cloudinary-core/src/main/java/com/cloudinary/Coordinates.java
================================================
package com.cloudinary;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;

import com.cloudinary.utils.Rectangle;
import com.cloudinary.utils.StringUtils;

public class Coordinates implements Serializable{

    Collection<Rectangle> coordinates = new ArrayList<Rectangle>();

    public Coordinates() {
    }

    public Coordinates(Collection<Rectangle> coordinates) {
        this.coordinates = coordinates;
    }

    public Coordinates(int[] rect) {
        Collection<Rectangle> coordinates = new ArrayList<Rectangle>();
        if (rect.length != 4) {
            throw new IllegalArgumentException("Must supply exactly 4 values for coordinates (x,y,width,height)");
        }
        coordinates.add(new Rectangle(rect[0], rect[1], rect[2], rect[3]));
        this.coordinates = coordinates;
    }

    public Coordinates(Rectangle rect) {
        Collection<Rectangle> coordinates = new ArrayList<Rectangle>();
        coordinates.add(rect);
        this.coordinates = coordinates;
    }

    public Coordinates(String stringCoords) throws IllegalArgumentException {
        Collection<Rectangle> coordinates = new ArrayList<Rectangle>();
        for (String stringRect : stringCoords.split("\\|")) {
            if (StringUtils.isEmpty(stringRect))
                continue;
            String[] elements = stringRect.split(",");
            if (elements.length != 4) {
                throw new IllegalArgumentException(String.format("Must supply exactly 4 values for coordinates (x,y,width,height) %d supplied: %s",
                        elements.length, stringRect));
            }
            coordinates.add(new Rectangle(Integer.parseInt(elements[0]), Integer.parseInt(elements[1]), Integer.parseInt(elements[2]), Integer
                    .parseInt(elements[3])));
        }
        this.coordinates = coordinates;
    }

    public static Coordinates parseCoordinates(Object coordinates) throws IllegalArgumentException {
        if (coordinates instanceof Coordinates) {
            return (Coordinates) coordinates;
        } else if (coordinates instanceof int[]) {
            return new Coordinates((int[]) coordinates);
        } else if (coordinates instanceof Rectangle) {
            return new Coordinates((Rectangle) coordinates);
        } else {
            return new Coordinates(coordinates.toString());
        }
    }

    public void addRect(Rectangle rect) {
        this.coordinates.add(rect);
    }

    public Collection<Rectangle> underlaying() {
        return this.coordinates;
    }

    @Override
    public String toString() {
        ArrayList<String> rects = new ArrayList<String>();
        for (Rectangle rect : this.coordinates) {
            rects.add(rect.x + "," + rect.y + "," + rect.width + "," + rect.height);
        }
        return StringUtils.join(rects, "|");
    }

}


================================================
FILE: cloudinary-core/src/main/java/com/cloudinary/CustomFunction.java
================================================
package com.cloudinary;

import com.cloudinary.utils.Base64Coder;

/**
 * Helper class to generate a custom function params to be used in {@link Transformation#customFunction(CustomFunction)}.
 */
public class CustomFunction extends BaseParam{

    private CustomFunction(String... components) {
        super(components);
    }

    /**
     * Generate a web-assembly custom action param to send to {@link Transformation#customFunction(CustomFunction)}
     * @param publicId The public id of the web-assembly file
     * @return A new instance of custom action param
     */
    public static CustomFunction wasm(String publicId){
        return new CustomFunction("wasm", publicId);
    }

    /**
     * Generate a remote lambda custom action param to send to {@link Transformation#customFunction(CustomFunction)}
     * @param url   The public url of the aws lambda function
     * @return A new instance of custom action param
     */
    public static CustomFunction remote(String url){
        return new CustomFunction("remote", Base64Coder.encodeURLSafeString(url));
    }
}


================================================
FILE: cloudinary-core/src/main/java/com/cloudinary/EagerTransformation.java
================================================
package com.cloudinary;

import com.cloudinary.utils.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class EagerTransformation extends Transformation<EagerTransformation> {
    protected String format;

    @SuppressWarnings("rawtypes")
    public EagerTransformation(List<Map> transformations) {
        super(transformations);
    }

    public EagerTransformation() {
        super();
    }

    public EagerTransformation format(String format) {
        this.format = format;
        return this;
    }

    public String getFormat() {
        return format;
    }

    @Override
    public String generate(Iterable<Map> optionsList) {
        List<String> components = new ArrayList<String>();
        for (Map options : optionsList) {
            if (options.size() > 0) {
                components.add(super.generate(options));
            }
        }

        if (format != null){
            components.add(format);
        }

        return StringUtils.join(components, "/");
    }

    @Override
    public String generate(Map options) {
        List<String> eager = new ArrayList<String>();
        eager.add(super.generate(options));

        if (format != null){
            eager.add(format);
        }

        return StringUtils.join(eager, "/");
    }
}


================================================
FILE: cloudinary-core/src/main/java/com/cloudinary/ProgressCallback.java
================================================
package com.cloudinary;

/**
 * Defines a callback for network operations.
 */
public interface ProgressCallback {
    /**
     * Invoked during network operation.
     * @param bytesUploaded the number of bytes uploaded so far
     * @param totalBytes the total number of byte to upload - if known
     */
    void onProgress(long bytesUploaded, long totalBytes);
}


================================================
FILE: cloudinary-core/src/main/java/com/cloudinary/ResponsiveBreakpoint.java
================================================
package com.cloudinary;

import org.cloudinary.json.JSONObject;

public class ResponsiveBreakpoint extends JSONObject {
    public ResponsiveBreakpoint() {
        put("create_derived", true);
    }

    public boolean isCreateDerived() {
        return optBoolean("create_derived");
    }

    public ResponsiveBreakpoint createDerived(boolean createDerived) {
        put("create_derived", createDerived);
        return this;
    }

    public Transformation transformation() {
        return (Transformation) opt("transformation");
    }

    public ResponsiveBreakpoint transformation(Transformation transformation) {
        put("transformation", transformation);
        return this;
    }

    public ResponsiveBreakpoint format(String format) {
        put("format", format);
        return this;
    }

    public String format() {
        return optString("format");
    }

    public int maxWidth() {
        return optInt("max_width");
    }

    public ResponsiveBreakpoint maxWidth(int maxWidth) {
        put("max_width", maxWidth);
        return this;
    }

    public int minWidth() {
        return optInt("min_width");
    }

    public ResponsiveBreakpoint minWidth(Integer minWidth) {
        put("min_width", minWidth);
        return this;
    }

    public int bytesStep() {
        return optInt("bytes_step");
    }

    public ResponsiveBreakpoint bytesStep(Integer bytesStep) {
        put("bytes_step", bytesStep);
        return this;
    }

    public int maxImages() {
        return optInt("max_images");
    }

    public ResponsiveBreakpoint maxImages(Integer maxImages) {
        put("max_images", maxImages);
        return this;
    }
}


================================================
FILE: cloudinary-core/src/main/java/com/cloudinary/Search.java
================================================
package com.cloudinary;

import com.cloudinary.api.ApiResponse;
import com.cloudinary.utils.Base64Coder;
import com.cloudinary.utils.ObjectUtils;
import com.cloudinary.utils.StringUtils;
import org.cloudinary.json.JSONObject;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class Search {

    protected final Api api;
    private ArrayList<HashMap<String, Object>> sortByParam;
    private ArrayList<String> aggregateParam;
    private ArrayList<String> withFieldParam;
    private HashMap<String, Object> params;
    private ArrayList<String> fields;

    private int ttl = 300;

    Search(Cloudinary cloudinary) {
        this.api = cloudinary.api();
        this.params = new HashMap<String, Object>();
        this.sortByParam = new ArrayList<HashMap<String, Object>>();
        this.aggregateParam = new ArrayList<String>();
        this.withFieldParam = new ArrayList<String>();
        this.fields = new ArrayList<String>();
    }

    public Search ttl(int ttl) {
        this.ttl = ttl;
        return this;
    }
    public Search expression(String value) {
        this.params.put("expression", value);
        return this;
    }

    public Search maxResults(Integer value) {
        this.params.put("max_results", value);
        return this;
    }

    public Search nextCursor(String value) {
        this.params.put("next_cursor", value);
        return this;
    }

    public Search aggregate(String field) {
        if (!aggregateParam.contains(field)) {
            aggregateParam.add(field);
        }
        return this;
    }

    public Search withField(String field) {
        if (!withFieldParam.contains(field)) {
            withFieldParam.add(field);
        }
        return this;
    }

    public Search sortBy(String field, String dir) {
        HashMap<String, Object> sortBucket = new HashMap<String, Object>();
        sortBucket.put(field, dir);
        for (int i = 0; i < sortByParam.size(); i++) {
            if (sortByParam.get(i).containsKey(field)){
                sortByParam.add(i, sortBucket);
                return this;
            }
        }
        sortByParam.add(sortBucket);
        return this;
    }

    public Search fields(String field) {
        if (!fields.contains(field)) {
            fields.add(field);
        }
        return this;
    }

    public HashMap<String, Object> toQuery() {
        HashMap<String, Object> queryParams = new HashMap<String, Object>(this.params);
        if (withFieldParam.size() > 0) {
            queryParams.put("with_field", withFieldParam);
        }
        if(sortByParam.size() > 0) {
            queryParams.put("sort_by", sortByParam);
        }
        if(aggregateParam.size() > 0) {
            queryParams.put("aggregate", aggregateParam);
        }
        if(fields.size() > 0) {
            queryParams.put("fields", fields);
        }
        return queryParams;
    }

    public ApiResponse execute() throws Exception {
        Map<String, String> options = ObjectUtils.asMap("content_type", "json");
        return this.api.callApi(Api.HttpMethod.POST, Arrays.asList("resources", "search"), this.toQuery(), options);
    }


    public String toUrl() throws Exception {
        return toUrl(null, null);
    }

    public String toUrl(String nextCursor) throws Exception {
        return toUrl(null, nextCursor);
    }
    /***
     Creates a signed Search URL that can be used on the client side.
     ***/
    public String toUrl(Integer ttl, String nextCursor) throws Exception {
        String nextCursorParam = nextCursor;
        String apiSecret = api.cloudinary.config.apiSecret;
        if (apiSecret == null) throw new IllegalArgumentException("Must supply api_secret");
        if(ttl == null) {
            ttl = this.ttl;
        }
        HashMap queryParams = toQuery();
        if(nextCursorParam == null) {
            nextCursorParam = (String) queryParams.get("next_cursor");
        }
        queryParams.remove("next_cursor");
        JSONObject json = ObjectUtils.toJSON(queryParams);
        String base64Query = Base64Coder.encodeURLSafeString(json.toString());
        String signature = StringUtils.encodeHexString(Util.hash(String.format("%d%s%s", ttl, base64Query, apiSecret), SignatureAlgorithm.SHA256));
        String prefix = Url.unsignedDownloadUrlPrefix(null,api.cloudinary.config);

        return String.format("%s/search/%s/%d/%s%s", prefix, signature, ttl, base64Query,nextCursorParam != null && !nextCursorParam.isEmpty() ? "/"+nextCursorParam : "");
    }
}


================================================
FILE: cloudinary-core/src/main/java/com/cloudinary/SearchFolders.java
================================================
package com.cloudinary;

import com.cloudinary.api.ApiResponse;
import com.cloudinary.utils.ObjectUtils;

import java.util.Arrays;
import java.util.Map;

public class SearchFolders extends Search {

    public SearchFolders(Cloudinary cloudinary) {
        super(cloudinary);
    }

    public ApiResponse execute() throws Exception {
        Map<String, String> options = ObjectUtils.asMap("content_type", "json");
        return this.api.callApi(Api.HttpMethod.POST, Arrays.asList("folders", "search"), this.toQuery(), options);
    }
}


================================================
FILE: cloudinary-core/src/main/java/com/cloudinary/SignatureAlgorithm.java
================================================
package com.cloudinary;

/**
 * Defines supported algorithms for generating/verifying hashed message authentication codes (HMAC).
 */
public enum SignatureAlgorithm {
    SHA1("SHA-1"),
    SHA256("SHA-256");

    private final String algorithmId;

    SignatureAlgorithm(String algorithmId) {
        this.algorithmId = algorithmId;
    }

    public String getAlgorithmId() {
        return algorithmId;
    }
}


================================================
FILE: cloudinary-core/src/main/java/com/cloudinary/SmartUrlEncoder.java
================================================
package com.cloudinary;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

public final class SmartUrlEncoder {
    private SmartUrlEncoder() {}

    public static String encode(String input) {
        try {
            return URLEncoder.encode(input, "UTF-8").replace("%2F", "/").replace("%3A", ":").replace("+", "%20");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }
}


================================================
FILE: cloudinary-core/src/main/java/com/cloudinary/StoredFile.java
================================================
package com.cloudinary;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StoredFile {
    protected Long version;

    protected String publicId;

    protected String format;

    protected String signature;

    protected String type = "upload";

    protected String resourceType = "image";

    private static final String IMAGE_RESOURCE_TYPE = "image";

    private static final String VIDEO_RESOURCE_TYPE = "video";

    private static final String AUTO_RESOURCE_TYPE = "auto";

    private static final Pattern PRELOADED_PATTERN = Pattern.compile("^([^\\/]+)\\/([^\\/]+)\\/v(\\d+)\\/([^#]+)#?([^\\/]+)?$");

    public Long getVersion() {
        return version;
    }

    public void setVersion(Long version) {
        this.version = version;
    }

    public String getPublicId() {
        return publicId;
    }

    public void setPublicId(String publicId) {
        this.publicId = publicId;
    }

    protected String getPublicIdForSigning() {
        return publicId + ((format != null && !format.isEmpty() && resourceType.equals("raw")) ? "." + format : "");
    }

    public String getFormat() {
        return format;
    }

    public void setFormat(String format) {
        this.format = format;
    }

    public String getSignature() {
        return signature;
    }

    public void setSignature(String signature) {
        this.signature = signature;
    }

    public String getResourceType() {
        return resourceType;
    }

    public void setResourceType(String resourceType) {
        this.resourceType = resourceType;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getPreloadedFile() {
        StringBuilder sb = new StringBuilder();
        sb.append(resourceType).append("/").append(type).append("/v").append(version).append("/").append(publicId);
        if (format != null && !format.isEmpty()) {
            sb.append(".").append(format);
        }
        if (signature != null && !signature.isEmpty()) {
            sb.append("#").append(signature);
        }
        return sb.toString();
    }

    public void setPreloadedFile(String uri) {
        if (uri.matches(PRELOADED_PATTERN.pattern())) {
            Matcher match = PRELOADED_PATTERN.matcher(uri);
            match.find();
            resourceType = match.group(1);
            type = match.group(2);
            version = Long.parseLong(match.group(3));
            String filename = match.group(4);
            if (match.groupCount() == 5)
                signature = match.group(5);
            int lastDotIndex = filename.lastIndexOf('.');
            if (lastDotIndex == -1) {
                publicId = filename;
            } else {
                publicId = filename.substring(0, lastDotIndex);
                format = filename.substring(lastDotIndex + 1);
            }
        }
    }

    public String getComputedSignature(Cloudinary cloudinary) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("version", getVersion().toString());
        params.put("public_id", getPublicIdForSigning());
        cloudinary.signRequest(params, new HashMap<String, Object>());
        return params.get("signature").toString();
    }

    public boolean getIsImage() {
        return IMAGE_RESOURCE_TYPE.equals(resourceType) || AUTO_RESOURCE_TYPE.equals(resourceType);
    }

    public boolean getIsVideo() {
        return VIDEO_RESOURCE_TYPE.equals(resourceType);
    }
}


================================================
FILE: cloudinary-core/src/main/java/com/cloudinary/Transformation.java
================================================
package com.cloudinary;

import java.io.Serializable;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.cloudinary.transformation.AbstractLayer;
import com.cloudinary.transformation.Condition;
import com.cloudinary.transformation.Expression;
import com.cloudinary.utils.ObjectUtils;
import com.cloudinary.utils.StringUtils;

@SuppressWarnings({"rawtypes", "unchecked"})
public class Transformation<T extends Transformation> implements Serializable {
    public static final String VAR_NAME_RE = "^\\$[a-zA-Z][a-zA-Z0-9]+$";
    protected Map transformation;
    protected List<Map> transformations;
    protected String htmlWidth;
    protected String htmlHeight;
    protected boolean hiDPI = false;
    protected boolean isResponsive = false;
    protected static boolean defaultIsResponsive = false;
    protected static Object defaultDPR = null;

    private static final Map<String, String> DEFAULT_RESPONSIVE_WIDTH_TRANSFORMATION = ObjectUtils.asMap("width", "auto", "crop", "limit");
    protected static Map responsiveWidthTransformation = null;
    private static final Pattern RANGE_VALUE_RE = Pattern.compile("^((?:\\d+\\.)?\\d+)([%pP])?$");
    private static final Pattern RANGE_RE = Pattern.compile("^(\\d+\\.)?\\d+[%pP]?\\.\\.(\\d+\\.)?\\d+[%pP]?$");
    private static final String[] SIMPLE_PARAMS = new String[]{
            "ac", "audio_codec",
            "af", "audio_frequency",
            "bo", "border",
            "br", "bit_rate",
            "cs", "color_space",
            "d", "default_image",
            "dl", "delay",
            "dn", "density",
            "f", "fetch_format",
            "fn", "custom_function",
            "fps", "fps",
            "g", "gravity",
            "l", "overlay",
            "p", "prefix",
            "pg", "page",
            "u", "underlay",
            "vs", "video_sampling",
            "sp", "streaming_profile",
            "ki", "keyframe_interval"
    };

    public Transformation(Transformation transformation) {
        this(dup(transformation.transformations));
        this.hiDPI = transformation.isHiDPI();
        this.isResponsive = transformation.isResponsive();
    }

    // Warning: options will destructively updated!
    public Transformation(List<Map> transformations) {
        this.transformations = transformations;
        if (transformations.isEmpty()) {
            chain();
        } else {
            this.transformation = transformations.get(transformations.size() - 1);
        }
    }

    public Transformation() {
        this.transformations = new ArrayList<Map>();
        chain();
    }

    public T width(Object value) {
        return param("width", value);
    }

    public T height(Object value) {
        return param("height", value);
    }

    public T named(String... value) {
        return param("transformation", value);
    }

    public T crop(String value) {
        return param("crop", value);
    }

    public T background(String value) {
        return param("background", value);
    }

    public T color(String value) {
        return param("color", value);
    }

    public T effect(String value) {
        return param("effect", value);
    }

    public T effect(String effect, Object param) {
        return param("effect", effect + ":" + param);
    }

    public T angle(int value) {
        return param("angle", value);
    }

    public T angle(String... value) {
        return param("angle", value);
    }

    public T border(String value) {
        return param("border", value);
    }

    public T border(int width, String color) {
        return param("border", "" + width + "px_solid_" + replaceColorPrefix(color));
    }

    public T x(Object value) {
        return param("x", value);
    }

    public T y(Object value) {
        return param("y", value);
    }

    /**
     * Add rounding transformation.
     * <p>
     * Radius can be specified either as value in pixels or expression. Specify 0 to keep corner untouched.
     *
     * @param value rounding radius for all four corners
     * @return updated transformation instance for chaining
     */
    public T radius(Object value) {
        return radius(new Object[]{value});
    }

    /**
     * Add rounding transformation.
     * <p>
     * Radius can be specified either as value in pixels or expression. Specify 0 to keep corner untouched.
     *
     * @param topLeftBottomRight rounding radius for top-left and bottom-right corners
     * @param topRightBottomLeft rounding radius for top-right and bottom-left corners
     * @return updated transformation instance for chaining
     */
    public T radius(Object topLeftBottomRight, Object topRightBottomLeft) {
        return radius(new Object[]{topLeftBottomRight, topRightBottomLeft});
    }

    /**
     * Add rounding transformation.
     * <p>
     * Radius can be specified either as value in pixels or expression. Specify 0 to keep corner untouched.
     *
     * @param topLeft            rounding radius for top-left corner
     * @param topRightBottomLeft rounding radius for top-right and bottom-left corners
     * @param bottomRight        rounding radius for bottom-right corner
     * @return updated transformation instance for chaining
     */
    public T radius(Object topLeft, Object topRightBottomLeft, Object bottomRight) {
        return radius(new Object[]{topLeft, topRightBottomLeft, bottomRight});
    }

    /**
     * Add rounding transformation.
     * <p>
     * Radius can be specified either as value in pixels or expression. Specify 0 to keep corner untouched.
     *
     * @param topLeft     rounding radius for top-left corner
     * @param topRight    rounding radius for top-right corner
     * @param bottomRight rounding radius for bottom-right corner
     * @param bottomLeft  rounding radius for bottom-left corner
     * @return updated transformation instance for chaining
     */
    public T radius(Object topLeft, Object topRight, Object bottomRight, Object bottomLeft) {
        return radius(new Object[]{topLeft, topRight, bottomRight, bottomLeft});
    }

    /**
     * Add rounding transformation.
     * <p>
     * Radius can be specified either as value in pixels or expression. Specify 0 to keep corner untouched.
     *
     * @param cornerRadiuses rounding radiuses for corners as array
     * @return updated transformation instance for chaining
     */
    public T radius(Object[] cornerRadiuses) {
        return param("radius", cornerRadiuses);
    }

    public T quality(Object value) {
        return param("quality", value);
    }

    public T defaultImage(String value) {
        return param("default_image", value);
    }

    public T gravity(String value) {
        return param("gravity", value);
    }

    /**
     * Set the keyframe interval parameter
     *
     * @param value Interval in seconds
     * @return The transformation for chaining
     */
    public T keyframeInterval(float value) {
        return param("keyframe_interval", value);
    }

    /**
     * Set the keyframe interval parameter
     *
     * @param value Interval in seconds.
     * @return The transformation for chaining
     */
    public T keyframeInterval(String value) {
        return param("keyframe_interval", value);
    }

    public T colorSpace(String value) {
        return param("color_space", value);
    }

    public T prefix(String value) {
        return param("prefix", value);
    }

    public T overlay(String value) {
        return param("overlay", value);
    }

    public T overlay(AbstractLayer<?> value) {
        return param("overlay", value);
    }

    public T underlay(String value) {
        return param("underlay", value);
    }

    public T underlay(AbstractLayer<?> value) {
        return param("underlay", value);
    }

    public T fetchFormat(String value) {
        return param("fetch_format", value);
    }

    public T density(Object value) {
        return param("density", value);
    }

    public T page(Object value) {
        return param("page", value);
    }

    public T delay(Object value) {
        return param("delay", value);
    }

    public T opacity(Object value) {
        return param("opacity", value);
    }

    public T rawTransformation(String value) {
        return param("raw_transformation", value);
    }

    public T flags(String... value) {
        return param("flags", value);
    }

    public T dpr(float value) {
        return param("dpr", value);
    }

    public T dpr(int value) {
        return param("dpr", value);
    }

    public T dpr(String value) {
        return param("dpr", value);
    }

    public T duration(String value) {
        return param("duration", value);
    }

    public T duration(float value) {
        return param("duration", new Float(value));
    }

    public T duration(double value) {
        return param("duration", new Double(value));
    }

    public T durationPercent(float value) {
        return param("duration", new Float(value).toString() + "p");
    }

    public T durationPercent(double value) {
        return param("duration", new Double(value).toString() + "p");
    }

    public T startOffset(String value) {
        return param("start_offset", value);
    }

    public T startOffset(float value) {
        return param("start_offset", new Float(value));
    }

    public T startOffset(double value) {
        return param("start_offset", new Double(value));
    }

    public T startOffsetPercent(float value) {
        return param("start_offset", new Float(value).toString() + "p");
    }

    public T startOffsetPercent(double value) {
        return param("start_offset", new Double(value).toString() + "p");
    }

    public T endOffset(String value) {
        return param("end_offset", value);
    }

    public T endOffset(float value) {
        return param("end_offset", new Float(value));
    }

    public T endOffset(double value) {
        return param("end_offset", new Double(value));
    }

    public T endOffsetPercent(float value) {
        return param("end_offset", new Float(value).toString() + "p");
    }

    public T endOffsetPercent(double value) {
        return param("end_offset", new Double(value).toString() + "p");
    }

    public T offset(String value) {
        return param("offset", value);
    }

    public T offset(String[] value) {
        if (value.length < 2) throw new IllegalArgumentException("Offset range must include at least 2 items");
        return param("offset", value);
    }

    public T offset(float[] value) {
        if (value.length < 2) throw new IllegalArgumentException("Offset range must include at least 2 items");
        Number[] numberArray = new Number[]{value[0], value[1]};
        return offset(numberArray);
    }

    public T offset(double[] value) {
        if (value.length < 2) throw new IllegalArgumentException("Offset range must include at least 2 items");
        Number[] numberArray = new Number[]{value[0], value[1]};
        return offset(numberArray);
    }

    public T offset(Number[] value) {
        if (value.length < 2) throw new IllegalArgumentException("Offset range must include at least 2 items");
        return param("offset", value);
    }

    public T videoCodec(String value) {
        return param("video_codec", value);
    }

    public T videoCodec(Map<String, String> value) {
        return param("video_codec", value);
    }

    public T audioCodec(String value) {
        return param("audio_codec", value);
    }

    public T audioFrequency(String value) {
        return param("audio_frequency", value);
    }

    public T audioFrequency(int value) {
        return param("audio_frequency", value);
    }

    public T bitRate(String value) {
        return param("bit_rate", value);
    }

    public T bitRate(int value) {
        return param("bit_rate", new Integer(value));
    }

    public T videoSampling(String value) {
        return param("video_sampling", value);
    }

    public T videoSamplingFrames(int value) {
        return param("video_sampling", value);
    }

    public T videoSamplingSeconds(Number value) {
        return param("video_sampling", value.toString() + "s");
    }

    public T videoSamplingSeconds(int value) {
        return videoSamplingSeconds(new Integer(value));
    }

    public T videoSamplingSeconds(float value) {
        return videoSamplingSeconds(new Float(value));
    }

    public T videoSamplingSeconds(double value) {
        return videoSamplingSeconds(new Double(value));
    }

    public T zoom(String value) {
        return param("zoom", value);
    }

    public T zoom(float value) {
        return param("zoom", new Float(value));
    }

    public T zoom(double value) {
        return param("zoom", new Double(value));
    }

    public T aspectRatio(double value) {
        return param("aspect_ratio", new Double(value));
    }

    public T aspectRatio(String value) {
        return param("aspect_ratio", value);
    }

    public T aspectRatio(int nom, int denom) {
        return aspectRatio(Integer.toString(nom) + ":" + Integer.toString(denom));
    }

    public T responsiveWidth(boolean value) {
        return param("responsive_width", value);
    }

    /**
     * Start defining a condition, which will be completed with a call {@link Condition#then()}
     *
     * @return condition
     */
    public Condition ifCondition() {
        return new Condition().setParent(this);
    }

    /**
     * Define a conditional transformation defined by the condition string
     *
     * @param condition a condition string
     * @return the transformation for chaining
     */
    public T ifCondition(String condition) {
        return param("if", condition);
    }


    /**
     * Define a conditional transformation
     *
     * @param expression a condition
     * @return the transformation for chaining
     */
    public T ifCondition(Expression expression) {
        return ifCondition(expression.toString());
    }

    /**
     * Define a conditional transformation
     *
     * @param condition a condition
     * @return the transformation for chaining
     */
    public T ifCondition(Condition condition) {
        return ifCondition(condition.toString());
    }

    public T ifElse() {
        chain();
        return param("if", "else");
    }

    public T endIf() {
        chain();
        int transSize = this.transformations.size();
        for (int i = transSize - 1; i >= 0; i--) {
            Map segment = this.transformations.get(i); // [..., {if: "w_gt_1000",c: "fill", w: 500}, ...]
            Object value = segment.get("if");
            if (value != null) { // if: "w_gt_1000"
                String ifValue = value.toString();
                if (ifValue.equals("end")) break;
                if (segment.size() > 1) {
                    segment.remove("if"); // {c: fill, w: 500}
                    transformations.set(i, segment); // [..., {c: fill, w: 500}, ...]
                    transformations.add(i, ObjectUtils.asMap("if", value)); // // [..., "if_w_gt_1000", {c: fill, w: 500}, ...]
                }
                if (!"else".equals(ifValue)) break; // otherwise keep looking for if_condition
            }
        }

        param("if", "end");
        return chain();
    }

    /**
     * fps (frames per second) parameter for video
     *
     * @param value Either a single value int or float or a range in the format <code>&lt;start&gt;[-&lt;end&gt;]</code>.  <br>
     *              For example, <code>23-29.7</code>
     * @return the transformation for chaining
     */
    public T fps(String value) {
        return param("fps", value);
    }

    /**
     * fps (frames per second) parameter for video
     *
     * @param value the desired fps
     * @return the transformation for chaining
     */
    public T fps(double value) {
        return param("fps", new Float(value));
    }

    /**
     * fps (frames per second) parameter for video
     *
     * @param value the desired fps
     * @return the transformation for chaining
     */
    public T fps(int value) {
        return param("fps", new Integer(value));
    }

    /**
     * fps (frames per second) parameter for video
     * @param rangeStart String or Number, can be null for open range.
     * @param rangeEnd String or Number, can be null for open range.
     * @return the transformation for chaining.
     */
    public T fps(Object rangeStart, Object rangeEnd){
        if (rangeEnd == null && rangeStart == null){
            throw new IllegalArgumentException("At least one of [rangeStart, rangeEnd] must be provided");
        }
        StringBuilder builder = new StringBuilder();
        if (rangeStart != null){
            builder.append(rangeStart);
        }

        builder.append("-");

        if (rangeEnd != null){
            builder.append(rangeEnd);
        }

        return param("fps", builder.toString());
    }

    public T streamingProfile(String value) {
        return param("streaming_profile", value);
    }

    public boolean isResponsive() {
        return this.isResponsive;
    }

    public boolean isHiDPI() {
        return this.hiDPI;
    }

    // Warning: options will destructively updated!
    public T params(Map transformation) {
        this.transformation = transformation;
        transformations.add(transformation);
        return (T) this;
    }

    public T chain() {
        return params(new HashMap());
    }

    public T chainWith(Transformation transformation) {
        List<Map> transformations = dup(this.transformations);
        transformations.addAll(dup(transformation.transformations));
        return (T) new Transformation(transformations);
    }
Download .txt
gitextract_fmnzldsh/

├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   ├── pull_request_template.md
│   └── workflows/
│       └── build.yml
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── MAVEN_CENTRAL_PUBLISHING_GUIDE.md
├── README.md
├── build.gradle
├── cloudinary-core/
│   ├── build.gradle
│   └── src/
│       ├── main/
│       │   └── java/
│       │       ├── com/
│       │       │   └── cloudinary/
│       │       │       ├── AccessControlRule.java
│       │       │       ├── Api.java
│       │       │       ├── ArchiveParams.java
│       │       │       ├── AuthToken.java
│       │       │       ├── BaseParam.java
│       │       │       ├── Cloudinary.java
│       │       │       ├── Configuration.java
│       │       │       ├── Coordinates.java
│       │       │       ├── CustomFunction.java
│       │       │       ├── EagerTransformation.java
│       │       │       ├── ProgressCallback.java
│       │       │       ├── ResponsiveBreakpoint.java
│       │       │       ├── Search.java
│       │       │       ├── SearchFolders.java
│       │       │       ├── SignatureAlgorithm.java
│       │       │       ├── SmartUrlEncoder.java
│       │       │       ├── StoredFile.java
│       │       │       ├── Transformation.java
│       │       │       ├── Uploader.java
│       │       │       ├── Url.java
│       │       │       ├── Util.java
│       │       │       ├── api/
│       │       │       │   ├── ApiResponse.java
│       │       │       │   ├── AuthorizationRequired.java
│       │       │       │   ├── RateLimit.java
│       │       │       │   ├── exceptions/
│       │       │       │   │   ├── AlreadyExists.java
│       │       │       │   │   ├── ApiException.java
│       │       │       │   │   ├── BadRequest.java
│       │       │       │   │   ├── GeneralError.java
│       │       │       │   │   ├── NotAllowed.java
│       │       │       │   │   ├── NotFound.java
│       │       │       │   │   └── RateLimited.java
│       │       │       │   └── signing/
│       │       │       │       ├── ApiResponseSignatureVerifier.java
│       │       │       │       ├── NotificationRequestSignatureVerifier.java
│       │       │       │       ├── SignedPayloadValidator.java
│       │       │       │       └── package-info.java
│       │       │       ├── metadata/
│       │       │       │   ├── DateMetadataField.java
│       │       │       │   ├── EnumMetadataField.java
│       │       │       │   ├── IntMetadataField.java
│       │       │       │   ├── MetadataDataSource.java
│       │       │       │   ├── MetadataField.java
│       │       │       │   ├── MetadataFieldType.java
│       │       │       │   ├── MetadataRule.java
│       │       │       │   ├── MetadataRuleCondition.java
│       │       │       │   ├── MetadataRuleResult.java
│       │       │       │   ├── MetadataValidation.java
│       │       │       │   ├── Restrictions.java
│       │       │       │   ├── SetMetadataField.java
│       │       │       │   └── StringMetadataField.java
│       │       │       ├── provisioning/
│       │       │       │   ├── Account.java
│       │       │       │   └── AccountConfiguration.java
│       │       │       ├── strategies/
│       │       │       │   ├── AbstractApiStrategy.java
│       │       │       │   ├── AbstractUploaderStrategy.java
│       │       │       │   └── StrategyLoader.java
│       │       │       ├── transformation/
│       │       │       │   ├── AbstractLayer.java
│       │       │       │   ├── BaseExpression.java
│       │       │       │   ├── Condition.java
│       │       │       │   ├── Expression.java
│       │       │       │   ├── FetchLayer.java
│       │       │       │   ├── Layer.java
│       │       │       │   ├── SubtitlesLayer.java
│       │       │       │   └── TextLayer.java
│       │       │       └── utils/
│       │       │           ├── Analytics.java
│       │       │           ├── Base64Coder.java
│       │       │           ├── Base64Map.java
│       │       │           ├── HtmlEscape.java
│       │       │           ├── ObjectUtils.java
│       │       │           ├── Rectangle.java
│       │       │           └── StringUtils.java
│       │       └── org/
│       │           └── cloudinary/
│       │               └── json/
│       │                   ├── JSONArray.java
│       │                   ├── JSONException.java
│       │                   ├── JSONObject.java
│       │                   ├── JSONString.java
│       │                   └── JSONTokener.java
│       └── test/
│           └── java/
│               └── com/
│                   └── cloudinary/
│                       ├── AuthTokenTest.java
│                       ├── TransformationTest.java
│                       ├── UtilTest.java
│                       ├── analytics/
│                       │   └── AnalyticsTest.java
│                       ├── api/
│                       │   └── signing/
│                       │       ├── ApiResponseSignatureVerifierTest.java
│                       │       └── NotificationRequestSignatureVerifierTest.java
│                       ├── test/
│                       │   └── CloudinaryTest.java
│                       └── transformation/
│                           ├── ExpressionTest.java
│                           └── LayerTest.java
├── cloudinary-http5/
│   ├── build.gradle
│   └── src/
│       ├── main/
│       │   └── java/
│       │       └── com/
│       │           └── cloudinary/
│       │               └── http5/
│       │                   ├── ApiStrategy.java
│       │                   ├── ApiUtils.java
│       │                   ├── UploaderStrategy.java
│       │                   └── api/
│       │                       └── Response.java
│       └── test/
│           └── java/
│               └── com/
│                   └── cloudinary/
│                       └── test/
│                           ├── AccountApiTest.java
│                           ├── ApiTest.java
│                           ├── ContextTest.java
│                           ├── FoldersApiTest.java
│                           ├── SearchTest.java
│                           ├── StreamingProfilesApiTest.java
│                           ├── StructuredMetadataTest.java
│                           └── UploaderTest.java
├── cloudinary-taglib/
│   ├── build.gradle
│   └── src/
│       └── main/
│           ├── java/
│           │   └── com/
│           │       └── cloudinary/
│           │           ├── Singleton.java
│           │           ├── SingletonManager.java
│           │           └── taglib/
│           │               ├── CloudinaryImageTag.java
│           │               ├── CloudinaryJsConfigTag.java
│           │               ├── CloudinaryJsIncludeTag.java
│           │               ├── CloudinaryTransformationTag.java
│           │               ├── CloudinaryUnsignedUploadTag.java
│           │               ├── CloudinaryUploadTag.java
│           │               ├── CloudinaryUrl.java
│           │               └── CloudinaryVideoTag.java
│           └── resources/
│               └── META-INF/
│                   └── cloudinary.tld
├── cloudinary-test-common/
│   ├── build.gradle
│   └── src/
│       └── main/
│           ├── java/
│           │   └── com/
│           │       └── cloudinary/
│           │           └── test/
│           │               ├── AbstractAccountApiTest.java
│           │               ├── AbstractApiTest.java
│           │               ├── AbstractContextTest.java
│           │               ├── AbstractFoldersApiTest.java
│           │               ├── AbstractSearchTest.java
│           │               ├── AbstractStreamingProfilesApiTest.java
│           │               ├── AbstractStructuredMetadataTest.java
│           │               ├── AbstractUploaderTest.java
│           │               ├── MetadataTestHelper.java
│           │               ├── MockableTest.java
│           │               ├── TimeoutTest.java
│           │               ├── helpers/
│           │               │   └── Feature.java
│           │               └── rules/
│           │                   └── RetryRule.java
│           └── resources/
│               ├── docx.docx
│               └── אבג.docx
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── java_shared.gradle
├── publish.gradle
├── samples/
│   ├── photo_album/
│   │   ├── META-INF/
│   │   │   └── persistence.xml
│   │   ├── README.md
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cloudinary/
│   │           │       ├── controllers/
│   │           │       │   └── PhotoController.java
│   │           │       ├── lib/
│   │           │       │   └── PhotoUploadValidator.java
│   │           │       ├── models/
│   │           │       │   ├── Photo.java
│   │           │       │   └── PhotoUpload.java
│   │           │       └── repositories/
│   │           │           └── PhotoRepository.java
│   │           ├── resources/
│   │           │   └── META-INF/
│   │           │       └── persistence.xml
│   │           └── webapp/
│   │               ├── WEB-INF/
│   │               │   ├── messages.properties
│   │               │   ├── mvc-dispatcher-servlet.xml
│   │               │   ├── pages/
│   │               │   │   ├── direct_upload_form.jsp
│   │               │   │   ├── photos.jsp
│   │               │   │   ├── post.jsp
│   │               │   │   ├── pre.jsp
│   │               │   │   ├── upload.jsp
│   │               │   │   └── upload_form.jsp
│   │               │   └── web.xml
│   │               └── assets/
│   │                   ├── cloudinary_cors.html
│   │                   ├── javascripts/
│   │                   │   └── cloudinary/
│   │                   │       ├── jquery.cloudinary.js
│   │                   │       ├── jquery.fileupload-image.js
│   │                   │       ├── jquery.fileupload-process.js
│   │                   │       ├── jquery.fileupload-validate.js
│   │                   │       ├── jquery.fileupload.js
│   │                   │       ├── jquery.iframe-transport.js
│   │                   │       └── jquery.ui.widget.js
│   │                   └── stylesheets/
│   │                       └── application.css
│   └── photo_album_gae/
│       ├── META-INF/
│       │   └── persistence.xml
│       ├── README.md
│       ├── nbactions.xml
│       ├── pom.xml
│       └── src/
│           └── main/
│               ├── java/
│               │   ├── cloudinary/
│               │   │   ├── controllers/
│               │   │   │   └── PhotoController.java
│               │   │   ├── lib/
│               │   │   │   └── PhotoUploadValidator.java
│               │   │   └── models/
│               │   │       └── PhotoUpload.java
│               │   └── org/
│               │       └── esxx/
│               │           └── js/
│               │               └── protocol/
│               │                   ├── GAEClientConnection.java
│               │                   └── GAEConnectionManager.java
│               └── webapp/
│                   ├── WEB-INF/
│                   │   ├── appengine-web.xml.sample
│                   │   ├── logging.properties
│                   │   ├── messages.properties
│                   │   ├── mvc-dispatcher-servlet.xml
│                   │   ├── pages/
│                   │   │   ├── direct_upload_form.jsp
│                   │   │   ├── photos.jsp
│                   │   │   ├── post.jsp
│                   │   │   ├── pre.jsp
│                   │   │   ├── upload.jsp
│                   │   │   └── upload_form.jsp
│                   │   └── web.xml
│                   └── assets/
│                       ├── cloudinary_cors.html
│                       ├── javascripts/
│                       │   └── cloudinary/
│                       │       ├── jquery.cloudinary.js
│                       │       ├── jquery.fileupload-image.js
│                       │       ├── jquery.fileupload-process.js
│                       │       ├── jquery.fileupload-validate.js
│                       │       ├── jquery.fileupload.js
│                       │       ├── jquery.iframe-transport.js
│                       │       └── jquery.ui.widget.js
│                       └── stylesheets/
│                           └── application.css
├── settings.gradle
└── tools/
    └── update_version.sh
Download .txt
SYMBOL INDEX (2001 symbols across 130 files)

FILE: cloudinary-core/src/main/java/com/cloudinary/AccessControlRule.java
  class AccessControlRule (line 11) | public class AccessControlRule extends JSONObject {
    method token (line 17) | public static AccessControlRule token(){
    method anonymousFrom (line 26) | public static AccessControlRule anonymousFrom(Date start){
    method anonymousUntil (line 35) | public static AccessControlRule anonymousUntil(Date end){
    method anonymous (line 45) | public static AccessControlRule anonymous(Date start, Date end){
    method AccessControlRule (line 49) | private AccessControlRule(AccessType accessType, Date start, Date end) {
    type AccessType (line 63) | public enum AccessType {

FILE: cloudinary-core/src/main/java/com/cloudinary/Api.java
  class Api (line 17) | @SuppressWarnings({"rawtypes", "unchecked"})
    method getStrategy (line 21) | public AbstractApiStrategy getStrategy() {
    type HttpMethod (line 25) | public enum HttpMethod {GET, POST, PUT, DELETE;}
    method callApi (line 43) | protected ApiResponse callApi(HttpMethod method, Iterable<String> uri,...
    method Api (line 59) | public Api(Cloudinary cloudinary, AbstractApiStrategy strategy) {
    method ping (line 65) | public ApiResponse ping(Map options) throws Exception {
    method usage (line 70) | public ApiResponse usage(Map options) throws Exception {
    method configuration (line 89) | public ApiResponse configuration(Map options) throws  Exception {
    method resourceTypes (line 100) | public ApiResponse resourceTypes(Map options) throws Exception {
    method resources (line 105) | public ApiResponse resources(Map options) throws Exception {
    method visualSearch (line 121) | public ApiResponse visualSearch(Map options) throws Exception {
    method resourcesByTag (line 132) | public ApiResponse resourcesByTag(String tag, Map options) throws Exce...
    method resourcesByContext (line 142) | public ApiResponse resourcesByContext(String key, Map options) throws ...
    method resourcesByContext (line 146) | public ApiResponse resourcesByContext(String key, String value, Map op...
    method resourceByAssetID (line 160) | public ApiResponse resourceByAssetID(String assetId, Map options) thro...
    method resourcesByAssetIDs (line 169) | public ApiResponse resourcesByAssetIDs(Iterable<String> assetIds, Map ...
    method resourcesByAssetFolder (line 177) | public ApiResponse resourcesByAssetFolder(String assetFolder, Map opti...
    method resourcesByIds (line 188) | public ApiResponse resourcesByIds(Iterable<String> publicIds, Map opti...
    method resourcesByModeration (line 198) | public ApiResponse resourcesByModeration(String kind, String status, M...
    method resource (line 208) | public ApiResponse resource(String public_id, Map options) throws Exce...
    method buildResourceDetailParams (line 219) | private Map buildResourceDetailParams(Map options) {
    method update (line 225) | public ApiResponse update(String public_id, Map options) throws Except...
    method deleteResources (line 238) | public ApiResponse deleteResources(Iterable<String> publicIds, Map opt...
    method deleteResourcesByAssetIds (line 247) | public ApiResponse deleteResourcesByAssetIds(Iterable<String> assetIds...
    method deleteDerivedByTransformation (line 254) | public ApiResponse deleteDerivedByTransformation(Iterable<String> publ...
    method deleteResourcesByPrefix (line 265) | public ApiResponse deleteResourcesByPrefix(String prefix, Map options)...
    method deleteResourcesByTag (line 274) | public ApiResponse deleteResourcesByTag(String tag, Map options) throw...
    method deleteAllResources (line 280) | public ApiResponse deleteAllResources(Map options) throws Exception {
    method deleteDerivedResources (line 289) | public ApiResponse deleteDerivedResources(Iterable<String> derivedReso...
    method tags (line 294) | public ApiResponse tags(Map options) throws Exception {
    method transformations (line 300) | public ApiResponse transformations(Map options) throws Exception {
    method transformation (line 305) | public ApiResponse transformation(String transformation, Map options) ...
    method deleteTransformation (line 312) | public ApiResponse deleteTransformation(String transformation, Map opt...
    method updateTransformation (line 321) | public ApiResponse updateTransformation(String transformation, Map upd...
    method createTransformation (line 327) | public ApiResponse createTransformation(String name, String definition...
    method uploadPresets (line 333) | public ApiResponse uploadPresets(Map options) throws Exception {
    method uploadPreset (line 338) | public ApiResponse uploadPreset(String name, Map options) throws Excep...
    method deleteUploadPreset (line 343) | public ApiResponse deleteUploadPreset(String name, Map options) throws...
    method updateUploadPreset (line 348) | public ApiResponse updateUploadPreset(String name, Map options) throws...
    method createUploadPreset (line 356) | public ApiResponse createUploadPreset(Map options) throws Exception {
    method rootFolders (line 364) | public ApiResponse rootFolders(Map options) throws Exception {
    method subFolders (line 372) | public ApiResponse subFolders(String ofFolderPath, Map options) throws...
    method createFolder (line 381) | public ApiResponse createFolder(String folderName, Map options) throws...
    method restore (line 387) | public ApiResponse restore(Iterable<String> publicIds, Map options) th...
    method restoreByAssetIds (line 400) | public ApiResponse restoreByAssetIds(Iterable<String> assetIds, Map op...
    method uploadMappings (line 408) | public ApiResponse uploadMappings(Map options) throws Exception {
    method uploadMapping (line 415) | public ApiResponse uploadMapping(String name, Map options) throws Exce...
    method deleteUploadMapping (line 421) | public ApiResponse deleteUploadMapping(String name, Map options) throw...
    method updateUploadMapping (line 427) | public ApiResponse updateUploadMapping(String name, Map options) throw...
    method createUploadMapping (line 436) | public ApiResponse createUploadMapping(String name, Map options) throw...
    method publishByPrefix (line 445) | public ApiResponse publishByPrefix(String prefix, Map options) throws ...
    method publishByTag (line 449) | public ApiResponse publishByTag(String tag, Map options) throws Except...
    method publishByIds (line 453) | public ApiResponse publishByIds(Iterable<String> publicIds, Map option...
    method publishResource (line 457) | private ApiResponse publishResource(String byKey, Object value, Map op...
    method createStreamingProfile (line 480) | public ApiResponse createStreamingProfile(String name, String displayN...
    method createStreamingProfile (line 502) | public ApiResponse createStreamingProfile(String name, String displayN...
    method getStreamingProfile (line 514) | public ApiResponse getStreamingProfile(String name, Map options) throw...
    method getStreamingProfile (line 526) | public ApiResponse getStreamingProfile(String name) throws Exception {
    method listStreamingProfiles (line 537) | public ApiResponse listStreamingProfiles(Map options) throws Exception {
    method listStreamingProfiles (line 548) | public ApiResponse listStreamingProfiles() throws Exception {
    method deleteStreamingProfile (line 560) | public ApiResponse deleteStreamingProfile(String name, Map options) th...
    method deleteStreamingProfile (line 572) | public ApiResponse deleteStreamingProfile(String name) throws Exception {
    method updateStreamingProfile (line 586) | public ApiResponse updateStreamingProfile(String name, String displayN...
    method updateStreamingProfile (line 610) | public ApiResponse updateStreamingProfile(String name, String displayN...
    method updateResourcesAccessModeByPrefix (line 632) | public ApiResponse updateResourcesAccessModeByPrefix(String accessMode...
    method updateResourcesAccessModeByTag (line 654) | public ApiResponse updateResourcesAccessModeByTag(String accessMode, S...
    method deleteFolder (line 666) | public ApiResponse deleteFolder(String folder, Map options) throws Exc...
    method updateResourcesAccessModeByIds (line 691) | public ApiResponse updateResourcesAccessModeByIds(String accessMode, I...
    method updateResourcesAccessMode (line 695) | private ApiResponse updateResourcesAccessMode(String accessMode, Strin...
    method addMetadataField (line 713) | public ApiResponse addMetadataField(MetadataField field) throws Except...
    method listMetadataFields (line 724) | public ApiResponse listMetadataFields() throws Exception {
    method metadataFieldByFieldId (line 735) | public ApiResponse metadataFieldByFieldId(String fieldExternalId) thro...
    method updateMetadataField (line 747) | public ApiResponse updateMetadataField(String fieldExternalId, Metadat...
    method updateMetadataFieldDatasource (line 761) | public ApiResponse updateMetadataFieldDatasource(String fieldExternalI...
    method deleteDatasourceEntries (line 774) | public ApiResponse deleteDatasourceEntries(String fieldExternalId, Lis...
    method restoreDatasourceEntries (line 787) | public ApiResponse restoreDatasourceEntries(String fieldExternalId, Li...
    method deleteMetadataField (line 799) | public ApiResponse deleteMetadataField(String fieldExternalId) throws ...
    method reorderMetadataFields (line 813) | public ApiResponse reorderMetadataFields(String orderBy, String direct...
    method listMetadataRules (line 827) | public ApiResponse listMetadataRules(Map options) throws Exception {
    method addMetadataRule (line 834) | public ApiResponse addMetadataRule(MetadataRule rule, Map options) thr...
    method updateMetadataRule (line 842) | public ApiResponse updateMetadataRule(String externalId, MetadataRule ...
    method deleteMetadataRule (line 850) | public ApiResponse deleteMetadataRule(String externalId, Map options) ...
    method analyze (line 856) | public ApiResponse analyze(String inputType, String analysisType, Stri...
    method renameFolder (line 867) | public ApiResponse renameFolder(String path, String toPath, Map option...
    method deleteBackedUpAssets (line 878) | public ApiResponse deleteBackedUpAssets(String assetId, String[] versi...
    method extractParams (line 897) | private Map<String, ?> extractParams(Map options, List<String> keys) {
    method validateAuthorization (line 909) | protected void validateAuthorization(String apiKey, String apiSecret, ...
    method getAuthorizationHeaderValue (line 916) | protected String getAuthorizationHeaderValue(String apiKey, String api...
    method createApiUrl (line 924) | protected String createApiUrl (Iterable<String> uri, Map options){

FILE: cloudinary-core/src/main/java/com/cloudinary/ArchiveParams.java
  class ArchiveParams (line 7) | public class ArchiveParams {
    method resourceType (line 34) | public String resourceType() {
    method resourceType (line 38) | public ArchiveParams resourceType(String resourceType) {
    method type (line 45) | public String type() {
    method type (line 49) | public ArchiveParams type(String type) {
    method mode (line 54) | public String mode() {
    method mode (line 58) | public ArchiveParams mode(String mode) {
    method targetFormat (line 63) | public String targetFormat() {
    method targetFormat (line 67) | public ArchiveParams targetFormat(String targetFormat) {
    method targetPublicId (line 72) | public String targetPublicId() {
    method targetPublicId (line 76) | public ArchiveParams targetPublicId(String targetPublicId) {
    method isFlattenFolders (line 81) | public boolean isFlattenFolders() {
    method flattenFolders (line 85) | public ArchiveParams flattenFolders(boolean flattenFolders) {
    method isFlattenTransformations (line 90) | public boolean isFlattenTransformations() {
    method flattenTransformations (line 94) | public ArchiveParams flattenTransformations(boolean flattenTransformat...
    method isUseOriginalFilename (line 99) | public boolean isUseOriginalFilename() {
    method useOriginalFilename (line 103) | public ArchiveParams useOriginalFilename(boolean useOriginalFilename) {
    method isAsync (line 108) | public boolean isAsync() {
    method async (line 112) | public ArchiveParams async(boolean async) {
    method isSkipTransformationName (line 117) | public boolean isSkipTransformationName() {
    method skipTransformationName (line 121) | public ArchiveParams skipTransformationName(boolean skipTransformation...
    method isAllowMissing (line 126) | public boolean isAllowMissing(){
    method allowMissing (line 130) | public ArchiveParams allowMissing(boolean allowMissing){
    method isKeepDerived (line 135) | public boolean isKeepDerived() {
    method keepDerived (line 139) | public ArchiveParams keepDerived(boolean keepDerived) {
    method notificationUrl (line 144) | public String notificationUrl() {
    method notificationUrl (line 148) | public ArchiveParams notificationUrl(String notificationUrl) {
    method targetTags (line 153) | public String[] targetTags() {
    method targetTags (line 157) | public ArchiveParams targetTags(String[] targetTags) {
    method tags (line 162) | public String[] tags() {
    method tags (line 166) | public ArchiveParams tags(String[] tags) {
    method publicIds (line 171) | public String[] publicIds() {
    method publicIds (line 175) | public ArchiveParams publicIds(String[] publicIds) {
    method fully_qualified_public_ids (line 180) | public String[] fully_qualified_public_ids() {
    method fullyQualifiedPublicIds (line 184) | public ArchiveParams fullyQualifiedPublicIds(String[] fullyQualifiedPu...
    method prefixes (line 189) | public String[] prefixes() {
    method prefixes (line 193) | public ArchiveParams prefixes(String[] prefixes) {
    method transformations (line 198) | public Transformation[] transformations() {
    method transformations (line 202) | public ArchiveParams transformations(Transformation[] transformations) {
    method expiresAt (line 207) | public ArchiveParams expiresAt(Long expiresAt) {
    method expiresAt (line 212) | public Long expiresAt(){
    method toMap (line 216) | public Map<String, Object> toMap() {

FILE: cloudinary-core/src/main/java/com/cloudinary/AuthToken.java
  class AuthToken (line 17) | public class AuthToken {
    method AuthToken (line 34) | public AuthToken() {
    method AuthToken (line 37) | public AuthToken(String key) {
    method AuthToken (line 46) | public AuthToken(Map options) {
    method asMap (line 67) | public Map<String,Object> asMap(){
    method tokenName (line 87) | public AuthToken tokenName(String tokenName) {
    method startTime (line 98) | public AuthToken startTime(long startTime) {
    method expiration (line 109) | public AuthToken expiration(long expiration) {
    method ip (line 120) | public AuthToken ip(String ip) {
    method acl (line 131) | public AuthToken acl(String... acl) {
    method duration (line 143) | public AuthToken duration(long duration) {
    method generate (line 153) | public String generate() {
    method generate (line 163) | public String generate(String url) {
    method escapeToLower (line 205) | private String escapeToLower(String url) {
    method copy (line 215) | public AuthToken copy() {
    method merge (line 232) | public AuthToken merge(AuthToken other) {
    method digest (line 248) | private String digest(String message) {
    method setNull (line 263) | private AuthToken setNull() {
    method equals (line 268) | @Override
    method hashCode (line 285) | @Override

FILE: cloudinary-core/src/main/java/com/cloudinary/BaseParam.java
  class BaseParam (line 7) | public class BaseParam {
    method BaseParam (line 10) | protected BaseParam(List<String> components) {
    method BaseParam (line 14) | protected BaseParam(String... components) {
    method toString (line 18) | @Override

FILE: cloudinary-core/src/main/java/com/cloudinary/Cloudinary.java
  class Cloudinary (line 20) | @SuppressWarnings({"rawtypes", "unchecked"})
    method uploader (line 44) | public Uploader uploader() {
    method api (line 48) | public Api api() {
    method search (line 52) | public Search search() {
    method searchFolders (line 56) | public SearchFolders searchFolders() {
    method registerUploaderStrategy (line 60) | public static void registerUploaderStrategy(String className) {
    method registerAPIStrategy (line 67) | public static void registerAPIStrategy(String className) {
    method loadStrategies (line 73) | private void loadStrategies() {
    method Cloudinary (line 87) | public Cloudinary(Map config) {
    method Cloudinary (line 91) | public Cloudinary(String cloudinaryUrl) {
    method Cloudinary (line 95) | public Cloudinary() {
    method Cloudinary (line 101) | public Cloudinary(Configuration config) {
    method url (line 106) | public Url url() {
    method cloudinaryApiUrl (line 110) | public String cloudinaryApiUrl(String action, Map options) {
    method randomPublicId (line 122) | public String randomPublicId() {
    method signedPreloadedImage (line 128) | public String signedPreloadedImage(Map result) {
    method apiSignRequest (line 133) | public String apiSignRequest(Map<String, Object> paramsToSign, String ...
    method getUserAgent (line 140) | public String getUserAgent(){
    method setUserAgent (line 150) | public void setUserAgent(String prefix, String version){
    method setAnalytics (line 158) | public void setAnalytics(Analytics analytics) {
    method verifyNotificationSignature (line 179) | public boolean verifyNotificationSignature(String body, String timesta...
    method verifyApiResponseSignature (line 197) | public boolean verifyApiResponseSignature(String publicId, String vers...
    method signRequest (line 201) | public void signRequest(Map<String, Object> params, Map<String, Object...
    method privateDownload (line 213) | public String privateDownload(String publicId, String format, Map<Stri...
    method zipDownload (line 225) | public String zipDownload(String tag, Map<String, Object> options) thr...
    method downloadArchive (line 241) | public String downloadArchive(Map<String, Object> options, String targ...
    method downloadArchive (line 248) | public String downloadArchive(ArchiveParams params) throws Unsupported...
    method downloadZip (line 252) | public String downloadZip(Map<String, Object> options) throws Unsuppor...
    method downloadGeneratedSprite (line 256) | public String downloadGeneratedSprite(String tag, Map options) throws ...
    method downloadGeneratedSprite (line 271) | public String downloadGeneratedSprite(String[] urls, Map options) thro...
    method downloadMulti (line 285) | public String downloadMulti(String tag, Map options) throws IOException {
    method downloadMulti (line 299) | public String downloadMulti(String[] urls, Map options) throws IOExcep...
    method downloadFolder (line 320) | public String downloadFolder(String folderPath, Map options) throws Un...
    method downloadBackedupAsset (line 348) | public String downloadBackedupAsset(String assetId, String versionId, ...
    method buildUrl (line 366) | private String buildUrl(String base, Map<String, Object> params) throw...

FILE: cloudinary-core/src/main/java/com/cloudinary/Configuration.java
  class Configuration (line 15) | public class Configuration {
    method Configuration (line 55) | public Configuration() {
    method Configuration (line 58) | private Configuration(
    method Configuration (line 109) | @SuppressWarnings("rawtypes")
    method update (line 114) | @SuppressWarnings("rawtypes")
    method asMap (line 152) | @SuppressWarnings("rawtypes")
    method Configuration (line 188) | public Configuration(Configuration other) {
    method from (line 226) | public static Configuration from(Configuration other) {
    method from (line 238) | public static Configuration from(String cloudinaryUrl) {
    method parseConfigUrl (line 245) | static protected Map parseConfigUrl(String cloudinaryUrl) {
    method updateMapfromURI (line 265) | static private void updateMapfromURI(Map params, URI cloudinaryUri) {
    method putNestedValue (line 284) | static private void putNestedValue(Map params, String key, String valu...
    method isNestedKey (line 299) | static private boolean isNestedKey(String key) {
    class Builder (line 306) | public static class Builder {
      method setTimeout (line 340) | public Builder setTimeout(int timeout) {
      method build (line 348) | public Configuration build() {
      method setCloudName (line 382) | public Builder setCloudName(String cloudName) {
      method setApiKey (line 391) | public Builder setApiKey(String apiKey) {
      method setApiSecret (line 400) | public Builder setApiSecret(String apiSecret) {
      method setSecureDistribution (line 409) | public Builder setSecureDistribution(String secureDistribution) {
      method setCname (line 418) | public Builder setCname(String cname) {
      method setSecure (line 426) | public Builder setSecure(boolean secure) {
      method setPrivateCdn (line 434) | public Builder setPrivateCdn(boolean privateCdn) {
      method setSecureCdnSubdomain (line 439) | public Builder setSecureCdnSubdomain(Boolean secureCdnSubdomain) {
      method setCdnSubdomain (line 448) | public Builder setCdnSubdomain(boolean cdnSubdomain) {
      method setShorten (line 453) | public Builder setShorten(boolean shorten) {
      method setCallback (line 458) | public Builder setCallback(String callback) {
      method setUploadPrefix (line 463) | public Builder setUploadPrefix(String uploadPrefix) {
      method setUseRootPath (line 468) | public Builder setUseRootPath(boolean useRootPath) {
      method setUseFetchFormat (line 473) | public Builder setUseFetchFormat(boolean useFetchFormat) {
      method setLoadStrategies (line 478) | public Builder setLoadStrategies(boolean loadStrategies) {
      method setAnalytics (line 483) | public Builder setAnalytics(boolean analytics) {
      method setClientHints (line 488) | public Builder setClientHints(boolean clientHints) {
      method setAuthToken (line 493) | public Builder setAuthToken(AuthToken authToken) {
      method setForceVersion (line 497) | public Builder setForceVersion(boolean forceVersion) {
      method setIsLongUrlSignature (line 502) | public Builder setIsLongUrlSignature(boolean isLong) {
      method setSignatureAlgorithm (line 507) | public Builder setSignatureAlgorithm(SignatureAlgorithm signatureAlg...
      method setSignatureVersion (line 512) | public Builder setSignatureVersion(int signatureVersion) {
      method setOAuthToken (line 517) | public Builder setOAuthToken(String oauthToken) {
      method from (line 528) | public Builder from(Configuration other) {

FILE: cloudinary-core/src/main/java/com/cloudinary/Coordinates.java
  class Coordinates (line 10) | public class Coordinates implements Serializable{
    method Coordinates (line 14) | public Coordinates() {
    method Coordinates (line 17) | public Coordinates(Collection<Rectangle> coordinates) {
    method Coordinates (line 21) | public Coordinates(int[] rect) {
    method Coordinates (line 30) | public Coordinates(Rectangle rect) {
    method Coordinates (line 36) | public Coordinates(String stringCoords) throws IllegalArgumentException {
    method parseCoordinates (line 52) | public static Coordinates parseCoordinates(Object coordinates) throws ...
    method addRect (line 64) | public void addRect(Rectangle rect) {
    method underlaying (line 68) | public Collection<Rectangle> underlaying() {
    method toString (line 72) | @Override

FILE: cloudinary-core/src/main/java/com/cloudinary/CustomFunction.java
  class CustomFunction (line 8) | public class CustomFunction extends BaseParam{
    method CustomFunction (line 10) | private CustomFunction(String... components) {
    method wasm (line 19) | public static CustomFunction wasm(String publicId){
    method remote (line 28) | public static CustomFunction remote(String url){

FILE: cloudinary-core/src/main/java/com/cloudinary/EagerTransformation.java
  class EagerTransformation (line 9) | public class EagerTransformation extends Transformation<EagerTransformat...
    method EagerTransformation (line 12) | @SuppressWarnings("rawtypes")
    method EagerTransformation (line 17) | public EagerTransformation() {
    method format (line 21) | public EagerTransformation format(String format) {
    method getFormat (line 26) | public String getFormat() {
    method generate (line 30) | @Override
    method generate (line 46) | @Override

FILE: cloudinary-core/src/main/java/com/cloudinary/ProgressCallback.java
  type ProgressCallback (line 6) | public interface ProgressCallback {
    method onProgress (line 12) | void onProgress(long bytesUploaded, long totalBytes);

FILE: cloudinary-core/src/main/java/com/cloudinary/ResponsiveBreakpoint.java
  class ResponsiveBreakpoint (line 5) | public class ResponsiveBreakpoint extends JSONObject {
    method ResponsiveBreakpoint (line 6) | public ResponsiveBreakpoint() {
    method isCreateDerived (line 10) | public boolean isCreateDerived() {
    method createDerived (line 14) | public ResponsiveBreakpoint createDerived(boolean createDerived) {
    method transformation (line 19) | public Transformation transformation() {
    method transformation (line 23) | public ResponsiveBreakpoint transformation(Transformation transformati...
    method format (line 28) | public ResponsiveBreakpoint format(String format) {
    method format (line 33) | public String format() {
    method maxWidth (line 37) | public int maxWidth() {
    method maxWidth (line 41) | public ResponsiveBreakpoint maxWidth(int maxWidth) {
    method minWidth (line 46) | public int minWidth() {
    method minWidth (line 50) | public ResponsiveBreakpoint minWidth(Integer minWidth) {
    method bytesStep (line 55) | public int bytesStep() {
    method bytesStep (line 59) | public ResponsiveBreakpoint bytesStep(Integer bytesStep) {
    method maxImages (line 64) | public int maxImages() {
    method maxImages (line 68) | public ResponsiveBreakpoint maxImages(Integer maxImages) {

FILE: cloudinary-core/src/main/java/com/cloudinary/Search.java
  class Search (line 14) | public class Search {
    method Search (line 25) | Search(Cloudinary cloudinary) {
    method ttl (line 34) | public Search ttl(int ttl) {
    method expression (line 38) | public Search expression(String value) {
    method maxResults (line 43) | public Search maxResults(Integer value) {
    method nextCursor (line 48) | public Search nextCursor(String value) {
    method aggregate (line 53) | public Search aggregate(String field) {
    method withField (line 60) | public Search withField(String field) {
    method sortBy (line 67) | public Search sortBy(String field, String dir) {
    method fields (line 80) | public Search fields(String field) {
    method toQuery (line 87) | public HashMap<String, Object> toQuery() {
    method execute (line 104) | public ApiResponse execute() throws Exception {
    method toUrl (line 110) | public String toUrl() throws Exception {
    method toUrl (line 114) | public String toUrl(String nextCursor) throws Exception {
    method toUrl (line 120) | public String toUrl(Integer ttl, String nextCursor) throws Exception {

FILE: cloudinary-core/src/main/java/com/cloudinary/SearchFolders.java
  class SearchFolders (line 9) | public class SearchFolders extends Search {
    method SearchFolders (line 11) | public SearchFolders(Cloudinary cloudinary) {
    method execute (line 15) | public ApiResponse execute() throws Exception {

FILE: cloudinary-core/src/main/java/com/cloudinary/SignatureAlgorithm.java
  type SignatureAlgorithm (line 6) | public enum SignatureAlgorithm {
    method SignatureAlgorithm (line 12) | SignatureAlgorithm(String algorithmId) {
    method getAlgorithmId (line 16) | public String getAlgorithmId() {

FILE: cloudinary-core/src/main/java/com/cloudinary/SmartUrlEncoder.java
  class SmartUrlEncoder (line 6) | public final class SmartUrlEncoder {
    method SmartUrlEncoder (line 7) | private SmartUrlEncoder() {}
    method encode (line 9) | public static String encode(String input) {

FILE: cloudinary-core/src/main/java/com/cloudinary/StoredFile.java
  class StoredFile (line 8) | public class StoredFile {
    method getVersion (line 29) | public Long getVersion() {
    method setVersion (line 33) | public void setVersion(Long version) {
    method getPublicId (line 37) | public String getPublicId() {
    method setPublicId (line 41) | public void setPublicId(String publicId) {
    method getPublicIdForSigning (line 45) | protected String getPublicIdForSigning() {
    method getFormat (line 49) | public String getFormat() {
    method setFormat (line 53) | public void setFormat(String format) {
    method getSignature (line 57) | public String getSignature() {
    method setSignature (line 61) | public void setSignature(String signature) {
    method getResourceType (line 65) | public String getResourceType() {
    method setResourceType (line 69) | public void setResourceType(String resourceType) {
    method getType (line 73) | public String getType() {
    method setType (line 77) | public void setType(String type) {
    method getPreloadedFile (line 81) | public String getPreloadedFile() {
    method setPreloadedFile (line 93) | public void setPreloadedFile(String uri) {
    method getComputedSignature (line 113) | public String getComputedSignature(Cloudinary cloudinary) {
    method getIsImage (line 121) | public boolean getIsImage() {
    method getIsVideo (line 125) | public boolean getIsVideo() {

FILE: cloudinary-core/src/main/java/com/cloudinary/Transformation.java
  class Transformation (line 14) | @SuppressWarnings({"rawtypes", "unchecked"})
    method Transformation (line 52) | public Transformation(Transformation transformation) {
    method Transformation (line 59) | public Transformation(List<Map> transformations) {
    method Transformation (line 68) | public Transformation() {
    method width (line 73) | public T width(Object value) {
    method height (line 77) | public T height(Object value) {
    method named (line 81) | public T named(String... value) {
    method crop (line 85) | public T crop(String value) {
    method background (line 89) | public T background(String value) {
    method color (line 93) | public T color(String value) {
    method effect (line 97) | public T effect(String value) {
    method effect (line 101) | public T effect(String effect, Object param) {
    method angle (line 105) | public T angle(int value) {
    method angle (line 109) | public T angle(String... value) {
    method border (line 113) | public T border(String value) {
    method border (line 117) | public T border(int width, String color) {
    method x (line 121) | public T x(Object value) {
    method y (line 125) | public T y(Object value) {
    method radius (line 137) | public T radius(Object value) {
    method radius (line 150) | public T radius(Object topLeftBottomRight, Object topRightBottomLeft) {
    method radius (line 164) | public T radius(Object topLeft, Object topRightBottomLeft, Object bott...
    method radius (line 179) | public T radius(Object topLeft, Object topRight, Object bottomRight, O...
    method radius (line 191) | public T radius(Object[] cornerRadiuses) {
    method quality (line 195) | public T quality(Object value) {
    method defaultImage (line 199) | public T defaultImage(String value) {
    method gravity (line 203) | public T gravity(String value) {
    method keyframeInterval (line 213) | public T keyframeInterval(float value) {
    method keyframeInterval (line 223) | public T keyframeInterval(String value) {
    method colorSpace (line 227) | public T colorSpace(String value) {
    method prefix (line 231) | public T prefix(String value) {
    method overlay (line 235) | public T overlay(String value) {
    method overlay (line 239) | public T overlay(AbstractLayer<?> value) {
    method underlay (line 243) | public T underlay(String value) {
    method underlay (line 247) | public T underlay(AbstractLayer<?> value) {
    method fetchFormat (line 251) | public T fetchFormat(String value) {
    method density (line 255) | public T density(Object value) {
    method page (line 259) | public T page(Object value) {
    method delay (line 263) | public T delay(Object value) {
    method opacity (line 267) | public T opacity(Object value) {
    method rawTransformation (line 271) | public T rawTransformation(String value) {
    method flags (line 275) | public T flags(String... value) {
    method dpr (line 279) | public T dpr(float value) {
    method dpr (line 283) | public T dpr(int value) {
    method dpr (line 287) | public T dpr(String value) {
    method duration (line 291) | public T duration(String value) {
    method duration (line 295) | public T duration(float value) {
    method duration (line 299) | public T duration(double value) {
    method durationPercent (line 303) | public T durationPercent(float value) {
    method durationPercent (line 307) | public T durationPercent(double value) {
    method startOffset (line 311) | public T startOffset(String value) {
    method startOffset (line 315) | public T startOffset(float value) {
    method startOffset (line 319) | public T startOffset(double value) {
    method startOffsetPercent (line 323) | public T startOffsetPercent(float value) {
    method startOffsetPercent (line 327) | public T startOffsetPercent(double value) {
    method endOffset (line 331) | public T endOffset(String value) {
    method endOffset (line 335) | public T endOffset(float value) {
    method endOffset (line 339) | public T endOffset(double value) {
    method endOffsetPercent (line 343) | public T endOffsetPercent(float value) {
    method endOffsetPercent (line 347) | public T endOffsetPercent(double value) {
    method offset (line 351) | public T offset(String value) {
    method offset (line 355) | public T offset(String[] value) {
    method offset (line 360) | public T offset(float[] value) {
    method offset (line 366) | public T offset(double[] value) {
    method offset (line 372) | public T offset(Number[] value) {
    method videoCodec (line 377) | public T videoCodec(String value) {
    method videoCodec (line 381) | public T videoCodec(Map<String, String> value) {
    method audioCodec (line 385) | public T audioCodec(String value) {
    method audioFrequency (line 389) | public T audioFrequency(String value) {
    method audioFrequency (line 393) | public T audioFrequency(int value) {
    method bitRate (line 397) | public T bitRate(String value) {
    method bitRate (line 401) | public T bitRate(int value) {
    method videoSampling (line 405) | public T videoSampling(String value) {
    method videoSamplingFrames (line 409) | public T videoSamplingFrames(int value) {
    method videoSamplingSeconds (line 413) | public T videoSamplingSeconds(Number value) {
    method videoSamplingSeconds (line 417) | public T videoSamplingSeconds(int value) {
    method videoSamplingSeconds (line 421) | public T videoSamplingSeconds(float value) {
    method videoSamplingSeconds (line 425) | public T videoSamplingSeconds(double value) {
    method zoom (line 429) | public T zoom(String value) {
    method zoom (line 433) | public T zoom(float value) {
    method zoom (line 437) | public T zoom(double value) {
    method aspectRatio (line 441) | public T aspectRatio(double value) {
    method aspectRatio (line 445) | public T aspectRatio(String value) {
    method aspectRatio (line 449) | public T aspectRatio(int nom, int denom) {
    method responsiveWidth (line 453) | public T responsiveWidth(boolean value) {
    method ifCondition (line 462) | public Condition ifCondition() {
    method ifCondition (line 472) | public T ifCondition(String condition) {
    method ifCondition (line 483) | public T ifCondition(Expression expression) {
    method ifCondition (line 493) | public T ifCondition(Condition condition) {
    method ifElse (line 497) | public T ifElse() {
    method endIf (line 502) | public T endIf() {
    method fps (line 531) | public T fps(String value) {
    method fps (line 541) | public T fps(double value) {
    method fps (line 551) | public T fps(int value) {
    method fps (line 561) | public T fps(Object rangeStart, Object rangeEnd){
    method streamingProfile (line 579) | public T streamingProfile(String value) {
    method isResponsive (line 583) | public boolean isResponsive() {
    method isHiDPI (line 587) | public boolean isHiDPI() {
    method params (line 592) | public T params(Map transformation) {
    method chain (line 598) | public T chain() {
    method chainWith (line 602) | public T chainWith(Transformation transformation) {
    method param (line 608) | public T param(String key, Object value) {
    method generate (line 622) | public String generate() {
    method toString (line 626) | @Override
    method generate (line 631) | public String generate(Iterable<Map> optionsList) {
    method generate (line 641) | public String generate(Map options) {
    method replaceColorPrefix (line 806) | private String replaceColorPrefix(String color) {
    method processVar (line 810) | private String processVar(Expression[] variables) {
    method isValidAttrValue (line 827) | private boolean isValidAttrValue(String value) {
    method getHtmlWidth (line 837) | public String getHtmlWidth() {
    method getHtmlHeight (line 841) | public String getHtmlHeight() {
    method dup (line 845) | private static List<Map> dup(List<Map> transformations) {
    method setResponsiveWidthTransformation (line 853) | public static void setResponsiveWidthTransformation(Map transformation) {
    method getResponsiveWidthTransformation (line 857) | private static Map getResponsiveWidthTransformation() {
    method setDefaultIsResponsive (line 867) | public static void setDefaultIsResponsive(boolean isResponsive) {
    method setDefaultDPR (line 871) | public static void setDefaultDPR(Object dpr) {
    method splitRange (line 875) | private static String[] splitRange(Object range) {
    method normRangeValue (line 889) | private static String normRangeValue(Object objectValue) {
    method normAutoRangeValue (line 907) | private static String normAutoRangeValue(Object objectValue) {
    method processVideoCodecParam (line 914) | private static String processVideoCodecParam(Object param) {
    method variable (line 942) | public T variable(String name, Object value) {
    method variables (line 952) | public T variables(Expression... variables) {
    method customFunction (line 961) | public T customFunction(CustomFunction action) {
    method customPreFunction (line 970) | public T customPreFunction(CustomFunction action) {
    method radiusToExpression (line 974) | private String radiusToExpression(Object[] radiusOption) {

FILE: cloudinary-core/src/main/java/com/cloudinary/Uploader.java
  class Uploader (line 14) | @SuppressWarnings({"rawtypes", "unchecked"})
    class Command (line 19) | private final class Command {
      method Command (line 25) | private Command() {
    method callApi (line 29) | public Map callApi(String action, Map<String, Object> params, Map opti...
    method callApi (line 33) | public Map callApi(String action, Map<String, Object> params, Map opti...
    method Uploader (line 40) | public Uploader(Cloudinary cloudinary, AbstractUploaderStrategy strate...
    method cloudinary (line 46) | public Cloudinary cloudinary() {
    method buildUploadParams (line 50) | public Map<String, Object> buildUploadParams(Map options) {
    method unsignedUpload (line 54) | public Map unsignedUpload(Object file, String uploadPreset, Map option...
    method unsignedUpload (line 58) | public Map unsignedUpload(Object file, String uploadPreset, Map option...
    method upload (line 67) | public Map upload(Object file, Map options) throws IOException {
    method upload (line 71) | public Map upload(Object file, Map options, final ProgressCallback pro...
    method uploadLargeRaw (line 79) | public Map uploadLargeRaw(Object file, Map options) throws IOException {
    method uploadLargeRaw (line 83) | public Map uploadLargeRaw(Object file, Map options, ProgressCallback p...
    method uploadLargeRaw (line 87) | public Map uploadLargeRaw(Object file, Map options, int bufferSize) th...
    method uploadLargeRaw (line 91) | public Map uploadLargeRaw(Object file, Map options, int bufferSize, Pr...
    method uploadLarge (line 98) | public Map uploadLarge(Object file, Map options) throws IOException {
    method uploadLarge (line 102) | public Map uploadLarge(Object file, Map options, ProgressCallback prog...
    method uploadLarge (line 107) | @SuppressWarnings("resource")
    method uploadLarge (line 112) | public Map uploadLarge(Object file, Map options, int bufferSize, Progr...
    method uploadLarge (line 116) | public Map uploadLarge(Object file, Map options, int bufferSize, long ...
    method uploadLargeParts (line 159) | private Map uploadLargeParts(InputStream input, Map options, int buffe...
    method destroy (line 230) | public Map destroy(String publicId, Map options) throws IOException {
    method rename (line 241) | public Map rename(String fromPublicId, String toPublicId, Map options)...
    method explicit (line 257) | public Map explicit(String publicId, Map options) throws IOException {
    method generateSprite (line 266) | public Map generateSprite(String tag, Map options) throws IOException {
    method generateSprite (line 275) | public Map generateSprite(String[] urls, Map options) throws IOExcepti...
    method multi (line 284) | public Map multi(String[] urls, Map options) throws IOException {
    method multi (line 294) | public Map multi(String tag, Map options) throws IOException {
    method multi (line 304) | private Map multi(Map options) throws IOException {
    method explode (line 308) | public Map explode(String public_id, Map options) throws IOException {
    method addTag (line 337) | public Map addTag(String tag, String[] publicIds, Map options) throws ...
    method addTag (line 353) | public Map addTag(String[] tag, String[] publicIds, Map options) throw...
    method removeTag (line 373) | public Map removeTag(String tag, String[] publicIds, Map options) thro...
    method removeTag (line 389) | public Map removeTag(String[] tag, String[] publicIds, Map options) th...
    method removeAllTags (line 406) | public Map removeAllTags(String[] publicIds, Map options) throws IOExc...
    method replaceTag (line 424) | public Map replaceTag(String tag, String[] publicIds, Map options) thr...
    method replaceTag (line 440) | public Map replaceTag(String[] tag, String[] publicIds, Map options) t...
    method callTagsApi (line 446) | public Map callTagsApi(String[] tag, String command, String[] publicId...
    method addContext (line 467) | public Map addContext(Map context, String[] publicIds, Map options) th...
    method addContext (line 479) | public Map addContext(String context, String[] publicIds, Map options)...
    method removeAllContext (line 490) | public Map removeAllContext(String[] publicIds, Map options) throws IO...
    method callContextApi (line 494) | protected Map callContextApi(Map context, String command, String[] pub...
    method callContextApi (line 498) | protected Map callContextApi(String context, String command, String[] ...
    method text (line 514) | public Map text(String text, Map options) throws IOException {
    method createArchive (line 525) | public Map createArchive(Map options, String targetFormat) throws IOEx...
    method createZip (line 530) | public Map createZip(Map options) throws IOException {
    method createArchive (line 534) | public Map createArchive(ArchiveParams params) throws IOException {
    method signRequestParams (line 538) | public void signRequestParams(Map<String, Object> params, Map options) {
    method uploadTagParams (line 544) | public String uploadTagParams(Map options) {
    method getUploadUrl (line 568) | public String getUploadUrl(Map options) {
    method unsignedImageUploadTag (line 574) | public String unsignedImageUploadTag(String field, String uploadPreset...
    method imageUploadTag (line 581) | public String imageUploadTag(String field, Map options, Map<String, Ob...
    method deleteByToken (line 608) | public Map deleteByToken(String token) throws Exception {
    method updateMetadata (line 620) | public Map updateMetadata(Map metadata, String[] publicIds, Map option...

FILE: cloudinary-core/src/main/java/com/cloudinary/Url.java
  class Url (line 22) | public class Url {
    method Url (line 49) | public Url(Cloudinary cloudinary) {
    method clone (line 56) | public Url clone() {
    method fromIdentifier (line 91) | public Url fromIdentifier(String identifier) {
    method type (line 127) | public Url type(String type) {
    method resourcType (line 132) | public Url resourcType(String resourceType) {
    method resourceType (line 136) | public Url resourceType(String resourceType) {
    method publicId (line 141) | public Url publicId(Object publicId) {
    method format (line 146) | public Url format(String format) {
    method cloudName (line 151) | public Url cloudName(String cloudName) {
    method secureDistribution (line 156) | public Url secureDistribution(String secureDistribution) {
    method secureCdnSubdomain (line 161) | public Url secureCdnSubdomain(boolean secureCdnSubdomain) {
    method suffix (line 166) | public Url suffix(String urlSuffix) {
    method useRootPath (line 171) | public Url useRootPath(boolean useRootPath) {
    method useFetchFormat (line 176) | public Url useFetchFormat(boolean useFetchFormat) {
    method cname (line 181) | public Url cname(String cname) {
    method version (line 186) | public Url version(Object version) {
    method transformation (line 191) | public Url transformation(Transformation transformation) {
    method secure (line 196) | public Url secure(boolean secure) {
    method privateCdn (line 201) | public Url privateCdn(boolean privateCdn) {
    method cdnSubdomain (line 206) | public Url cdnSubdomain(boolean cdnSubdomain) {
    method shorten (line 211) | public Url shorten(boolean shorten) {
    method transformation (line 216) | public Transformation transformation() {
    method signed (line 222) | public Url signed(boolean signUrl) {
    method authToken (line 242) | public Url authToken(AuthToken authToken) {
    method longUrlSignature (line 253) | public Url longUrlSignature(boolean isLong) {
    method sourceTransformation (line 258) | public Url sourceTransformation(Map<String, Transformation> sourceTran...
    method sourceTransformationFor (line 263) | public Url sourceTransformationFor(String source, Transformation trans...
    method sourceTypes (line 271) | public Url sourceTypes(String[] sourceTypes) {
    method fallbackContent (line 276) | public Url fallbackContent(String fallbackContent) {
    method posterTransformation (line 281) | public Url posterTransformation(Transformation posterTransformation) {
    method posterTransformation (line 286) | @SuppressWarnings("rawtypes")
    method posterTransformation (line 292) | @SuppressWarnings({"rawtypes", "unchecked"})
    method posterSource (line 302) | public Url posterSource(String posterSource) {
    method posterUrl (line 307) | public Url posterUrl(Url posterUrl) {
    method poster (line 312) | public Url poster(Object poster) {
    method forceVersion (line 338) | public Url forceVersion(boolean forceVersion){
    method generate (line 343) | public String generate() {
    method generate (line 347) | public String generate(String source) {
    method finalizeSource (line 440) | private String[] finalizeSource(String source, String format, String u...
    method finalizeResourceType (line 470) | public String finalizeResourceType(String resourceType, String type, S...
    method unsignedDownloadUrlPrefix (line 514) | public static String unsignedDownloadUrlPrefix(String source, Configur...
    method shard (line 559) | private static String shard(String input) {
    method imageTag (line 565) | @SuppressWarnings("unchecked")
    method imageTag (line 570) | public String imageTag(Map<String, String> attributes) {
    method imageTag (line 574) | public String imageTag(String source, Map<String, String> attributes) {
    method videoTag (line 609) | public String videoTag() {
    method videoTag (line 613) | public String videoTag(String source) {
    method videoTag (line 617) | public String videoTag(Map<String, String> attributes) {
    method finalizePosterUrl (line 621) | private String finalizePosterUrl(String source) {
    method appendVideoSources (line 637) | private void appendVideoSources(StringBuilder html, String source, Str...
    method videoTag (line 659) | public String videoTag(String source, Map<String, String> attributes) {
    method generateSpriteCss (line 725) | public String generateSpriteCss(String source) {
    method source (line 732) | public Url source(String source) {
    method source (line 737) | public Url source(StoredFile source) {

FILE: cloudinary-core/src/main/java/com/cloudinary/Util.java
  class Util (line 11) | public final class Util {
    method Util (line 12) | private Util() {}
    method buildUploadParams (line 19) | @SuppressWarnings({"rawtypes", "unchecked"})
    method buildMultiParams (line 82) | public static Map buildMultiParams(Map options) {
    method buildGenerateSpriteParams (line 105) | public static Map<String, Object> buildGenerateSpriteParams(Map option...
    method buildEager (line 133) | protected static final String buildEager(List<? extends Transformation...
    method processWriteParameters (line 149) | @SuppressWarnings("unchecked")
    method encodeAccessControl (line 198) | protected static String encodeAccessControl(Object accessControl) {
    method encodeContext (line 206) | protected static String encodeContext(Object context) {
    method encodeList (line 229) | private static String encodeList(Object[] list) {
    method encodeSingleContextString (line 245) | private static String encodeSingleContextString(String value) {
    method buildCustomHeaders (line 249) | @SuppressWarnings("unchecked")
    method clearEmpty (line 267) | @SuppressWarnings("rawtypes")
    method buildArchiveParams (line 277) | @SuppressWarnings({"rawtypes", "unchecked"})
    method putEager (line 305) | private static void putEager(String name, Map from, Map<String, Object...
    method putBoolean (line 311) | private static void putBoolean(String name, Map from, Map<String, Obje...
    method putObject (line 318) | private static void putObject(String name, Map from, Map<String, Objec...
    method putObject (line 322) | private static void putObject(String name, Map from, Map<String, Objec...
    method putArray (line 331) | private static void putArray(String name, Map from, Map<String, Object...
    method timestamp (line 338) | protected static String timestamp() {
    method getUTF8Bytes (line 348) | public static byte[] getUTF8Bytes(String string) {
    method produceSignature (line 369) | public static String produceSignature(Map<String, Object> paramsToSign...
    method produceSignature (line 387) | public static String produceSignature(Map<String, Object> paramsToSign...
    method flattenAndSanitizeParams (line 394) | private static Collection<String> flattenAndSanitizeParams(Map<String,...
    method escapeAmpersand (line 421) | private static String escapeAmpersand(String input) {
    method hash (line 432) | public static byte[] hash(String input, SignatureAlgorithm signatureAl...

FILE: cloudinary-core/src/main/java/com/cloudinary/api/ApiResponse.java
  type ApiResponse (line 6) | @SuppressWarnings("rawtypes")
    method rateLimits (line 8) | Map<String, RateLimit> rateLimits() throws ParseException;
    method apiRateLimit (line 10) | RateLimit apiRateLimit() throws ParseException;

FILE: cloudinary-core/src/main/java/com/cloudinary/api/AuthorizationRequired.java
  class AuthorizationRequired (line 5) | public class AuthorizationRequired extends ApiException {
    method AuthorizationRequired (line 8) | public AuthorizationRequired(String message) {

FILE: cloudinary-core/src/main/java/com/cloudinary/api/RateLimit.java
  class RateLimit (line 5) | public class RateLimit {
    method RateLimit (line 10) | public RateLimit() {
    method getLimit (line 14) | public long getLimit() {
    method setLimit (line 18) | public void setLimit(long limit) {
    method getRemaining (line 22) | public long getRemaining() {
    method setRemaining (line 26) | public void setRemaining(long remaining) {
    method getReset (line 30) | public Date getReset() {
    method setReset (line 34) | public void setReset(Date reset) {

FILE: cloudinary-core/src/main/java/com/cloudinary/api/exceptions/AlreadyExists.java
  class AlreadyExists (line 3) | public class AlreadyExists extends ApiException {
    method AlreadyExists (line 6) | public AlreadyExists(String message) {

FILE: cloudinary-core/src/main/java/com/cloudinary/api/exceptions/ApiException.java
  class ApiException (line 3) | public class ApiException extends Exception {
    method ApiException (line 6) | public ApiException(String message) {

FILE: cloudinary-core/src/main/java/com/cloudinary/api/exceptions/BadRequest.java
  class BadRequest (line 4) | public class BadRequest extends ApiException {
    method BadRequest (line 7) | public BadRequest(String message) {

FILE: cloudinary-core/src/main/java/com/cloudinary/api/exceptions/GeneralError.java
  class GeneralError (line 3) | public class GeneralError extends ApiException {
    method GeneralError (line 6) | public GeneralError(String message) {

FILE: cloudinary-core/src/main/java/com/cloudinary/api/exceptions/NotAllowed.java
  class NotAllowed (line 4) | public class NotAllowed extends ApiException {
    method NotAllowed (line 7) | public NotAllowed(String message) {

FILE: cloudinary-core/src/main/java/com/cloudinary/api/exceptions/NotFound.java
  class NotFound (line 4) | public class NotFound extends ApiException {
    method NotFound (line 7) | public NotFound(String message) {

FILE: cloudinary-core/src/main/java/com/cloudinary/api/exceptions/RateLimited.java
  class RateLimited (line 4) | public class RateLimited extends ApiException {
    method RateLimited (line 7) | public RateLimited(String message) {

FILE: cloudinary-core/src/main/java/com/cloudinary/api/signing/ApiResponseSignatureVerifier.java
  class ApiResponseSignatureVerifier (line 13) | public class ApiResponseSignatureVerifier {
    method ApiResponseSignatureVerifier (line 23) | public ApiResponseSignatureVerifier(String secretKey) {
    method ApiResponseSignatureVerifier (line 39) | public ApiResponseSignatureVerifier(String secretKey, SignatureAlgorit...
    method verifySignature (line 60) | public boolean verifySignature(String publicId, String version, String...

FILE: cloudinary-core/src/main/java/com/cloudinary/api/signing/NotificationRequestSignatureVerifier.java
  class NotificationRequestSignatureVerifier (line 11) | public class NotificationRequestSignatureVerifier {
    method NotificationRequestSignatureVerifier (line 19) | public NotificationRequestSignatureVerifier(String secretKey) {
    method NotificationRequestSignatureVerifier (line 29) | public NotificationRequestSignatureVerifier(String secretKey, Signatur...
    method verifySignature (line 43) | public boolean verifySignature(String body, String timestamp, String s...
    method verifySignature (line 63) | public boolean verifySignature(String body, String timestamp, String s...

FILE: cloudinary-core/src/main/java/com/cloudinary/api/signing/SignedPayloadValidator.java
  class SignedPayloadValidator (line 9) | class SignedPayloadValidator {
    method SignedPayloadValidator (line 13) | SignedPayloadValidator(String secretKey, SignatureAlgorithm signatureA...
    method validateSignedPayload (line 22) | boolean validateSignedPayload(String signedPayload, String signature) {

FILE: cloudinary-core/src/main/java/com/cloudinary/metadata/DateMetadataField.java
  class DateMetadataField (line 11) | public class DateMetadataField extends MetadataField<Date> {
    method DateMetadataField (line 13) | public DateMetadataField() {
    method setDefaultValue (line 21) | @Override
    method getDefaultValue (line 31) | @Override

FILE: cloudinary-core/src/main/java/com/cloudinary/metadata/EnumMetadataField.java
  class EnumMetadataField (line 6) | public class EnumMetadataField extends MetadataField<String> {
    method EnumMetadataField (line 7) | EnumMetadataField() {

FILE: cloudinary-core/src/main/java/com/cloudinary/metadata/IntMetadataField.java
  class IntMetadataField (line 6) | public class IntMetadataField extends MetadataField<Integer> {
    method IntMetadataField (line 7) | public IntMetadataField() {

FILE: cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataDataSource.java
  class MetadataDataSource (line 12) | public class MetadataDataSource extends JSONObject {
    method MetadataDataSource (line 17) | public MetadataDataSource(List<Entry> entries) {
    class Entry (line 24) | public static class Entry extends JSONObject {
      method Entry (line 25) | public Entry(String externalId, String value){
      method Entry (line 34) | public Entry(String value){
      method setExternalId (line 42) | public void setExternalId(String externalId) {
      method getExternalId (line 50) | public String getExternalId() {
      method setValue (line 58) | public void setValue(String value) {
      method getValue (line 66) | public String getValue() {

FILE: cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataField.java
  class MetadataField (line 11) | public class MetadataField<T> extends JSONObject {
    method MetadataField (line 23) | public MetadataField(MetadataFieldType type) {
    method MetadataField (line 27) | public MetadataField(String type) {
    method getType (line 35) | public MetadataFieldType getType() {
    method getExternalId (line 43) | public String getExternalId() {
    method setExternalId (line 51) | public void setExternalId(String externalId) {
    method getLabel (line 59) | public String getLabel() {
    method setLabel (line 67) | public void setLabel(String label) {
    method isMandatory (line 75) | public boolean isMandatory() {
    method setMandatory (line 83) | public void setMandatory(Boolean mandatory) {
    method getDefaultValue (line 92) | public T getDefaultValue() throws ParseException {
    method setDefaultValue (line 101) | public void setDefaultValue(T defaultValue) {
    method getValidation (line 109) | public MetadataValidation getValidation() {
    method setValidation (line 117) | public void setValidation(MetadataValidation validation) {
    method getDataSource (line 125) | public MetadataDataSource getDataSource() {
    method setDataSource (line 133) | public void setDataSource(MetadataDataSource dataSource) {
    method setRestrictions (line 141) | public void setRestrictions(Restrictions restrictions) {
    method setDefaultDisabled (line 149) | public void setDefaultDisabled(Boolean disabled) {
    method setAllowDynamicListValues (line 157) | public void setAllowDynamicListValues(Boolean allowDynamicListValues) ...

FILE: cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataFieldType.java
  type MetadataFieldType (line 6) | public enum MetadataFieldType  {
    method toString (line 13) | @Override

FILE: cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataRule.java
  class MetadataRule (line 8) | public class MetadataRule {
    method MetadataRule (line 14) | public MetadataRule(String metadataFieldId, String name, MetadataRuleC...
    method getMetadataFieldId (line 21) | public String getMetadataFieldId() {
    method setMetadataFieldId (line 25) | public void setMetadataFieldId(String metadataFieldId) {
    method getName (line 29) | public String getName() {
    method setName (line 33) | public void setName(String name) {
    method getCondition (line 37) | public MetadataRuleCondition getCondition() {
    method setCondition (line 41) | public void setCondition(MetadataRuleCondition condition) {
    method getResult (line 45) | public MetadataRuleResult getResult() {
    method setResult (line 49) | public void setResult(MetadataRuleResult result) {
    method asMap (line 53) | public Map asMap() {

FILE: cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataRuleCondition.java
  class MetadataRuleCondition (line 5) | public class MetadataRuleCondition {
    method MetadataRuleCondition (line 11) | public MetadataRuleCondition(String metadata_field_id, Boolean populat...
    method getMetadata_field_id (line 18) | public String getMetadata_field_id() {
    method setMetadata_field_id (line 22) | public void setMetadata_field_id(String metadata_field_id) {
    method getPopulated (line 26) | public Boolean getPopulated() {
    method setPopulated (line 30) | public void setPopulated(Boolean populated) {
    method getIncludes (line 34) | public Map<String, String> getIncludes() {
    method setIncludes (line 38) | public void setIncludes(Map<String, String> includes) {
    method getEquals (line 42) | public String getEquals() {
    method setEquals (line 46) | public void setEquals(String equals) {
    method asMap (line 50) | public Map asMap() {

FILE: cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataRuleResult.java
  class MetadataRuleResult (line 6) | public class MetadataRuleResult {
    method MetadataRuleResult (line 12) | public MetadataRuleResult(Boolean enabled, String activateValues, Stri...
    method getEnabled (line 19) | public Boolean getEnabled() {
    method setEnabled (line 23) | public void setEnabled(Boolean enabled) {
    method getActivateValues (line 27) | public String getActivateValues() {
    method setActivateValues (line 31) | public void setActivateValues(String activateValues) {
    method getApplyValues (line 35) | public String getApplyValues() {
    method setApplyValues (line 39) | public void setApplyValues(String applyValues) {
    method getSetMandatory (line 43) | public Boolean getSetMandatory() {
    method setSetMandatory (line 47) | public void setSetMandatory(Boolean setMandatory) {
    method asMap (line 50) | public Map asMap() {

FILE: cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataValidation.java
  class MetadataValidation (line 13) | public abstract class MetadataValidation extends JSONObject {
    class AndValidator (line 27) | public static class AndValidator extends MetadataValidation {
      method AndValidator (line 35) | public AndValidator(List<MetadataValidation> rules) {
    class StringLength (line 44) | public static class StringLength extends MetadataValidation {
      method StringLength (line 50) | public StringLength(Integer min, Integer max) {
    class ComparisonRule (line 61) | public abstract static class ComparisonRule<T> extends MetadataValidat...
      method ComparisonRule (line 62) | public ComparisonRule(String type, T value) {
      method ComparisonRule (line 66) | public ComparisonRule(String type, T value, Boolean equals) {
      method putValue (line 74) | protected void putValue(T value) {
    class IntGreaterThan (line 82) | public static class IntGreaterThan extends ComparisonRule<Integer> {
      method IntGreaterThan (line 87) | public IntGreaterThan(Integer value) {
      method IntGreaterThan (line 96) | public IntGreaterThan(Integer value, Boolean equals) {
    class DateGreaterThan (line 104) | public static class DateGreaterThan extends ComparisonRule<Date> {
      method DateGreaterThan (line 109) | public DateGreaterThan(Date value) {
      method DateGreaterThan (line 118) | public DateGreaterThan(Date value, Boolean equals) {
      method putValue (line 122) | @Override
    class IntLessThan (line 131) | public static class IntLessThan extends ComparisonRule<Integer> {
      method IntLessThan (line 136) | public IntLessThan(Integer value) {
      method IntLessThan (line 145) | public IntLessThan(Integer value, Boolean equals) {
    class DateLessThan (line 153) | public static class DateLessThan extends ComparisonRule<Date> {
      method DateLessThan (line 158) | public DateLessThan(Date value) {
      method DateLessThan (line 167) | public DateLessThan(Date value, Boolean equals) {
      method putValue (line 171) | @Override

FILE: cloudinary-core/src/main/java/com/cloudinary/metadata/Restrictions.java
  class Restrictions (line 8) | public class Restrictions {
    method setRestriction (line 17) | public Restrictions setRestriction(String key, Object value) {
    method setReadOnlyUI (line 26) | public Restrictions setReadOnlyUI(Boolean value) {
    method setReadOnlyUI (line 33) | public Restrictions setReadOnlyUI() {
    method toHash (line 37) | public HashMap toHash() {

FILE: cloudinary-core/src/main/java/com/cloudinary/metadata/SetMetadataField.java
  class SetMetadataField (line 8) | public class SetMetadataField extends MetadataField<List<String>> {
    method SetMetadataField (line 9) | public SetMetadataField() {

FILE: cloudinary-core/src/main/java/com/cloudinary/metadata/StringMetadataField.java
  class StringMetadataField (line 6) | public class StringMetadataField extends MetadataField<String> {
    method StringMetadataField (line 7) | public StringMetadataField() {

FILE: cloudinary-core/src/main/java/com/cloudinary/provisioning/Account.java
  class Account (line 16) | public class Account {
    method Account (line 37) | public Account(Cloudinary cloudinary) {
    method Account (line 58) | public Account(AccountConfiguration accountConfiguration, Cloudinary c...
    method callAccountApi (line 66) | private ApiResponse callAccountApi(Api.HttpMethod method, List<String>...
    type Role (line 106) | public enum Role {
      method Role (line 117) | Role(String serializedValue) {
      method toString (line 121) | @Override
    method subAccount (line 135) | public ApiResponse subAccount(String subAccountId) throws Exception {
    method subAccount (line 147) | public ApiResponse subAccount(String subAccountId, Map<String, Object>...
    method subAccounts (line 161) | public ApiResponse subAccounts(Boolean enabled, List<String> ids, Stri...
    method subAccounts (line 175) | public ApiResponse subAccounts(Boolean enabled, List<String> ids, Stri...
    method createSubAccount (line 190) | public ApiResponse createSubAccount(String name, String cloudName, Map...
    method createSubAccount (line 204) | public ApiResponse createSubAccount(String name, String cloudName, Map...
    method updateSubAccount (line 228) | public ApiResponse updateSubAccount(String subAccountId, String name, ...
    method updateSubAccount (line 242) | public ApiResponse updateSubAccount(String subAccountId, String name, ...
    method deleteSubAccount (line 263) | public ApiResponse deleteSubAccount(String subAccountId) throws Except...
    method deleteSubAccount (line 275) | public ApiResponse deleteSubAccount(String subAccountId, Map<String, O...
    method user (line 288) | public ApiResponse user(String userId) throws Exception {
    method user (line 300) | public ApiResponse user(String userId, Map<String, Object> options) th...
    method users (line 315) | public ApiResponse users(Boolean pending, List<String> userIds, String...
    method users (line 330) | public ApiResponse users(Boolean pending, List<String> userIds, String...
    method createUser (line 351) | public ApiResponse createUser(String name, String email, Role role, Li...
    method createUser (line 367) | public ApiResponse createUser(String name, String email, Role role, Li...
    method createUser (line 384) | public ApiResponse createUser(String name, String email, Role role, Bo...
    method updateUser (line 401) | public ApiResponse updateUser(String userId, String name, String email...
    method updateUser (line 418) | public ApiResponse updateUser(String userId, String name, String email...
    method updateUser (line 436) | public ApiResponse updateUser(String userId, String name, String email...
    method deleteUser (line 448) | public ApiResponse deleteUser(String userId) throws Exception {
    method deleteUser (line 460) | public ApiResponse deleteUser(String userId, Map<String, Object> optio...
    method createUserGroup (line 472) | public ApiResponse createUserGroup(String name) throws Exception {
    method createUserGroup (line 483) | public ApiResponse createUserGroup(String name, Map<String, Object> op...
    method updateUserGroup (line 496) | public ApiResponse updateUserGroup(String groupId, String name) throws...
    method updateUserGroup (line 509) | public ApiResponse updateUserGroup(String groupId, String name, Map<St...
    method deleteUserGroup (line 521) | public ApiResponse deleteUserGroup(String groupId) throws Exception {
    method deleteUserGroup (line 533) | public ApiResponse deleteUserGroup(String groupId, Map<String, Object>...
    method addUserToGroup (line 544) | public ApiResponse addUserToGroup(String groupId, String userId) throw...
    method addUserToGroup (line 554) | public ApiResponse addUserToGroup(String groupId, String userId, Map<S...
    method removeUserFromGroup (line 566) | public ApiResponse removeUserFromGroup(String groupId, String userId) ...
    method removeUserFromGroup (line 577) | public ApiResponse removeUserFromGroup(String groupId, String userId, ...
    method userGroup (line 588) | public ApiResponse userGroup(String groupId) throws Exception {
    method userGroup (line 599) | public ApiResponse userGroup(String groupId, Map<String, Object> optio...
    method userGroups (line 609) | public ApiResponse userGroups() throws Exception {
    method userGroups (line 619) | public ApiResponse userGroups(Map<String, Object> options) throws Exce...
    method userGroupUsers (line 630) | public ApiResponse userGroupUsers(String groupId) throws Exception {
    method userGroupUsers (line 640) | public ApiResponse userGroupUsers(String groupId, Map<String, Object> ...
    method getAccessKeys (line 652) | public ApiResponse getAccessKeys(String subAccountId, Map<String, Obje...
    method createAccessKey (line 666) | public ApiResponse createAccessKey(String subAccountId, String name, B...
    method updateAccessKey (line 681) | public ApiResponse updateAccessKey(String subAccountId, String accessK...
    method deleteAccessKey (line 694) | public ApiResponse deleteAccessKey(String subAccountId, String accessK...
    method performUserAction (line 711) | private ApiResponse performUserAction(Api.HttpMethod method, List<Stri...
    method verifyOptions (line 724) | private Map<String, Object> verifyOptions(Map<String, Object> options) {
    method getAuthorizationHeaderValue (line 732) | protected String getAuthorizationHeaderValue(String apiKey, String api...

FILE: cloudinary-core/src/main/java/com/cloudinary/provisioning/AccountConfiguration.java
  class AccountConfiguration (line 7) | public class AccountConfiguration {
    method AccountConfiguration (line 13) | public AccountConfiguration(String accountId, String provisioningApiKe...
    method from (line 19) | public static AccountConfiguration from(String accountUrl) {

FILE: cloudinary-core/src/main/java/com/cloudinary/strategies/AbstractApiStrategy.java
  class AbstractApiStrategy (line 9) | public abstract class AbstractApiStrategy {
    method init (line 12) | public void init(Api api) {
    method callApi (line 16) | @SuppressWarnings("rawtypes")
    method callAccountApi (line 19) | public abstract ApiResponse callAccountApi(HttpMethod method, String a...

FILE: cloudinary-core/src/main/java/com/cloudinary/strategies/AbstractUploaderStrategy.java
  class AbstractUploaderStrategy (line 16) | public abstract class AbstractUploaderStrategy {
    method init (line 20) | public void init(Uploader uploader) {
    method cloudinary (line 24) | public Cloudinary cloudinary() {
    method callApi (line 28) | @SuppressWarnings("rawtypes")
    method callApi (line 33) | public abstract Map callApi(String action, Map<String, Object> params,...
    method buildUploadUrl (line 35) | protected String buildUploadUrl(String action, Map options) {
    method processResponse (line 51) | protected Map processResponse(boolean returnError, int code, String re...
    method includesServerResponse (line 92) | private boolean includesServerResponse(int code) {
    method requiresSigning (line 96) | protected boolean requiresSigning(String action, Map options) {

FILE: cloudinary-core/src/main/java/com/cloudinary/strategies/StrategyLoader.java
  class StrategyLoader (line 5) | public class StrategyLoader {
    method load (line 7) | @SuppressWarnings("unchecked")
    method find (line 18) | public static <T> T find(List<String> strategies) {
    method exists (line 29) | public boolean exists(List<String> strategies) {

FILE: cloudinary-core/src/main/java/com/cloudinary/transformation/AbstractLayer.java
  class AbstractLayer (line 8) | public abstract class AbstractLayer<T extends AbstractLayer<T>> implemen...
    method getThis (line 9) | abstract T getThis();
    method resourceType (line 16) | public T resourceType(String resourceType) {
    method type (line 21) | public T type(String type) {
    method publicId (line 26) | public T publicId(String publicId) {
    method format (line 31) | public T format(String format) {
    method toString (line 36) | @Override
    method formattedPublicId (line 57) | protected String formattedPublicId() {

FILE: cloudinary-core/src/main/java/com/cloudinary/transformation/BaseExpression.java
  class BaseExpression (line 16) | public abstract class BaseExpression<T extends BaseExpression> {
    method BaseExpression (line 61) | protected BaseExpression() {
    method normalize (line 71) | public static String normalize(Object expression) {
    method normalizeBuiltins (line 96) | private static String normalizeBuiltins(String input) {
    method getPattern (line 117) | private static Pattern getPattern() {
    method getParent (line 131) | public Transformation getParent() {
    method setParent (line 135) | public T setParent(Transformation parent) {
    method serialize (line 140) | public String serialize() {
    method toString (line 144) | @Override
    method clone (line 149) | @SuppressWarnings("MethodDoesntCallSuperMethod")
    method multiple (line 158) | public T multiple(Object value) {
    method newInstance (line 164) | abstract protected T newInstance();
    method gt (line 166) | public T gt(Object value) {
    method gt (line 170) | public T gt() {
    method and (line 175) | public T and(Object value) {
    method and (line 179) | public T and() {
    method or (line 184) | public T or(Object value) {
    method or (line 188) | public T or() {
    method eq (line 193) | public T eq(Object value) {
    method eq (line 197) | public T eq() {
    method ne (line 202) | public T ne(Object value) {
    method ne (line 206) | public T ne() {
    method lt (line 211) | public T lt(Object value) {
    method lt (line 215) | public T lt() {
    method lte (line 220) | public T lte(Object value) {
    method lte (line 224) | public T lte() {
    method gte (line 229) | public T gte(Object value) {
    method gte (line 233) | public T gte() {
    method div (line 238) | public T div(Object value) {
    method div (line 242) | public T div() {
    method add (line 247) | public T add(Object value) {
    method add (line 251) | public T add() {
    method sub (line 256) | public T sub(Object value) {
    method sub (line 260) | public T sub() {
    method pow (line 273) | public T pow(Object value) {
    method pow (line 283) | public T pow() {
    method value (line 288) | public T value(Object value) {

FILE: cloudinary-core/src/main/java/com/cloudinary/transformation/Condition.java
  class Condition (line 8) | public class Condition extends BaseExpression<Condition> {
    method Condition (line 10) | public Condition() {
    method Condition (line 21) | public Condition(String conditionStr) {
    method newInstance (line 28) | @Override
    method predicate (line 33) | protected Condition predicate(String name, String operator, Object val...
    method then (line 45) | public Transformation then() {
    method width (line 50) | public Condition width(String operator, Object value) {
    method height (line 54) | public Condition height(String operator, Object value) {
    method aspectRatio (line 58) | public Condition aspectRatio(String operator, Object value) {
    method duration (line 61) | public Condition duration(String operator, Object value) {
    method initialDuration (line 64) | public Condition initialDuration(String operator, Object value) {
    method faceCount (line 68) | public Condition faceCount(String operator, Object value) {
    method pageCount (line 72) | public Condition pageCount(String operator, Object value) {

FILE: cloudinary-core/src/main/java/com/cloudinary/transformation/Expression.java
  class Expression (line 6) | public class Expression extends BaseExpression<Expression> {
    method Expression (line 10) | public Expression(){
    method Expression (line 14) | public Expression(String name){
    method variable (line 19) | public static Expression variable(String name, Object value){
    method faceCount (line 25) | public static Expression faceCount() {
    method newInstance (line 29) | @Override
    method width (line 36) | public static Expression width() {
    method height (line 42) | public static Expression height() {
    method initialWidth (line 48) | public static Expression initialWidth() {
    method initialHeight (line 54) | public static Expression initialHeight() {
    method aspectRatio (line 60) | public static Expression aspectRatio() {
    method initialAspectRatio (line 66) | public static Expression initialAspectRatio() {
    method pageCount (line 72) | public static Expression pageCount() {
    method currentPage (line 78) | public static Expression currentPage() {
    method tags (line 84) | public static Expression tags() {
    method pageX (line 90) | public static Expression pageX() {
    method pageY (line 96) | public static Expression pageY() {

FILE: cloudinary-core/src/main/java/com/cloudinary/transformation/FetchLayer.java
  class FetchLayer (line 5) | public class FetchLayer extends AbstractLayer<FetchLayer> {
    method FetchLayer (line 7) | public FetchLayer() {
    method url (line 11) | public FetchLayer url(String remoteUrl) {
    method type (line 16) | @Override
    method getThis (line 21) | @Override

FILE: cloudinary-core/src/main/java/com/cloudinary/transformation/Layer.java
  class Layer (line 3) | public class Layer extends AbstractLayer<Layer> {
    method getThis (line 4) | @Override

FILE: cloudinary-core/src/main/java/com/cloudinary/transformation/SubtitlesLayer.java
  class SubtitlesLayer (line 3) | public class SubtitlesLayer extends TextLayer {
    method SubtitlesLayer (line 4) | public SubtitlesLayer() {

FILE: cloudinary-core/src/main/java/com/cloudinary/transformation/TextLayer.java
  class TextLayer (line 10) | public class TextLayer extends AbstractLayer<TextLayer> {
    method getThis (line 26) | @Override
    method resourceType (line 31) | public TextLayer resourceType(String resourceType) {
    method type (line 35) | public TextLayer type(String type) {
    method format (line 39) | public TextLayer format(String format) {
    method fontFamily (line 43) | public TextLayer fontFamily(String fontFamily) {
    method fontAntialiasing (line 48) | public TextLayer fontAntialiasing(String fontAntialiasing) {
    method fontHinting (line 53) | public TextLayer fontHinting(String fontHinting) {
    method fontSize (line 59) | public TextLayer fontSize(int fontSize) {
    method fontWeight (line 64) | public TextLayer fontWeight(String fontWeight) {
    method fontStyle (line 69) | public TextLayer fontStyle(String fontStyle) {
    method textDecoration (line 74) | public TextLayer textDecoration(String textDecoration) {
    method textAlign (line 79) | public TextLayer textAlign(String textAlign) {
    method stroke (line 84) | public TextLayer stroke(String stroke) {
    method letterSpacing (line 89) | public TextLayer letterSpacing(String letterSpacing) {
    method letterSpacing (line 94) | public TextLayer letterSpacing(int letterSpacing) {
    method lineSpacing (line 99) | public TextLayer lineSpacing(Integer lineSpacing) {
    method text (line 104) | public TextLayer text(String text) {
    method textStyle (line 128) | public TextLayer textStyle(String textStyleIdentifier) {
    method textStyle (line 139) | public TextLayer textStyle(Expression textStyleIdentifier) {
    method toString (line 144) | @Override
    method textStyleIdentifier (line 169) | protected String textStyleIdentifier() {

FILE: cloudinary-core/src/main/java/com/cloudinary/utils/Analytics.java
  class Analytics (line 8) | public class Analytics {
    method Analytics (line 21) | public Analytics() {
    method Analytics (line 24) | public Analytics(String sdkCode, String sdkVersion, String techVersion...
    method setSDKCode (line 33) | public Analytics setSDKCode(String SDKCode) {
    method setSDKSemver (line 38) | public Analytics setSDKSemver(String SDKSemver) {
    method setTechVersion (line 43) | public Analytics setTechVersion(String techVersion) {
    method setFeatureFlag (line 48) | public Analytics setFeatureFlag(String flag) {
    method toQueryParam (line 57) | public String toQueryParam() {
    method getTechVersion (line 65) | private String getTechVersion() throws Exception {
    method versionArrayToString (line 71) | private String versionArrayToString(String[] versions) throws Exception {
    method versionArrayToOsString (line 78) | private String versionArrayToOsString(String[] versions) throws  Excep...
    method getOsType (line 85) | private String getOsType() {
    method getOsVersion (line 89) | private String getOsVersion() throws Exception {
    method getSDKType (line 93) | private String getSDKType() {
    method getAlgorithmVersion (line 97) | private String getAlgorithmVersion() {
    method getSDKFeatureFlag (line 101) | private String getSDKFeatureFlag() {
    method getSDKVersion (line 105) | private String getSDKVersion() throws Exception {
    method getOsVersionString (line 109) | private String getOsVersionString(String string) throws Exception {
    method getPaddedString (line 121) | private String getPaddedString(String string) throws Exception {
    method reverseVersion (line 148) | private String reverseVersion(String SDKSemver) throws Exception {

FILE: cloudinary-core/src/main/java/com/cloudinary/utils/Base64Coder.java
  class Base64Coder (line 29) | public class Base64Coder {
    method encodeString (line 67) | public static String encodeString(String s) {
    method encodeLines (line 79) | public static String encodeLines(byte[] in) {
    method encodeLines (line 95) | public static String encodeLines(
    method encode (line 121) | public static char[] encode(byte[] in) {
    method encode (line 133) | public static char[] encode(byte[] in, int iLen) {
    method encode (line 147) | public static char[] encode(byte[] in, int iOff, int iLen) {
    method decodeString (line 180) | public static String decodeString(String s) {
    method decodeLines (line 194) | public static byte[] decodeLines(String s) {
    method decode (line 213) | public static byte[] decode(String s) {
    method decode (line 225) | public static byte[] decode(char[] in) {
    method decode (line 241) | public static byte[] decode(char[] in, int iOff, int iLen) {
    method Base64Coder (line 280) | private Base64Coder() {
    method encodeURLSafeString (line 283) | public static String encodeURLSafeString(String s) {
    method encodeURLSafeString (line 287) | public static String encodeURLSafeString(byte[] digest) {

FILE: cloudinary-core/src/main/java/com/cloudinary/utils/Base64Map.java
  class Base64Map (line 6) | public final class Base64Map {
    method Base64Map (line 7) | private Base64Map() {}

FILE: cloudinary-core/src/main/java/com/cloudinary/utils/HtmlEscape.java
  class HtmlEscape (line 19) | public final class HtmlEscape {
    method HtmlEscape (line 20) | private HtmlEscape() {}
    method escapeTextArea (line 30) | public static String escapeTextArea(String original) {
    method escape (line 40) | public static String escape(String original) {
    method escapeTags (line 44) | public static String escapeTags(String original) {
    method escapeBr (line 71) | public static String escapeBr(String original) {
    method escapeSpecial (line 93) | public static String escapeSpecial(String original) {

FILE: cloudinary-core/src/main/java/com/cloudinary/utils/ObjectUtils.java
  class ObjectUtils (line 14) | public final class ObjectUtils {
    method ObjectUtils (line 15) | private ObjectUtils() {}
    method toISO8601 (line 22) | public static String toISO8601(Date date){
    method fromISO8601 (line 27) | public static Date fromISO8601(String date) throws ParseException {
    method getDateFormat (line 32) | private static DateFormat getDateFormat() {
    method asString (line 38) | public static String asString(Object value) {
    method asString (line 46) | public static String asString(Object value, String defaultValue) {
    method serialize (line 54) | public static String serialize(Object object) throws IOException {
    method deserialize (line 65) | public static Object deserialize(String base64SerializedString) throws...
    method asArray (line 70) | @SuppressWarnings({"rawtypes", "unchecked"})
    method asBoolean (line 91) | public static Boolean asBoolean(Object value, Boolean defaultValue) {
    method asBoolean (line 97) | public static Boolean asBoolean(Object value) {
    method asFloat (line 105) | public static Float asFloat(Object value) {
    method asMap (line 115) | @SuppressWarnings({"rawtypes", "unchecked"})
    method emptyMap (line 126) | @SuppressWarnings("rawtypes")
    method encodeMap (line 131) | @SuppressWarnings({"unchecked", "rawtypes"})
    method only (line 147) | public static Map<String, ? extends Object> only(Map<String, ? extends...
    method toMap (line 157) | @SuppressWarnings("rawtypes")
    method toJSON (line 169) | public static JSONObject toJSON(Map<String, ? extends Object> map) thr...
    method fromJson (line 179) | private static Object fromJson(Object json) throws JSONException {
    method toList (line 191) | @SuppressWarnings({"rawtypes", "unchecked"})
    method asInteger (line 200) | public static Integer asInteger(Object value, Integer defaultValue) {
    method asLong (line 210) | public static Long asLong(Object value, Long defaultValue) {
    method toUsageApiDateFormat (line 220) | public static String toUsageApiDateFormat(Date date){
    method toISO8601DateOnly (line 224) | public static String toISO8601DateOnly(Date date) {
    method fromISO8601DateOnly (line 228) | public static Date fromISO8601DateOnly(String string) throws ParseExce...

FILE: cloudinary-core/src/main/java/com/cloudinary/utils/Rectangle.java
  class Rectangle (line 5) | public class Rectangle implements Serializable{
    method Rectangle (line 12) | public Rectangle(int x, int y, int width, int height) {

FILE: cloudinary-core/src/main/java/com/cloudinary/utils/StringUtils.java
  class StringUtils (line 11) | public final class StringUtils {
    method StringUtils (line 12) | private StringUtils() {}
    method join (line 23) | public static String join(List<String> list, String separator) {
    method join (line 38) | public static String join(Object[] array, String separator) {
    method join (line 52) | public static String join(Collection<String> collection, String separa...
    method join (line 68) | public static String join(final Object[] array, String separator, fina...
    method encodeHexString (line 102) | public static String encodeHexString(byte[] bytes) {
    method hexStringToByteArray (line 118) | public static byte[] hexStringToByteArray(String s) {
    method escapeHtml (line 140) | public static String escapeHtml(String input) {
    method isNotBlank (line 150) | public static boolean isNotBlank(Object input) {
    method isNotBlank (line 161) | public static boolean isNotBlank(String input) {
    method isEmpty (line 171) | public static boolean isEmpty(String input) {
    method isBlank (line 182) | public static boolean isBlank(String input) {
    method read (line 202) | public static String read(InputStream in) throws IOException {
    method isRemoteUrl (line 212) | public static boolean isRemoteUrl(String file) {
    method urlEncode (line 224) | public static String urlEncode(String url, Pattern unsafe, Charset cha...
    method mergeToSingleUnderscore (line 253) | public static String mergeToSingleUnderscore(String s) {
    method isVariable (line 280) | public static boolean isVariable(String s) {
    method replaceIfFirstChar (line 306) | public static String replaceIfFirstChar(String s, char c, String repla...
    method isHttpUrl (line 315) | public static boolean isHttpUrl(String s) {
    method removeStartingChars (line 326) | public static String removeStartingChars(String s, char c) {
    method startWithVersionString (line 348) | public static boolean startWithVersionString(String publicId){
    method mergeSlashesInUrl (line 360) | public static String mergeSlashesInUrl(String url) {
    method emptyIfNull (line 398) | public static String emptyIfNull(String str) {
    method reverseStringArray (line 408) | static String[] reverseStringArray(String[] strings) {
    method padStart (line 421) | public static String padStart(String inputString, int length, char pad...
    method getAllSubStringWithSize (line 441) | public static List<String> getAllSubStringWithSize(String text, int n) {

FILE: cloudinary-core/src/main/java/org/cloudinary/json/JSONArray.java
  class JSONArray (line 81) | public class JSONArray implements Serializable {
    method JSONArray (line 91) | public JSONArray() {
    method JSONArray (line 101) | public JSONArray(JSONTokener x) throws JSONException {
    method JSONArray (line 140) | public JSONArray(String source) throws JSONException {
    method JSONArray (line 149) | public JSONArray(Collection<Object> collection) {
    method JSONArray (line 164) | public JSONArray(Object array) throws JSONException {
    method get (line 183) | public Object get(int index) throws JSONException {
    method getBoolean (line 200) | public boolean getBoolean(int index) throws JSONException {
    method getDouble (line 218) | public double getDouble(int index) throws JSONException {
    method getInt (line 234) | public int getInt(int index) throws JSONException {
    method getJSONArray (line 251) | public JSONArray getJSONArray(int index) throws JSONException {
    method getJSONObject (line 267) | public JSONObject getJSONObject(int index) throws JSONException {
    method getLong (line 283) | public long getLong(int index) throws JSONException {
    method getString (line 299) | public String getString(int index) throws JSONException {
    method isNull (line 313) | public boolean isNull(int index) {
    method join (line 326) | public String join(String separator) throws JSONException {
    method length (line 344) | public int length() {
    method opt (line 354) | public Object opt(int index) {
    method optBoolean (line 366) | public boolean optBoolean(int index) {
    method optBoolean (line 379) | public boolean optBoolean(int index, boolean defaultValue) {
    method optDouble (line 395) | public double optDouble(int index) {
    method optDouble (line 408) | public double optDouble(int index, double defaultValue) {
    method optInt (line 424) | public int optInt(int index) {
    method optInt (line 437) | public int optInt(int index, int defaultValue) {
    method optJSONArray (line 452) | public JSONArray optJSONArray(int index) {
    method optJSONObject (line 465) | public JSONObject optJSONObject(int index) {
    method optLong (line 478) | public long optLong(int index) {
    method optLong (line 491) | public long optLong(int index, long defaultValue) {
    method optString (line 507) | public String optString(int index) {
    method optString (line 519) | public String optString(int index, String defaultValue) {
    method put (line 530) | public JSONArray put(boolean value) {
    method put (line 542) | public JSONArray put(Collection<Object> value) {
    method put (line 554) | public JSONArray put(double value) throws JSONException {
    method put (line 567) | public JSONArray put(int value) {
    method put (line 578) | public JSONArray put(long value) {
    method put (line 590) | public JSONArray put(Map<String, Object> value) {
    method put (line 603) | public JSONArray put(Object value) {
    method put (line 618) | public JSONArray put(int index, boolean value) throws JSONException {
    method put (line 632) | public JSONArray put(int index, Collection<Object> value) throws JSONE...
    method put (line 647) | public JSONArray put(int index, double value) throws JSONException {
    method put (line 662) | public JSONArray put(int index, int value) throws JSONException {
    method put (line 677) | public JSONArray put(int index, long value) throws JSONException {
    method put (line 692) | public JSONArray put(int index, Map<String, Object> value) throws JSON...
    method put (line 710) | public JSONArray put(int index, Object value) throws JSONException {
    method remove (line 733) | public Object remove(int index) {
    method similar (line 744) | public boolean similar(Object other) {
    method toJSONObject (line 780) | public JSONObject toJSONObject(JSONArray names) throws JSONException {
    method toString (line 802) | public String toString() {
    method toString (line 821) | public String toString(int indentFactor) throws JSONException {
    method write (line 837) | public Writer write(Writer writer) throws JSONException {
    method write (line 852) | Writer write(Writer writer, int indentFactor, int indent) throws JSONE...
    method toList (line 886) | @SuppressWarnings("unchecked")

FILE: cloudinary-core/src/main/java/org/cloudinary/json/JSONException.java
  class JSONException (line 9) | public class JSONException extends RuntimeException {
    method JSONException (line 18) | public JSONException(String message) {
    method JSONException (line 27) | public JSONException(Throwable cause) {
    method getCause (line 39) | @Override

FILE: cloudinary-core/src/main/java/org/cloudinary/json/JSONObject.java
  class JSONObject (line 97) | public class JSONObject implements Serializable{
    class Null (line 103) | private static final class Null {
      method clone (line 111) | @Override
      method equals (line 123) | @Override
      method toString (line 133) | public String toString() {
    method JSONObject (line 154) | public JSONObject() {
    method JSONObject (line 169) | public JSONObject(JSONObject jo, String[] names) {
    method JSONObject (line 186) | public JSONObject(JSONTokener x) throws JSONException {
    method JSONObject (line 239) | public JSONObject(Map<String, Object> map) {
    method JSONObject (line 273) | public JSONObject(Object bean) {
    method JSONObject (line 290) | @SuppressWarnings("rawtypes")
    method JSONObject (line 313) | public JSONObject(String source) throws JSONException {
    method JSONObject (line 324) | public JSONObject(String baseName, Locale locale) throws JSONException {
    method accumulate (line 373) | public JSONObject accumulate(String key, Object value) throws JSONExce...
    method append (line 400) | public JSONObject append(String key, Object value) throws JSONException {
    method doubleToString (line 421) | public static String doubleToString(double d) {
    method get (line 448) | public Object get(String key) throws JSONException {
    method getBoolean (line 467) | public boolean getBoolean(String key) throws JSONException {
    method getDouble (line 490) | public double getDouble(String key) throws JSONException {
    method getInt (line 509) | public int getInt(String key) throws JSONException {
    method getJSONArray (line 527) | public JSONArray getJSONArray(String key) throws JSONException {
    method getJSONObject (line 543) | public JSONObject getJSONObject(String key) throws JSONException {
    method getLong (line 560) | public long getLong(String key) throws JSONException {
    method getNames (line 576) | public static String[] getNames(JSONObject jo) {
    method getNames (line 596) | @SuppressWarnings("rawtypes")
    method getString (line 621) | public String getString(String key) throws JSONException {
    method has (line 635) | public boolean has(String key) {
    method increment (line 649) | public JSONObject increment(String key) throws JSONException {
    method isNull (line 675) | public boolean isNull(String key) {
    method keys (line 684) | public Iterator<String> keys() {
    method keySet (line 693) | public Set<String> keySet() {
    method length (line 702) | public int length() {
    method names (line 713) | public JSONArray names() {
    method numberToString (line 729) | public static String numberToString(Number number) throws JSONException {
    method opt (line 756) | public Object opt(String key) {
    method optBoolean (line 767) | public boolean optBoolean(String key) {
    method optBoolean (line 780) | public boolean optBoolean(String key, boolean defaultValue) {
    method optDouble (line 796) | public double optDouble(String key) {
    method optDouble (line 809) | public double optDouble(String key, double defaultValue) {
    method optInt (line 825) | public int optInt(String key) {
    method optInt (line 838) | public int optInt(String key, int defaultValue) {
    method optJSONArray (line 853) | public JSONArray optJSONArray(String key) {
    method optJSONObject (line 865) | public JSONObject optJSONObject(String key) {
    method optLong (line 878) | public long optLong(String key) {
    method optLong (line 891) | public long optLong(String key, long defaultValue) {
    method optString (line 907) | public String optString(String key) {
    method optString (line 919) | public String optString(String key, String defaultValue) {
    method populateMap (line 924) | @SuppressWarnings("rawtypes")
    method put (line 979) | public JSONObject put(String key, boolean value) throws JSONException {
    method put (line 993) | public JSONObject put(String key, Collection<Object> value) throws JSO...
    method put (line 1006) | public JSONObject put(String key, double value) throws JSONException {
    method put (line 1019) | public JSONObject put(String key, int value) throws JSONException {
    method put (line 1032) | public JSONObject put(String key, long value) throws JSONException {
    method put (line 1046) | public JSONObject put(String key, Map<String, Object> value) throws JS...
    method put (line 1062) | public JSONObject put(String key, Object value) throws JSONException {
    method putOnce (line 1085) | public JSONObject putOnce(String key, Object value) throws JSONExcepti...
    method putOpt (line 1106) | public JSONObject putOpt(String key, Object value) throws JSONException {
    method quote (line 1122) | public static String quote(String string) {
    method quote (line 1134) | public static Writer quote(String string, Writer w) throws IOException {
    method remove (line 1200) | public Object remove(String key) {
    method similar (line 1212) | public boolean similar(Object other) {
    method stringToValue (line 1251) | public static Object stringToValue(String string) {
    method testValidity (line 1302) | public static void testValidity(Object o) throws JSONException {
    method toJSONArray (line 1327) | public JSONArray toJSONArray(JSONArray names) throws JSONException {
    method toString (line 1350) | public String toString() {
    method toString (line 1370) | public String toString(int indentFactor) throws JSONException {
    method valueToString (line 1399) | @SuppressWarnings("unchecked")
    method wrap (line 1446) | @SuppressWarnings("unchecked")
    method write (line 1494) | public Writer write(Writer writer) throws JSONException {
    method writeValue (line 1498) | @SuppressWarnings("unchecked")
    method indent (line 1532) | static final void indent(Writer writer, int indent) throws IOException {
    method write (line 1547) | Writer write(Writer writer, int indentFactor, int indent)

FILE: cloudinary-core/src/main/java/org/cloudinary/json/JSONString.java
  type JSONString (line 11) | public interface JSONString {
    method toJSONString (line 18) | public String toJSONString();

FILE: cloudinary-core/src/main/java/org/cloudinary/json/JSONTokener.java
  class JSONTokener (line 42) | public class JSONTokener {
    method JSONTokener (line 58) | public JSONTokener(Reader reader) {
    method JSONTokener (line 76) | public JSONTokener(InputStream inputStream) throws JSONException {
    method JSONTokener (line 86) | public JSONTokener(String s) {
    method back (line 96) | public void back() throws JSONException {
    method dehexchar (line 114) | public static int dehexchar(char c) {
    method end (line 127) | public boolean end() {
    method more (line 138) | public boolean more() throws JSONException {
    method next (line 153) | public char next() throws JSONException {
    method next (line 193) | public char next(char c) throws JSONException {
    method next (line 211) | public String next(int n) throws JSONException {
    method nextClean (line 236) | public char nextClean() throws JSONException {
    method nextString (line 258) | public String nextString(char quote) throws JSONException {
    method nextTo (line 316) | public String nextTo(char delimiter) throws JSONException {
    method nextTo (line 338) | public String nextTo(String delimiters) throws JSONException {
    method nextValue (line 362) | public Object nextValue() throws JSONException {
    method skipTo (line 410) | public char skipTo(char to) throws JSONException {
    method syntaxError (line 441) | public JSONException syntaxError(String message) {
    method toString (line 451) | public String toString() {

FILE: cloudinary-core/src/test/java/com/cloudinary/AuthTokenTest.java
  class AuthTokenTest (line 22) | public class AuthTokenTest {
    method setUp (line 30) | @Before
    method generateWithStartAndDuration (line 41) | @Test
    method generateWithDuration (line 48) | @Test
    method testMustProvideExpirationOrDuration (line 64) | @Test(expected = IllegalArgumentException.class)
    method testAuthenticatedUrl (line 69) | @Test
    method testConfiguration (line 100) | @Test
    method testTokenGeneration (line 106) | @Test
    method testUrlInTag (line 117) | @Test
    method testIgnoreUrlIfAclIsProvided (line 125) | @Test
    method testMultiplePatternsInAcl (line 135) | @Test
    method testPublicAclInitializationFromMap (line 142) | @Test
    method testMissingAclAndUrlShouldThrow (line 153) | @Test(expected = IllegalArgumentException.class)
    method testMissingUrlNotMissingAclShouldNotThrow (line 158) | @Test

FILE: cloudinary-core/src/test/java/com/cloudinary/TransformationTest.java
  class TransformationTest (line 25) | @SuppressWarnings("unchecked")
    method setUp (line 29) | @Before
    method tearDown (line 34) | @After
    method withLiteral (line 39) | @Test
    method literalWithSpaces (line 54) | @Test
    method endIf (line 64) | @Test
    method ifElse (line 77) | @Test
    method testDuration (line 97) | @Test
    method chainedConditions (line 108) | @Test
    method shouldSupportAndTranslateOperators (line 125) | @Test
    method endIf2 (line 152) | @Test
    method testArrayShouldDefineASetOfVariables (line 163) | @Test
    method testShouldSortDefinedVariable (line 174) | @Test
    method testShouldPlaceDefinedVariablesBeforeOrdered (line 180) | @Test
    method testVariable (line 189) | @Test
    method testShouldSupportTextValues (line 202) | @Test
    method testSupportStringInterpolation (line 210) | @Test
    method testShouldSupportPowOperator (line 220) | @Test
    method testShouldNotChangeVariableNamesWhenTheyNamedAfterKeyword (line 228) | @Test
    method testRadiusTwoCornersAsValues (line 238) | @Test
    method testRadiusTwoCornersAsExpressions (line 246) | @Test
    method testRadiusThreeCorners (line 254) | @Test
    method testRadiusFourCorners (line 262) | @Test
    method testRadiusArray1 (line 270) | @Test
    method testRadiusArray2 (line 278) | @Test
    method testUserVariableNamesContainingPredefinedNamesAreNotAffected (line 286) | @Test
    method testContextMetadataToUserVariables (line 298) | @Test
    method testFormatInTransformation (line 310) | @Test
    method testVerifyNormalizationShouldNormalize (line 319) | @Parameters({ "angle",
    method testVerifyNormalizationShouldNotNormalize (line 338) | @Parameters({
    method testSupportStartOffset (line 364) | @Test
    method testSupportEndOffset (line 373) | @Test

FILE: cloudinary-core/src/test/java/com/cloudinary/UtilTest.java
  class UtilTest (line 18) | public class UtilTest {
    method encodeContext (line 25) | @Test
    method testAccessControlRule (line 33) | @Test
    method testMergeToSingleUnderscore (line 61) | @Test
    method testIsVariable (line 72) | @Test
    method testReplaceIfFirstChar (line 92) | @Test
    method testIsHttpUrl (line 109) | @Test
    method testMergeSlashes (line 121) | @Test
    method testStartWithVersionString (line 131) | @Test
    method testRemoveStartingChars (line 155) | @Test

FILE: cloudinary-core/src/test/java/com/cloudinary/analytics/AnalyticsTest.java
  class AnalyticsTest (line 11) | public class AnalyticsTest {
    method setUp (line 20) | @Before
    method testEncodeVersion (line 26) | @Test
    method testToQueryParam (line 52) | @Test
    method testUrlWithAnalytics (line 63) | @Test
    method testUrlWithNoAnalytics (line 71) | @Test
    method testUrlWithNoAnalyticsDefined (line 78) | @Test
    method testUrlWithNoAnalyticsNull (line 85) | @Test
    method testUrlWithNoAnalyticsNullAndTrue (line 92) | @Test
    method testMiscAnalyticsObject (line 101) | @Test
    method testErrorAnalytics (line 109) | @Test
    method testUrlNoAnalyticsWithQueryParams (line 117) | @Test
    method testFeatureFlag (line 132) | @Test
    method tearDown (line 140) | @After

FILE: cloudinary-core/src/test/java/com/cloudinary/api/signing/ApiResponseSignatureVerifierTest.java
  class ApiResponseSignatureVerifierTest (line 9) | public class ApiResponseSignatureVerifierTest {
    method testVerifySignature (line 10) | @Test
    method testVerifySignatureFail (line 19) | @Test
    method testVerifySignatureSHA256 (line 28) | @Test

FILE: cloudinary-core/src/test/java/com/cloudinary/api/signing/NotificationRequestSignatureVerifierTest.java
  class NotificationRequestSignatureVerifierTest (line 9) | public class NotificationRequestSignatureVerifierTest {
    method testVerifySignature (line 10) | @Test
    method testVerifySignatureFailWhenSignatureDoesntMatch (line 22) | @Test
    method testVerifySignatureFailWhenTooOld (line 34) | @Test
    method testVerifySignaturePassWhenStillValid (line 47) | @Test
    method testVerifySignatureFailWhenStillValidButSignatureDoesntMatch (line 60) | @Test
    method testVerifySignatureSHA256 (line 73) | @Test

FILE: cloudinary-core/src/test/java/com/cloudinary/test/CloudinaryTest.java
  class CloudinaryTest (line 35) | @RunWith(JUnitParamsRunner.class)
    method setUp (line 45) | @Before
    method testUrlSuffixWithDotOrSlash (line 51) | @Test
    method testCloudName (line 84) | @Test
    method testCloudNameOptions (line 91) | @Test
    method testSecureDistribution (line 98) | @Test
    method testTextLayerStyleIdentifierVariables (line 105) | @Test
    method testSecureDistributionOverwrite (line 129) | @Test
    method testSecureDistibution (line 136) | @Test
    method testSecureAkamai (line 144) | @Test
    method testSecureNonAkamai (line 154) | @Test
    method testHttpPrivateCdn (line 165) | @Test
    method testFormat (line 173) | @Test
    method testType (line 180) | @Test
    method testResourceType (line 187) | @Test
    method testIgnoreHttp (line 194) | @Test
    method testFetch (line 205) | @Test
    method testCname (line 212) | @Test
    method testCnameSubdomain (line 219) | @Test
    method testDisallowUrlSuffixInNonUploadTypes (line 226) | @Test(expected = IllegalArgumentException.class)
    method testDisallowUrlSuffixWithSlash (line 232) | @Test(expected = IllegalArgumentException.class)
    method testDisallowUrlSuffixWithDot (line 237) | @Test(expected = IllegalArgumentException.class)
    method testSupportUrlSuffixForPrivateCdn (line 242) | @Test
    method testPutFormatAfterUrlSuffix (line 252) | @Test
    method testNotSignTheUrlSuffix (line 258) | @Test
    method testSignatureLength (line 280) | @Test
    method testSupportUrlSuffixForRawUploads (line 289) | @Test
    method testSupportUrlSuffixForVideoUploads (line 295) | @Test
    method testSupportUrlSuffixForAuthenticatedImages (line 301) | @Test
    method testSupportUrlSuffixForPrivateImages (line 307) | @Test
    method testSupportUseRootPathForPrivateCdn (line 313) | @Test
    method testSupportUseRootPathTogetherWithUrlSuffixForPrivateCdn (line 322) | @Test
    method testDisllowUseRootPathIfNotImageUploadForFacebook (line 330) | @Test(expected = IllegalArgumentException.class)
    method testDisllowUseRootPathIfNotImageUploadForRaw (line 335) | @Test(expected = IllegalArgumentException.class)
    method testCrop (line 340) | @Test
    method testVariousOptions (line 352) | @Test
    method testQuality (line 360) | @Test
    method parametersForTestQuality (line 368) | @SuppressWarnings("unused")
    method testAutoGravity (line 378) | @Test
    method parametersForTestAutoGravity (line 387) | @SuppressWarnings("unused")
    method testTransformationSimple (line 400) | @Test
    method testTransformationArray (line 408) | @Test
    method testNamedTransformationWithSpaces (line 416) | @Test
    method testBaseTransformations (line 424) | @Test
    method testBaseTransformationArray (line 433) | @Test
    method testNoEmptyTransformation (line 442) | @Test
    method testHttpEscape (line 450) | @Test
    method testBackground (line 457) | @Test
    method testDefaultImage (line 468) | @Test
    method testAngle (line 476) | @Test
    method testFetchFormat (line 487) | @Test
    method testUseFetchFormat (line 494) | @Test
    method testEffect (line 501) | @Test
    method testEffectWithParam (line 509) | @Test
    method testArtisticFilter (line 517) | @Test
    method testDensity (line 524) | @Test
    method testPage (line 532) | @Test
    method testBorder (line 540) | @Test
    method testFlags (line 554) | @Test
    method testOpacity (line 565) | @Test
    method testImageTag (line 577) | @SuppressWarnings("unchecked")
    method testClientHints (line 603) | @Test
    method testFolders (line 624) | @Test
    method testFoldersWithExcludeVersion (line 633) | @Test
    method testFoldersWithVersion (line 664) | @Test
    method testShorten (line 671) | @Test
    method testPrivateDownload (line 678) | @SuppressWarnings("unchecked")
    method testZipDownload (line 692) | @SuppressWarnings("unchecked")
    method testDownloadSprite (line 703) | @Test
    method testDownloadMulti (line 727) | @Test
    method testDownloadFolderShouldReturnURLWithResourceTypeAllByDefault (line 754) | @Test
    method testDownloadFolderShouldAllowToOverrideResourceType (line 760) | @Test
    method testDownloadFolderShouldPutFolderPathAsPrefixes (line 766) | @Test
    method testDownloadFolderShouldIncludeSpecifiedTargetFormat (line 772) | @Test
    method testDownloadFolderShouldNotIncludeTargetFormatIfNotSpecified (line 778) | @Test
    method testSpriteCss (line 784) | @Test
    method testEscapePublicId (line 792) | @SuppressWarnings("unchecked")
    method testSignedUrl (line 803) | @Test
    method testSignedUrlSHA256 (line 820) | @Test
    method testResponsiveWidth (line 828) | @Test
    method testShouldSupportAutoWidth (line 843) | @Parameters({
    method testEagerWithStreamingProfile (line 857) | @Test
    method testEagerWithChaining (line 863) | @Test
    method testShouldSupportIhIw (line 869) | @Test
    method testVideoCodec (line 875) | @Test
    method testVideoCodecBFrameTrue (line 889) | @Test
    method testVideoCodecBFrameFalse (line 898) | @Test
    method testAudioCodec (line 907) | @Test
    method testBitRate (line 914) | @Test
    method testAudioFrequency (line 930) | @Test
    method testVideoSampling (line 942) | @Test
    method testStartOffset (line 958) | @Test
    method testDuration (line 977) | @Test
    method testOffset (line 993) | @Test
    method testZoom (line 1017) | @Test
    method testUtils (line 1027) | @Test
    method testVideoTag (line 1033) | @Test
    method testVideoTagWithAttributes (line 1046) | @Test
    method testVideoTagWithTransformation (line 1064) | @Test
    method testVideoTagWithFallback (line 1110) | @Test
    method testVideoTagWithSourceTypes (line 1127) | @Test
    method testVideoTagWithSourceTransformation (line 1138) | @Test
    method testVideoTagWithPoster (line 1165) | @Test
    method videoTagWithAuthTokenTest (line 1207) | @Test
    method testAspectRatio (line 1221) | @Test
    method testOverlayOptions (line 1234) | @Test
    method testBackwardCampatibleOverlayOptions (line 1280) | @Test
    method testOverlayError1 (line 1312) | @Test(expected = IllegalArgumentException.class)
    method testOverlayError2 (line 1318) | @Test(expected = IllegalArgumentException.class)
    method testResponsiveBreakpointsToJson (line 1324) | @Test
    method testFps (line 1342) | @Test
    method testKeyframeInterval (line 1362) | @Test
    method testCustomFunction (line 1373) | @Test
    method testCustomPreFunction (line 1380) | @Test
    method getUrlParameters (line 1387) | public static Map<String, String> getUrlParameters(URI uri) throws Uns...
    method testUrlCloneConfig (line 1401) | @Test
    method testConfiguration (line 1408) | @Test
    method testCloudinaryUrlValidScheme (line 1420) | @Test
    method testCloudinaryUrlInvalidScheme (line 1426) | @Test(expected = IllegalArgumentException.class)
    method testCloudinaryUrlEmptyScheme (line 1432) | @Test(expected = IllegalArgumentException.class)
    method testApiSignRequestSHA1 (line 1438) | @Test
    method testApiSignRequestSHA256 (line 1445) | @Test
    method testDownloadBackedupAsset (line 1452) | @Test
    method testRegisterUploaderStrategy (line 1467) | @Test
    method testRegisterApiStrategy (line 1474) | @Test
    method assertFieldsEqual (line 1481) | private void assertFieldsEqual(Object a, Object b) throws IllegalAcces...
    method randomizeFields (line 1489) | private void randomizeFields(Object instance) throws IllegalAccessExce...
    method setRandomValue (line 1497) | private void setRandomValue(Random rand, Field field, Object instance)...
    method randomEnum (line 1529) | private <T extends Enum<?>> T randomEnum(Class<T> clazz, Random random) {

FILE: cloudinary-core/src/test/java/com/cloudinary/transformation/ExpressionTest.java
  class ExpressionTest (line 8) | public class ExpressionTest {
    method normalize_null_null (line 10) | @Test
    method normalize_number_number (line 16) | @Test
    method normalize_emptyString_emptyString (line 22) | @Test
    method normalize_singleSpace_underscore (line 28) | @Test
    method normalize_blankString_underscore (line 34) | @Test
    method normalize_underscore_underscore (line 40) | @Test
    method normalize_underscores_underscore (line 46) | @Test
    method normalize_underscoresAndSpaces_underscore (line 52) | @Test
    method normalize_arbitraryText_isNotAffected (line 58) | @Test
    method normalize_doubleAmpersand_replacedWithAndOperator (line 64) | @Test
    method normalize_doubleAmpersandWithNoSpaceAtEnd_isNotAffected (line 70) | @Test
    method normalize_width_recognizedAsVariableAndReplacedWithW (line 76) | @Test
    method normalize_initialAspectRatio_recognizedAsVariableAndReplacedWithIar (line 82) | @Test
    method normalize_dollarWidth_recognizedAsUserVariableAndNotAffected (line 88) | @Test
    method normalize_dollarInitialAspectRatio_recognizedAsUserVariableAndAsVariableReplacedWithAr (line 94) | @Test
    method normalize_dollarMyWidth_recognizedAsUserVariableAndNotAffected (line 100) | @Test
    method normalize_dollarWidthWidth_recognizedAsUserVariableAndNotAffected (line 106) | @Test
    method normalize_dollarUnderscoreWidth_recognizedAsUserVariableAndNotAffected (line 112) | @Test
    method normalize_dollarUnderscoreX2Width_recognizedAsUserVariableAndNotAffected (line 118) | @Test
    method normalize_dollarX2Width_recognizedAsUserVariableAndNotAffected (line 124) | @Test
    method normalize_doesntReplaceVariable_1 (line 130) | @Test
    method normalize_doesntReplaceVariable_2 (line 136) | @Test
    method normalize_doesntReplaceVariable_3 (line 142) | @Test
    method normalize_doesntReplaceVariable_4 (line 148) | @Test
    method normalize_doesntReplaceVariable_5 (line 154) | @Test
    method normalize_doesntReplaceVariable_6 (line 160) | @Test
    method normalize_doesntReplaceVariable_7 (line 166) | @Test
    method normalize_doesntReplaceVariable_8 (line 172) | @Test
    method normalize_duration (line 178) | @Test
    method normalize_previewDuration (line 184) | @Test

FILE: cloudinary-core/src/test/java/com/cloudinary/transformation/LayerTest.java
  class LayerTest (line 14) | public class LayerTest {
    method setUp (line 20) | @Before
    method tearDown (line 25) | @After
    method testOverlay (line 30) | @Test
    method testUnderlay (line 48) | @Test
    method testPublicIdWithDoubleUnderscoresInOverlay (line 61) | @Test
    method testLayerOptions (line 68) | @Test
    method testOverlayError1 (line 101) | @Test(expected = IllegalArgumentException.class)
    method testOverlayError2 (line 107) | @Test(expected = IllegalArgumentException.class)
    method testResourceType (line 113) | @Test
    method testType (line 118) | @Test
    method testPublicId (line 123) | @Test
    method testFormat (line 128) | @Test
    method testToString (line 133) | @Test
    method testFormattedPublicId (line 138) | @Test

FILE: cloudinary-http5/src/main/java/com/cloudinary/http5/ApiStrategy.java
  class ApiStrategy (line 38) | public class ApiStrategy extends AbstractApiStrategy {
    method init (line 44) | public void init(Api api) {
    method buildRequestConfig (line 62) | public RequestConfig buildRequestConfig() {
    method callApi (line 80) | @SuppressWarnings({"rawtypes", "unchecked"})
    method getApiResponse (line 89) | private ApiResponse getApiResponse(HttpUriRequestBase request) throws ...
    method callAccountApi (line 137) | @Override
    method prepareRequest (line 150) | private HttpUriRequestBase prepareRequest(Api.HttpMethod method, Strin...
    method setEntity (line 182) | private void setEntity(HttpUriRequestBase request, Map<String, ?> para...

FILE: cloudinary-http5/src/main/java/com/cloudinary/http5/ApiUtils.java
  class ApiUtils (line 13) | public final class ApiUtils {
    method ApiUtils (line 14) | private ApiUtils() {}
    method setTimeouts (line 16) | public static void setTimeouts(HttpUriRequestBase request, Map<String,...
    method prepareParams (line 45) | public static List<NameValuePair> prepareParams(Map<String, ?> params) {

FILE: cloudinary-http5/src/main/java/com/cloudinary/http5/UploaderStrategy.java
  class UploaderStrategy (line 33) | public class UploaderStrategy extends AbstractUploaderStrategy {
    method init (line 39) | @Override
    method buildRequestConfig (line 58) | public RequestConfig buildRequestConfig() {
    method callApi (line 76) | @SuppressWarnings({"rawtypes", "unchecked"})
    method prepareRequest (line 116) | private HttpUriRequestBase prepareRequest(String apiUrl, Map<String, O...
    method addFilePart (line 153) | private void addFilePart(MultipartEntityBuilder multipartBuilder, Obje...

FILE: cloudinary-http5/src/main/java/com/cloudinary/http5/api/Response.java
  class Response (line 17) | public class Response extends HashMap implements ApiResponse {
    method Response (line 21) | @SuppressWarnings("unchecked")
    method getRawHttpResponse (line 27) | public HttpResponse getRawHttpResponse() {
    method rateLimits (line 36) | public Map<String, RateLimit> rateLimits() throws ParseException {
    method apiRateLimit (line 60) | public RateLimit apiRateLimit() throws ParseException {

FILE: cloudinary-http5/src/test/java/com/cloudinary/test/AccountApiTest.java
  class AccountApiTest (line 3) | public class AccountApiTest extends AbstractAccountApiTest {

FILE: cloudinary-http5/src/test/java/com/cloudinary/test/ApiTest.java
  class ApiTest (line 19) | public class ApiTest extends AbstractApiTest {
    method testBuildRequestConfig_withProxyAndTimeout (line 21) | @Test
    method testBuildRequestConfig_withoutProxy (line 39) | @Test
    method testConnectTimeoutParameter (line 51) | @Category(TimeoutTest.class)
    method testTimeoutParameter (line 67) | @Category(TimeoutTest.class)
    method testUploaderTimeoutParameter (line 83) | @Category(TimeoutTest.class)

FILE: cloudinary-http5/src/test/java/com/cloudinary/test/ContextTest.java
  class ContextTest (line 3) | public class ContextTest extends AbstractContextTest {

FILE: cloudinary-http5/src/test/java/com/cloudinary/test/FoldersApiTest.java
  class FoldersApiTest (line 3) | public class FoldersApiTest extends AbstractFoldersApiTest {

FILE: cloudinary-http5/src/test/java/com/cloudinary/test/SearchTest.java
  class SearchTest (line 3) | public class SearchTest extends AbstractSearchTest {

FILE: cloudinary-http5/src/test/java/com/cloudinary/test/StreamingProfilesApiTest.java
  class StreamingProfilesApiTest (line 6) | public class StreamingProfilesApiTest extends AbstractStreamingProfilesA...

FILE: cloudinary-http5/src/test/java/com/cloudinary/test/StructuredMetadataTest.java
  class StructuredMetadataTest (line 3) | public class StructuredMetadataTest extends AbstractStructuredMetadataTe...

FILE: cloudinary-http5/src/test/java/com/cloudinary/test/UploaderTest.java
  class UploaderTest (line 3) | public class UploaderTest extends AbstractUploaderTest {

FILE: cloudinary-taglib/src/main/java/com/cloudinary/Singleton.java
  class Singleton (line 13) | public final class Singleton {
    method Singleton (line 14) | private Singleton() {}
    method registerCloudinary (line 18) | public static void registerCloudinary(Cloudinary cloudinary) {
    method deregisterCloudinary (line 22) | public static void deregisterCloudinary() {
    class DefaultCloudinaryHolder (line 26) | private static class DefaultCloudinaryHolder {
    method getCloudinary (line 30) | public static Cloudinary getCloudinary() {

FILE: cloudinary-taglib/src/main/java/com/cloudinary/SingletonManager.java
  class SingletonManager (line 3) | public class SingletonManager {
    method setCloudinary (line 7) | public void setCloudinary(Cloudinary cloudinary) {
    method init (line 11) | public void init() {
    method destroy (line 15) | public void destroy() {

FILE: cloudinary-taglib/src/main/java/com/cloudinary/taglib/CloudinaryImageTag.java
  class CloudinaryImageTag (line 34) | public class CloudinaryImageTag extends CloudinaryUrl {
    method prepareAttributes (line 39) | protected Map<String, String> prepareAttributes() {
    method doTag (line 50) | public void doTag() throws JspException, IOException {
    method setId (line 56) | public void setId(String id) {
    method getId (line 60) | public String getId() {
    method getExtraClasses (line 64) | public String getExtraClasses() {
    method setExtraClasses (line 68) | public void setExtraClasses(String extraClasses) {

FILE: cloudinary-taglib/src/main/java/com/cloudinary/taglib/CloudinaryJsConfigTag.java
  class CloudinaryJsConfigTag (line 12) | public class CloudinaryJsConfigTag extends SimpleTagSupport {
    method doTag (line 13) | @SuppressWarnings("unused")
    method print (line 30) | private void print(JspWriter out, String key, Object value) throws IOE...

FILE: cloudinary-taglib/src/main/java/com/cloudinary/taglib/CloudinaryJsIncludeTag.java
  class CloudinaryJsIncludeTag (line 11) | public class CloudinaryJsIncludeTag  extends SimpleTagSupport {
    method doTag (line 15) | public void doTag() throws JspException, IOException {
    method isFull (line 34) | public boolean isFull() {
    method setFull (line 38) | public void setFull(boolean full) {
    method getBase (line 42) | public String getBase() {
    method setBase (line 46) | public void setBase(String base) {

FILE: cloudinary-taglib/src/main/java/com/cloudinary/taglib/CloudinaryTransformationTag.java
  class CloudinaryTransformationTag (line 12) | public class CloudinaryTransformationTag extends SimpleTagSupport implem...
    method doTag (line 15) | public void doTag() throws JspException, IOException {
    method setDynamicAttribute (line 20) | @Override

FILE: cloudinary-taglib/src/main/java/com/cloudinary/taglib/CloudinaryUnsignedUploadTag.java
  class CloudinaryUnsignedUploadTag (line 7) | public class CloudinaryUnsignedUploadTag extends CloudinaryUploadTag {
    method CloudinaryUnsignedUploadTag (line 8) | public CloudinaryUnsignedUploadTag() {
    method uploadTag (line 13) | @SuppressWarnings({ "unchecked", "rawtypes" })

FILE: cloudinary-taglib/src/main/java/com/cloudinary/taglib/CloudinaryUploadTag.java
  class CloudinaryUploadTag (line 19) | public class CloudinaryUploadTag extends SimpleTagSupport {
    method doTag (line 65) | public void doTag() throws JspException, IOException {
    method setId (line 121) | public void setId(String id) {
    method getId (line 125) | public String getId() {
    method setName (line 129) | public void setName(String name) {
    method getName (line 133) | public String getName() {
    method setExtraClasses (line 137) | public void setExtraClasses(String extraClasses) {
    method getExtraClasses (line 141) | public String getExtraClasses() {
    method setTags (line 145) | public void setTags(String tags) {
    method getTags (line 149) | public String getTags() {
    method setFieldName (line 153) | public void setFieldName(String fieldName) {
    method getFieldName (line 157) | public String getFieldName() {
    method setTransformation (line 161) | public void setTransformation(String transformation) {
    method getTransformation (line 165) | public String getTransformation() {
    method getResourceType (line 170) | public String getResourceType() {
    method setResourceType (line 174) | public void setResourceType(String resourceType) {
    method getMultiple (line 178) | public Boolean getMultiple() {
    method setMultiple (line 182) | public void setMultiple(Boolean multiple) {
    method getEager (line 186) | public String getEager() {
    method setEager (line 190) | public void setEager(String eager) {
    method getPublicId (line 194) | public String getPublicId() {
    method setPublicId (line 198) | public void setPublicId(String publicId) {
    method getFormat (line 202) | public String getFormat() {
    method setFormat (line 206) | public void setFormat(String format) {
    method getNotificationUrl (line 210) | public String getNotificationUrl() {
    method setNotificationUrl (line 214) | public void setNotificationUrl(String notificationUrl) {
    method getEagerNotificationUrl (line 218) | public String getEagerNotificationUrl() {
    method setEagerNotificationUrl (line 222) | public void setEagerNotificationUrl(String eagerNotificationUrl) {
    method getProxy (line 226) | public String getProxy() {
    method setProxy (line 230) | public void setProxy(String proxy) {
    method getFolder (line 234) | public String getFolder() {
    method setFolder (line 238) | public void setFolder(String folder) {
    method isBackup (line 242) | public boolean isBackup() {
    method setBackup (line 246) | public void setBackup(boolean backup) {
    method isExif (line 250) | public boolean isExif() {
    method setExif (line 254) | public void setExif(boolean exif) {
    method isFaces (line 258) | public boolean isFaces() {
    method setFaces (line 262) | public void setFaces(boolean faces) {
    method isColors (line 266) | public boolean isColors() {
    method setColors (line 270) | public void setColors(boolean colors) {
    method isImageMetadata (line 274) | public boolean isImageMetadata() {
    method setImageMetadata (line 278) | public void setImageMetadata(boolean imageMetadata) {
    method isUseFilename (line 282) | public boolean isUseFilename() {
    method setUseFilename (line 286) | public void setUseFilename(boolean useFilename) {
    method isUniqueFilename (line 290) | public boolean isUniqueFilename() {
    method setUniqueFilename (line 294) | public void setUniqueFilename(boolean uniqueFilename) {
    method isEagerAsync (line 298) | public boolean isEagerAsync() {
    method setEagerAsync (line 302) | public void setEagerAsync(boolean eagerAsync) {
    method isInvalidate (line 306) | public boolean isInvalidate() {
    method setInvalidate (line 310) | public void setInvalidate(boolean invalidate) {
    method getCallback (line 314) | public String getCallback() {
    method setCallback (line 318) | public void setCallback(String callback) {
    method getFaceCoordinates (line 322) | public String getFaceCoordinates() {
    method setFaceCoordinates (line 326) | public void setFaceCoordinates(String faceCoordinates) {
    method getCustomCoordinates (line 330) | public String getCustomCoordinates() {
    method setCustomCoordinates (line 334) | public void setCustomCoordinates(String customCoordinates) {
    method getAllowedFormats (line 338) | public String getAllowedFormats() {
    method setAllowedFormats (line 342) | public void setAllowedFormats(String allowedFormats) {
    method getContext (line 346) | public String getContext() {
    method setContext (line 350) | public void setContext(String context) {
    method isOverwrite (line 354) | public boolean isOverwrite() {
    method setOverwrite (line 358) | public void setOverwrite(boolean overwrite) {
    method isPhash (line 362) | public boolean isPhash() {
    method setPhash (line 366) | public void setPhash(boolean phash) {
    method getOcr (line 370) | public String getOcr() {
    method setOcr (line 374) | public void setOcr(String ocr) {
    method getDetection (line 378) | public String getDetection() {
    method setDetection (line 382) | public void setDetection(String detection) {
    method getCategorization (line 386) | public String getCategorization() {
    method setCategorization (line 390) | public void setCategorization(String categorization) {
    method getSimilaritySearch (line 394) | public String getSimilaritySearch() {
    method setSimilaritySearch (line 398) | public void setSimilaritySearch(String similaritySearch) {
    method getBackgroundRemoval (line 402) | public String getBackgroundRemoval() {
    method setBackgroundRemoval (line 406) | public void setBackgroundRemoval(String backgroundRemoval) {
    method getAutoTagging (line 410) | public Float getAutoTagging() {
    method setAutoTagging (line 414) | public void setAutoTagging(String autoTagging) {
    method getUploadPreset (line 418) | public String getUploadPreset() {
    method setUploadPreset (line 422) | public void setUploadPreset(String uploadPreset) {
    method uploadTag (line 426) | @SuppressWarnings({ "unchecked", "rawtypes" })
    method buildCallbackUrl (line 431) | @SuppressWarnings({ "rawtypes", "unchecked" })
    method buildEager (line 449) | private List<Transformation> buildEager() {

FILE: cloudinary-taglib/src/main/java/com/cloudinary/taglib/CloudinaryUrl.java
  class CloudinaryUrl (line 23) | public class CloudinaryUrl extends SimpleTagSupport implements DynamicAt...
    method prepareUrl (line 46) | protected Url prepareUrl() throws JspException {
    method doTag (line 78) | public void doTag() throws JspException, IOException {
    method setSrc (line 84) | public void setSrc(String src) {
    method getStoredSrc (line 88) | public StoredFile getStoredSrc() {
    method setStoredSrc (line 92) | public void setStoredSrc(StoredFile storedSrc) {
    method getSrc (line 96) | public String getSrc() {
    method setFormat (line 100) | public void setFormat(String format) {
    method getFormat (line 104) | public String getFormat() {
    method getType (line 108) | public String getType() {
    method setType (line 112) | public void setType(String type) {
    method getResourceType (line 116) | public String getResourceType() {
    method setResourceType (line 120) | public void setResourceType(String resourceType) {
    method getTransformation (line 125) | public String getTransformation() {
    method setTransformation (line 129) | public void setTransformation(String transformation) {
    method getSecure (line 133) | public Boolean getSecure() {
    method setSecure (line 137) | public void setSecure(Boolean secure) {
    method getCdnSubdomain (line 141) | public Boolean getCdnSubdomain() {
    method setCdnSubdomain (line 145) | public void setCdnSubdomain(Boolean cdnSubdomain) {
    method getSigned (line 149) | public Boolean getSigned() {
    method setSigned (line 153) | public void setSigned(Boolean signed) {
    method getNamed (line 157) | public String getNamed() {
    method setNamed (line 161) | public void setNamed(String namedTransformation) {
    method setDynamicAttribute (line 165) | @Override
    method isSecureRequest (line 170) | private Boolean isSecureRequest() {
    method getUseRootPath (line 177) | public Boolean getUseRootPath() {
    method setUseRootPath (line 181) | public void setUseRootPath(Boolean useRootPath) {
    method getSecureCdnSubdomain (line 185) | public Boolean getSecureCdnSubdomain() {
    method setSecureCdnSubdomain (line 189) | public void setSecureCdnSubdomain(Boolean secureCdnSubdomain) {
    method getUrlSuffix (line 193) | public String getUrlSuffix() {
    method setUrlSuffix (line 197) | public void setUrlSuffix(String urlSuffix) {

FILE: cloudinary-taglib/src/main/java/com/cloudinary/taglib/CloudinaryVideoTag.java
  class CloudinaryVideoTag (line 12) | public class CloudinaryVideoTag extends CloudinaryImageTag {
    method getAutoplay (line 21) | public Boolean getAutoplay() {
    method setAutoplay (line 24) | public void setAutoplay(Boolean autoplay) {
    method getControls (line 27) | public Boolean getControls() {
    method setControls (line 30) | public void setControls(Boolean controls) {
    method getLoop (line 33) | public Boolean getLoop() {
    method setLoop (line 36) | public void setLoop(Boolean loop) {
    method getMuted (line 39) | public Boolean getMuted() {
    method setMuted (line 42) | public void setMuted(Boolean muted) {
    method getPreload (line 45) | public Boolean getPreload() {
    method setPreload (line 48) | public void setPreload(Boolean preload) {
    method getPoster (line 51) | public Object getPoster() {
    method setPoster (line 54) | public void setPoster(Object poster) {
    method getSourceTypes (line 58) | public String getSourceTypes() {
    method setSourceTypes (line 61) | public void setSourceTypes(String sourceTypes) {
    method doTag (line 65) | public void doTag() throws JspException, IOException {

FILE: cloudinary-test-common/src/main/java/com/cloudinary/test/AbstractAccountApiTest.java
  class AbstractAccountApiTest (line 19) | public abstract class AbstractAccountApiTest extends MockableTest {
    method setUpClass (line 26) | @BeforeClass
    method setUp (line 36) | @Before
    method tearDownClass (line 43) | @AfterClass
    method testPassingCredentialsThroughOptions (line 74) | @Test
    method testGetSubAccount (line 108) | @Test
    method testGetSubAccounts (line 116) | @Test
    method testCreateSubAccount (line 125) | @Test
    method testUpdateSubAccount (line 142) | @Test
    method testDeleteSubAccount (line 152) | @Test
    method testGetUser (line 164) | @Test
    method testGetUsers (line 175) | @Test
    method testGetPendingUsers (line 196) | @Test
    method testGetUsersByPrefix (line 211) | @Test
    method testGetUsersBySubAccountIds (line 230) | @Test
    method testGetUsersThrowsWhenSubAccountIdDoesntExist (line 249) | @Test
    method testCreateUser (line 257) | @Test
    method testCreateUserWithOptions (line 265) | @Test
    method testCreateUserEnabled (line 273) | @Test
    method testCreateUserDisabled (line 281) | @Test
    method testUpdateUser (line 289) | @Test
    method testUpdateUserEnabled (line 302) | @Test
    method testUpdateUserDisabled (line 315) | @Test
    method testDeleteUser (line 328) | @Test
    method testCreateUserGroup (line 339) | @Test
    method testUpdateUserGroup (line 346) | @Test
    method testDeleteUserGroup (line 355) | @Test
    method testAddUserToUserGroup (line 366) | @Test
    method testRemoveUserFromUserGroup (line 377) | @Test
    method testListUserGroups (line 390) | @Test
    method testListUserGroup (line 399) | @Test
    method testListUsersInGroup (line 407) | @Test
    method testGetAccessKeys (line 425) | @Test
    method testCreateNewAccessKey (line 432) | @Test
    method testUpdateAccessKey (line 441) | @Test
    method testDeleteAccessKey (line 455) | @Test
    method createGroup (line 468) | private ApiResponse createGroup() throws Exception {
    method createUser (line 476) | private ApiResponse createUser() throws Exception {
    method createUser (line 481) | private ApiResponse createUser(Account.Role role) throws Exception {
    method createUser (line 486) | private ApiResponse createUser(List<String> subAccountsIds) throws Exc...
    method createUser (line 491) | private ApiResponse createUser(List<String> subAccountsIds, Map<String...
    method createUser (line 496) | private ApiResponse createUser(List<String> subAccountsIds, Boolean en...
    method createUser (line 501) | private ApiResponse createUser(List<String> subAccountsIds, Account.Ro...
    method createUser (line 507) | private ApiResponse createUser(List<String> subAccountsIds, Account.Ro...
    method createUser (line 515) | private ApiResponse createUser(List<String> subAccountsIds, Account.Ro...
    method createUser (line 523) | private ApiResponse createUser(final String name, String email, Accoun...
    method deleteUser (line 530) | private void deleteUser(String userId){
    method createSubAccount (line 541) | private ApiResponse createSubAccount() throws Exception {
    method randomLetters (line 548) | private static String randomLetters() {

FILE: cloudinary-test-common/src/main/java/com/cloudinary/test/AbstractApiTest.java
  class AbstractApiTest (line 26) | @SuppressWarnings({"rawtypes", "unchecked", "JavaDoc"})
    method setUpClass (line 63) | @BeforeClass
    method tearDownClass (line 100) | @AfterClass
    method setUp (line 149) | @Before
    method findByAttr (line 159) | public Map findByAttr(List<Map> elements, String attr, Object value) {
    method testCustomUserAgent (line 168) | @Test
    method test01ResourceTypes (line 176) | @Test
    method testSingleSelectiveResponse (line 184) | @Test
    method testMultipleSelectiveResponse (line 197) | @Test
    method test03ResourcesCursor (line 211) | @Test
    method test04ResourcesByType (line 230) | @Test
    method testOAuthToken (line 240) | @Test
    method test05ResourcesByPrefix (line 252) | @Test
    method testResourcesListingDirection (line 265) | @Test
    method testResourcesListingStartAt (line 284) | @Ignore
    method testTransformationsWithCursor (line 297) | @Test
    method testResourcesByAssetIds (line 311) | @Test
    method testResourceByAssetId (line 320) | @Test
    method testResourceByAssetFolder (line 326) | @Test
    method testResourcesByPublicIds (line 334) | @Test
    method test06ResourcesTag (line 351) | @Test
    method test07ResourceMetadata (line 368) | @Test
    method test08DeleteDerived (line 378) | @Test
    method testDeleteDerivedByTransformation (line 395) | @Test()
    method testGetResourcesWithMetadata (line 415) | @Test
    method getMetadata (line 451) | private Object getMetadata(String public_id, Map result) {
    method test09DeleteResources (line 456) | @Test(expected = NotFound.class)
    method test10DeleteResourcesByAssetsIds (line 467) | @Test(expected = NotFound.class)
    method test09aDeleteResourcesByPrefix (line 481) | @Test(expected = NotFound.class)
    method test09aDeleteResourcesByTags (line 492) | @Test(expected = NotFound.class)
    method test10Tags (line 503) | @Test
    method test11TagsPrefix (line 512) | @Test
    method test12Transformations (line 523) | @Test
    method test13TransformationMetadata (line 535) | @Test
    method test14TransformationUpdate (line 544) | @Test
    method test15TransformationCreate (line 557) | @Test
    method test15aTransformationUnsafeUpdate (line 568) | @Test
    method test16aTransformationDelete (line 580) | @Test(expected = NotFound.class)
    method test17aTransformationDeleteImplicit (line 590) | @Test(expected = NotFound.class)
    method testListTransformationByNamed (line 599) | @Test
    method test20ResourcesContext (line 639) | @Test
    method test18Usage (line 651) | @Test
    method yesterday (line 666) | private Date yesterday() {
    method testRateLimitWithNonEnglishLocale (line 670) | @Test
    method testRateLimits (line 677) | @Test
    method testConfiguration (line 685) | @Test
    method test19Ping (line 692) | @Test
    method testDeleteAllResources (line 703) | public void testDeleteAllResources() throws Exception {
    method testManualModeration (line 715) | @Test
    method testOcrUpdate (line 723) | @Test
    method testRawConvertUpdate (line 740) | @Test
    method testCategorizationUpdate (line 752) | @Test
    method testDetectionUpdate (line 764) | @Test
    method testUpdateResourceClearInvalid (line 776) | @Test
    method testUpdateCustomCoordinates (line 786) | @Test
    method testUpdateAccessControl (line 800) | @Test
    method testListUploadPresets (line 818) | @Test
    method testGetUploadPreset (line 836) | @Test
    method testDeleteUploadPreset (line 861) | @Test
    method testUpdateUploadPreset (line 876) | @Test
    method testListByModerationUpdate (line 893) | @Test
    method testFolderApi (line 927) | public void testFolderApi() throws Exception {
    method testCreateFolder (line 947) | @Test
    method testRestore (line 955) | @Test
    method testRestoreByAssetIds (line 974) | @Test
    method testRestoreDifferentVersionsOfDeletedAsset (line 1000) | @Test
    method testShouldRestoreTwoDifferentDeletedAssets (line 1049) | @Test
    method testEncodeUrlInApiCall (line 1090) | @Test
    method testUploadMapping (line 1098) | @Test
    method testPublishByIds (line 1138) | @Test
    method testPublishWithType (line 1152) | @Test
    method testPublishByPrefix (line 1181) | @Test
    method testPublishByTag (line 1195) | @Test
    method testUpdateResourcesAccessModeByIds (line 1209) | @Test
    method testUpdateResourcesAccessModeByPrefix (line 1224) | @Test
    method testUpdateResourcesAccessModeByTag (line 1239) | @Test
    method testQualityAnalysis (line 1254) | @Test
    method testDeleteFolder (line 1260) | @Test(expected = NotFound.class)
    method testCinemagraphAnalysisResource (line 1274) | @Test
    method testAccessibilityAnalysisResource (line 1280) | @Test
    method testAnalyzeApi (line 1286) | @Test
    method testFolderDecoupling (line 1294) | @Test
    method testVisualSearch (line 1306) | @Test
    method testRenameFolder (line 1316) | @Test
    method testDeleteBackedupAsset (line 1327) | @Test
    method testAllowDerivedNextCursor (line 1347) | @Test
    method testSignatureWithEscapingCharacters (line 1372) | @Test

FILE: cloudinary-test-common/src/main/java/com/cloudinary/test/AbstractContextTest.java
  class AbstractContextTest (line 21) | @SuppressWarnings({"rawtypes", "unchecked"})
    method setUpClass (line 28) | @BeforeClass
    method uploadResource (line 36) | private static Map uploadResource(String publicId) throws IOException {
    method tearDownClass (line 44) | @AfterClass
    method setUp (line 56) | @Before
    method testExplicit (line 65) | @Test
    method testAddContext (line 77) | @Test
    method testRemoveAllContext (line 90) | @Test

FILE: cloudinary-test-common/src/main/java/com/cloudinary/test/AbstractFoldersApiTest.java
  class AbstractFoldersApiTest (line 17) | @SuppressWarnings({"rawtypes"})
    method setUp (line 24) | @Before
    method testRootFolderWithParams (line 32) | @Test
    method testSubFolderWithParams (line 59) | @Test
    method testDeleteFolderWithSkipBackup (line 89) | @Test

FILE: cloudinary-test-common/src/main/java/com/cloudinary/test/AbstractSearchTest.java
  class AbstractSearchTest (line 17) | @SuppressWarnings({"rawtypes", "unchecked", "JavaDoc"})
    method setUpClass (line 29) | @BeforeClass
    method tearDownClass (line 46) | @AfterClass
    method setUp (line 57) | @Before
    method shouldFindResourcesByTag (line 64) | @Test
    method shouldFindFolders (line 71) | @Test
    method shouldFindResourceByPublicId (line 83) | @Test
    method shouldFindResourceByAssetId (line 90) | @Test
    method testShouldNotDuplicateValues (line 97) | @Test
    method shouldPaginateResourcesLimitedByTagAndOrderdByAscendingPublicId (line 132) | @Test
    method testShouldBuildSearchUrl (line 160) | @Test
    method testSearchWithSelectiveResponse (line 178) | @Test

FILE: cloudinary-test-common/src/main/java/com/cloudinary/test/AbstractStreamingProfilesApiTest.java
  class AbstractStreamingProfilesApiTest (line 25) | abstract public class AbstractStreamingProfilesApiTest extends MockableT...
    method setUpClass (line 33) | @BeforeClass
    method setUp (line 44) | @Before
    method testCreate (line 52) | @Test
    method testGet (line 63) | @Test
    method testList (line 72) | @Test
    method testDelete (line 84) | @Test
    method testUpdate (line 98) | @Test
    method tearDownClass (line 126) | @AfterClass

FILE: cloudinary-test-common/src/main/java/com/cloudinary/test/AbstractStructuredMetadataTest.java
  class AbstractStructuredMetadataTest (line 22) | public abstract class AbstractStructuredMetadataTest extends MockableTest {
    method setUpClass (line 29) | @BeforeClass
    method tearDownClass (line 40) | @AfterClass
    method setUp (line 55) | @Before
    method testCreateMetadata (line 63) | @Test
    method testCreateSetMetadataWithAllowDynamicListValues (line 76) | @Test
    method testFieldRestrictions (line 85) | @Test
    method testDateFieldDefaultValueValidation (line 97) | @Test
    method testListFields (line 134) | @Test
    method testGetMetadata (line 145) | @Test
    method testUpdateField (line 153) | @Test
    method testDeleteField (line 170) | @Test
    method testUpdateDatasource (line 178) | @Test
    method testDeleteDatasourceEntries (line 188) | @Test
    method testRestoreDatasourceEntries (line 196) | @Test
    method testReorderMetadataFieldsByLabel (line 206) | @Test
    method testReorderMetadataFieldsOrderByIsRequired (line 222) | @Test(expected = IllegalArgumentException.class)
    method getField (line 227) | private String getField(ApiResponse result, int index) {
    method AddStringField (line 232) | private void AddStringField(String labelPrefix) throws Exception {
    method testUploadWithMetadata (line 238) | @Test
    method testExplicitWithMetadata (line 249) | @Test
    method testUpdateWithMetadata (line 273) | @Test
    method testUploaderUpdateMetadata (line 286) | @Test
    method testUploaderUpdateMetadataClearInvalid (line 300) | @Test
    method testSetField (line 309) | @Test
    method testListMetadataRules (line 325) | @Test
    method testAddMetadataRule (line 332) | @Test
    method testUpdateMetadataRule (line 348) | @Test
    method testDeleteMetadataRule (line 361) | @Test
    method createSetField (line 374) | private SetMetadataField createSetField(String labelPrefix) {
    method newFieldInstance (line 392) | private StringMetadataField newFieldInstance(String labelPrefix, Boole...
    method addFieldToAccount (line 397) | private ApiResponse addFieldToAccount(MetadataField field) throws Exce...

FILE: cloudinary-test-common/src/main/java/com/cloudinary/test/AbstractUploaderTest.java
  class AbstractUploaderTest (line 26) | @SuppressWarnings({"rawtypes", "unchecked"})
    method setUpClass (line 39) | @BeforeClass
    method tearDownClass (line 56) | @AfterClass
    method setUp (line 87) | @Before
    method testUtf8Upload (line 96) | @Test
    method testDeleteByToken (line 111) | @Test
    method testUpload (line 124) | @Test
    method testIsRemoteUrl (line 138) | @Test
    method testUploadUrl (line 162) | @Test
    method testUploadLargeUrl (line 174) | @Test
    method testUploadDataUri (line 186) | @Test
    method testUploadUTF8 (line 198) | @Test
    method testRename (line 205) | @Test
    method testRenameShouldReturnContext (line 226) | @Test
    method testRenameShouldReturnMetadata (line 236) | @Test
    method testUniqueFilename (line 251) | @Test
    method testExplicit (line 259) | @Test
    method testEager (line 268) | @Test
    method testUploadAsync (line 273) | @Test
    method testHeaders (line 279) | @Test
    method testText (line 285) | @Test
    method testImageUploadTag (line 293) | @Test
    method testEvalUploadParameter (line 304) | @Test
    method testSprite (line 316) | @Test
    method testMulti (line 339) | @Test
    method testTags (line 366) | @Test
    method testAllowedFormats (line 408) | @Test
    method testAllowedFormatsWithIllegalFormat (line 416) | @Test
    method testAllowedFormatsWithFormat (line 429) | @Test
    method testFaceCoordinates (line 437) | @Test
    method testCustomCoordinates (line 480) | @Test
    method testModerationRequest (line 502) | @Test
    method testRawConvertRequest (line 511) | @Test
    method testCategorizationRequest (line 521) | @Test
    method testDetectionRequest (line 535) | @Test
    method testUploadLarge (line 548) | @Test
    method testUnsignedUpload (line 594) | @Test
    method testFilenameOption (line 603) | @Test
    method testFilenameOverrideOption (line 610) | @Test
    method testResponsiveBreakpoints (line 617) | @Test
    method testCreateArchive (line 658) | @Test
    method testCreateArchiveRaw (line 674) | @Test
    method testCreateZipMultipleResourceTypes (line 682) | @Test
    method testDownloadArchive (line 689) | @Test
    method testUploadInvalidUrl (line 706) | public void testUploadInvalidUrl() {
    method testAccessControl (line 715) | @Test
    method testOnSuccessScript (line 767) | @Test
    method testQualityAnalysis (line 774) | @Test
    method testCinemagraphAnalysisUpload (line 783) | @Test
    method testAccessibilityAnalysisUpload (line 792) | @Test
    method addToDeleteList (line 800) | private void addToDeleteList(String type, String id) {
    method testUploadLocalUnicodeFilename (line 810) | @Test
    method testUploadFolderDecoupling (line 816) | @Test
    method testNotificationUrl (line 836) | @Test
    method testAutoChaptering (line 843) | @Test
    method testAutoTranscription (line 851) | @Test

FILE: cloudinary-test-common/src/main/java/com/cloudinary/test/MetadataTestHelper.java
  class MetadataTestHelper (line 9) | public final class MetadataTestHelper {
    method MetadataTestHelper (line 10) | private MetadataTestHelper() {}
    method newFieldInstance (line 12) | public static StringMetadataField newFieldInstance(String label, Boole...
    method addFieldToAccount (line 21) | public static ApiResponse addFieldToAccount(Api api, MetadataField fie...

FILE: cloudinary-test-common/src/main/java/com/cloudinary/test/MockableTest.java
  class MockableTest (line 16) | public class MockableTest {
    method getParam (line 27) | protected Object getParam(String name){
    method getURL (line 30) | protected String getURL(){
    method getHttpMethod (line 33) | protected String getHttpMethod(){
    method preloadResource (line 37) | protected Map preloadResource(Map options) throws IOException {
    method assumeAddonEnabled (line 48) | protected void assumeAddonEnabled(String addon) throws Exception {
    method getEnabledAddons (line 55) | private static List<String> getEnabledAddons() {
    method shouldTestFeature (line 64) | protected static boolean shouldTestFeature(String feature) {
    method assumeCloudinaryAccountURLExist (line 73) | static protected boolean assumeCloudinaryAccountURLExist() {

FILE: cloudinary-test-common/src/main/java/com/cloudinary/test/TimeoutTest.java
  type TimeoutTest (line 6) | public interface TimeoutTest {

FILE: cloudinary-test-common/src/main/java/com/cloudinary/test/helpers/Feature.java
  class Feature (line 3) | public final class Feature {
    method Feature (line 4) | private Feature() {}

FILE: cloudinary-test-common/src/main/java/com/cloudinary/test/rules/RetryRule.java
  class RetryRule (line 9) | public class RetryRule implements TestRule {
    method RetryRule (line 13) | public RetryRule(int retryCount, int delay) {
    method RetryRule (line 18) | public RetryRule() {
    method apply (line 23) | public Statement apply(Statement base, Description description) {
    method statement (line 27) | private Statement statement(final Statement base, final Description de...

FILE: samples/photo_album/src/main/java/cloudinary/controllers/PhotoController.java
  class PhotoController (line 21) | @Controller
    method listPhotos (line 27) | @RequestMapping(value = "/", method = RequestMethod.GET)
    method uploadPhoto (line 33) | @SuppressWarnings("rawtypes")
    method uploadPhotoForm (line 70) | @RequestMapping(value = "/upload_form", method = RequestMethod.GET)
    method directUploadPhotoForm (line 76) | @RequestMapping(value = "/direct_upload_form", method = RequestMethod....
    method directUnsignedUploadPhotoForm (line 83) | @SuppressWarnings("unchecked")

FILE: samples/photo_album/src/main/java/cloudinary/lib/PhotoUploadValidator.java
  class PhotoUploadValidator (line 8) | public class PhotoUploadValidator implements Validator {
    method supports (line 9) | public boolean supports(Class clazz) {
    method validate (line 13) | public void validate(Object obj, Errors e) {

FILE: samples/photo_album/src/main/java/cloudinary/models/Photo.java
  class Photo (line 8) | @Entity(name = "photos")
    method getId (line 23) | public Long getId() {
    method setId (line 27) | public void setId(Long id) {
    method getTitle (line 31) | public String getTitle() {
    method setTitle (line 35) | public void setTitle(String title) {
    method getImage (line 39) | public String getImage() {
    method setImage (line 43) | public void setImage(String image) {
    method getCreatedAt (line 47) | public Date getCreatedAt() {
    method setCreatedAt (line 51) | public void setCreatedAt(Date createdAt) {
    method getUpload (line 55) | public StoredFile getUpload() {
    method setUpload (line 61) | public void setUpload(StoredFile file) {

FILE: samples/photo_album/src/main/java/cloudinary/models/PhotoUpload.java
  class PhotoUpload (line 8) | public class PhotoUpload extends StoredFile {
    method getUrl (line 13) | public String getUrl() {
    method getThumbnailUrl (line 24) | public String getThumbnailUrl() {
    method getComputedSignature (line 34) | public String getComputedSignature() {
    method validSignature (line 38) | public boolean validSignature() {
    method getTitle (line 42) | public String getTitle() {
    method setTitle (line 46) | public void setTitle(String title) {
    method getFile (line 50) | public MultipartFile getFile() {
    method setFile (line 54) | public void setFile(MultipartFile file) {

FILE: samples/photo_album/src/main/java/cloudinary/repositories/PhotoRepository.java
  type PhotoRepository (line 6) | public interface PhotoRepository extends JpaRepository<Photo, Long> {

FILE: samples/photo_album/src/main/webapp/assets/javascripts/cloudinary/jquery.cloudinary.js
  function utf8_encode (line 34) | function utf8_encode (argString) {
  function crc32 (line 86) | function crc32 (str) {
  function option_consume (line 114) | function option_consume(options, option_name, default_value) {
  function build_array (line 120) | function build_array(arg) {
  function present (line 130) | function present(value) {
  function process_base_transformations (line 134) | function process_base_transformations(options) {
  function process_size (line 156) | function process_size(options) {
  function process_html_dimensions (line 165) | function process_html_dimensions(options) {
  function generate_transformation_string (line 236) | function generate_transformation_string(options) {
  function absolutize (line 260) | function absolutize(url) {
  function cloudinary_url (line 273) | function cloudinary_url(public_id, options) {
  function default_stoppoints (line 342) | function default_stoppoints(width) {
  function prepare_html_url (line 346) | function prepare_html_url(public_id, options) {
  function get_config (line 358) | function get_config(name, options, default_value) {
  function reset (line 449) | function reset() {
  function run (line 455) | function run() {
  function wait (line 458) | function wait() {

FILE: samples/photo_album/src/main/webapp/assets/javascripts/cloudinary/jquery.ui.widget.js
  function handlerProxy (line 396) | function handlerProxy() {
  function handlerProxy (line 432) | function handlerProxy() {

FILE: samples/photo_album_gae/src/main/java/cloudinary/controllers/PhotoController.java
  class PhotoController (line 27) | @Controller
    method listPhotos (line 32) | @RequestMapping(value = "/", method = RequestMethod.GET)
    method uploadPhoto (line 45) | @RequestMapping(value = "/upload", method = RequestMethod.POST)
    method uploadPhotoForm (line 78) | @RequestMapping(value = "/upload_form", method = RequestMethod.GET)
    method directUploadPhotoForm (line 84) | @RequestMapping(value = "/direct_upload_form", method = RequestMethod....

FILE: samples/photo_album_gae/src/main/java/cloudinary/lib/PhotoUploadValidator.java
  class PhotoUploadValidator (line 8) | public class PhotoUploadValidator implements Validator {
    method supports (line 9) | public boolean supports(Class clazz) {
    method validate (line 13) | public void validate(Object obj, Errors e) {

FILE: samples/photo_album_gae/src/main/java/cloudinary/models/PhotoUpload.java
  class PhotoUpload (line 9) | public class PhotoUpload extends StoredFile {
    method PhotoUpload (line 13) | public PhotoUpload() {
    method PhotoUpload (line 17) | public PhotoUpload(Entity entity) {
    method getUrl (line 27) | public String getUrl() {
    method getThumbnailUrl (line 38) | public String getThumbnailUrl() {
    method getComputedSignature (line 48) | public String getComputedSignature() {
    method validSignature (line 52) | public boolean validSignature() {
    method getTitle (line 56) | public String getTitle() {
    method setTitle (line 60) | public void setTitle(String title) {
    method getFile (line 64) | public GMultipartFile getFile() {
    method setFile (line 68) | public void setFile(GMultipartFile file) {
    method toEntity (line 72) | public void toEntity(Entity photo) {

FILE: samples/photo_album_gae/src/main/java/org/esxx/js/protocol/GAEClientConnection.java
  class GAEClientConnection (line 37) | class GAEClientConnection
    method GAEClientConnection (line 40) | public GAEClientConnection(ClientConnectionManager cm, HttpRoute route...
    method isSecure (line 49) | @Override public boolean isSecure() {
    method getRoute (line 53) | @Override public HttpRoute getRoute() {
    method getSSLSession (line 57) | @Override public javax.net.ssl.SSLSession getSSLSession() {
    method open (line 61) | @Override public void open(HttpRoute route, HttpContext context, HttpP...
    method tunnelTarget (line 68) | @Override public void tunnelTarget(boolean secure, HttpParams params)
    method tunnelProxy (line 73) | @Override public void tunnelProxy(HttpHost next, boolean secure, HttpP...
    method layerProtocol (line 78) | @Override public void layerProtocol(HttpContext context, HttpParams pa...
    method markReusable (line 83) | @Override public void markReusable() {
    method unmarkReusable (line 87) | @Override public void unmarkReusable() {
    method isMarkedReusable (line 91) | @Override public boolean isMarkedReusable() {
    method setState (line 95) | @Override public void setState(Object state) {
    method getState (line 99) | @Override public Object getState() {
    method setIdleDuration (line 103) | @Override public void setIdleDuration(long duration, TimeUnit unit) {
    method isResponseAvailable (line 110) | @Override public boolean isResponseAvailable(int timeout)
    method sendRequestHeader (line 116) | @Override public void sendRequestHeader(HttpRequest request)
    method sendRequestEntity (line 147) | @Override public void sendRequestEntity(HttpEntityEnclosingRequest req...
    method receiveResponseHeader (line 157) | @Override public HttpResponse receiveResponseHeader()
    method receiveResponseEntity (line 177) | @Override public void receiveResponseEntity(HttpResponse response)
    method flush (line 190) | @Override public void flush()
    method close (line 210) | @Override public void close()
    method isOpen (line 218) | @Override public boolean isOpen() {
    method isStale (line 222) | @Override public boolean isStale() {
    method setSocketTimeout (line 226) | @Override public void setSocketTimeout(int timeout) {
    method getSocketTimeout (line 229) | @Override public int getSocketTimeout() {
    method shutdown (line 233) | @Override public void shutdown()
    method getMetrics (line 238) | @Override public HttpConnectionMetrics getMetrics() {
    method getLocalAddress (line 245) | @Override public InetAddress getLocalAddress() {
    method getLocalPort (line 249) | @Override public int getLocalPort() {
    method getRemoteAddress (line 253) | @Override public InetAddress getRemoteAddress() {
    method getRemotePort (line 257) | @Override public int getRemotePort() {
    method releaseConnection (line 265) | @Override public void releaseConnection()
    method abortConnection (line 270) | @Override public void abortConnection()

FILE: samples/photo_album_gae/src/main/java/org/esxx/js/protocol/GAEConnectionManager.java
  class GAEConnectionManager (line 31) | public class GAEConnectionManager
    method GAEConnectionManager (line 34) | public GAEConnectionManager() {
    method getSchemeRegistry (line 57) | @Override public SchemeRegistry getSchemeRegistry() {
    method requestConnection (line 61) | @Override public ClientConnectionRequest requestConnection(final HttpR...
    method releaseConnection (line 74) | @Override public void releaseConnection(ManagedClientConnection conn,
    method closeIdleConnections (line 78) | @Override public void closeIdleConnections(long idletime, TimeUnit tun...
    method closeExpiredConnections (line 81) | @Override public void closeExpiredConnections() {
    method shutdown (line 84) | @Override public void shutdown() {
    method getConnection (line 87) | private ManagedClientConnection getConnection(HttpRoute route, Object ...

FILE: samples/photo_album_gae/src/main/webapp/assets/javascripts/cloudinary/jquery.cloudinary.js
  function utf8_encode (line 13) | function utf8_encode (argString) {
  function crc32 (line 65) | function crc32 (str) {
  function option_consume (line 93) | function option_consume(options, option_name, default_value) {
  function build_array (line 98) | function build_array(arg) {
  function present (line 107) | function present(value) {
  function generate_transformation_string (line 110) | function generate_transformation_string(options) {
  function absolutize (line 188) | function absolutize(url) {
  function cloudinary_url (line 195) | function cloudinary_url(public_id, options) {
  function html_only_attributes (line 259) | function html_only_attributes(options) {

FILE: samples/photo_album_gae/src/main/webapp/assets/javascripts/cloudinary/jquery.ui.widget.js
  function handlerProxy (line 396) | function handlerProxy() {
  function handlerProxy (line 432) | function handlerProxy() {
Condensed preview — 199 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,357K chars).
[
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 1085,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n## Bug report fo"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 530,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n## Feature re"
  },
  {
    "path": ".github/pull_request_template.md",
    "chars": 960,
    "preview": "### Brief Summary of Changes\n<!-- Provide some context as to what was changed, from an implementation standpoint. -->\n\n#"
  },
  {
    "path": ".github/workflows/build.yml",
    "chars": 1395,
    "preview": "name: Java SDK Matrix CI\n\non:\n  push:\n    branches-ignore:\n      - staging-test\n  pull_request:\n\njobs:\n  build:\n    name"
  },
  {
    "path": ".gitignore",
    "chars": 566,
    "preview": "## Apple storage files\n*.DS_Store\n\n## Android default ignore\n# Built application files\n*.apk\n*.ap_\n\n# Files for the Dalv"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 30005,
    "preview": "2.3.1 / 2025-08-13\n==================\n\n* Bump dependencies version\n\n2.3.0 / 2025-06-18\n==================\n* Fix API para"
  },
  {
    "path": "LICENSE",
    "chars": 1067,
    "preview": "MIT License\n\nCopyright (c) 2017 Cloudinary\n\nPermission is hereby granted, free of charge, to any person obtaining a copy"
  },
  {
    "path": "MAVEN_CENTRAL_PUBLISHING_GUIDE.md",
    "chars": 14930,
    "preview": "# Maven Central Publishing Guide - Cloudinary Java SDK\n\nThis guide documents the complete process for publishing the Clo"
  },
  {
    "path": "README.md",
    "chars": 6771,
    "preview": "[![Build Status](https://travis-ci.org/cloudinary/cloudinary_java.svg?branch=master)](https://travis-ci.org/cloudinary/c"
  },
  {
    "path": "build.gradle",
    "chars": 1591,
    "preview": "import groovy.json.JsonSlurper\n\nplugins {\n    id 'maven-publish'\n    // Removed old nexus plugin - we'll create bundles "
  },
  {
    "path": "cloudinary-core/build.gradle",
    "chars": 419,
    "preview": "plugins {\n    id 'java-library'\n}\n\ntask ciTest( type: Test )\n\ndependencies {\n    testImplementation \"org.hamcrest:java-h"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/AccessControlRule.java",
    "chars": 1898,
    "preview": "package com.cloudinary;\n\nimport com.cloudinary.utils.ObjectUtils;\nimport org.cloudinary.json.JSONObject;\n\nimport java.ut"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/Api.java",
    "chars": 44294,
    "preview": "package com.cloudinary;\n\nimport java.util.*;\n\nimport com.cloudinary.api.ApiResponse;\nimport com.cloudinary.api.Authoriza"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/ArchiveParams.java",
    "chars": 6890,
    "preview": "package com.cloudinary;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class ArchiveP"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/AuthToken.java",
    "chars": 9471,
    "preview": "package com.cloudinary;\n\nimport com.cloudinary.utils.ObjectUtils;\nimport com.cloudinary.utils.StringUtils;\n\nimport javax"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/BaseParam.java",
    "chars": 443,
    "preview": "package com.cloudinary;\n\nimport com.cloudinary.utils.StringUtils;\n\nimport java.util.List;\n\npublic class BaseParam {\n    "
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/Cloudinary.java",
    "chars": 17074,
    "preview": "package com.cloudinary;\n\nimport com.cloudinary.api.signing.ApiResponseSignatureVerifier;\nimport com.cloudinary.api.signi"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/Configuration.java",
    "chars": 21412,
    "preview": "package com.cloudinary;\n\nimport java.io.UnsupportedEncodingException;\nimport java.net.URI;\nimport java.net.URLDecoder;\ni"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/Coordinates.java",
    "chars": 2871,
    "preview": "package com.cloudinary;\n\nimport java.io.Serializable;\nimport java.util.ArrayList;\nimport java.util.Collection;\n\nimport c"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/CustomFunction.java",
    "chars": 1085,
    "preview": "package com.cloudinary;\n\nimport com.cloudinary.utils.Base64Coder;\n\n/**\n * Helper class to generate a custom function par"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/EagerTransformation.java",
    "chars": 1320,
    "preview": "package com.cloudinary;\n\nimport com.cloudinary.utils.StringUtils;\n\nimport java.util.ArrayList;\nimport java.util.List;\nim"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/ProgressCallback.java",
    "chars": 367,
    "preview": "package com.cloudinary;\n\n/**\n * Defines a callback for network operations.\n */\npublic interface ProgressCallback {\n    /"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/ResponsiveBreakpoint.java",
    "chars": 1678,
    "preview": "package com.cloudinary;\n\nimport org.cloudinary.json.JSONObject;\n\npublic class ResponsiveBreakpoint extends JSONObject {\n"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/Search.java",
    "chars": 4582,
    "preview": "package com.cloudinary;\n\nimport com.cloudinary.api.ApiResponse;\nimport com.cloudinary.utils.Base64Coder;\nimport com.clou"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/SearchFolders.java",
    "chars": 539,
    "preview": "package com.cloudinary;\n\nimport com.cloudinary.api.ApiResponse;\nimport com.cloudinary.utils.ObjectUtils;\n\nimport java.ut"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/SignatureAlgorithm.java",
    "chars": 414,
    "preview": "package com.cloudinary;\n\n/**\n * Defines supported algorithms for generating/verifying hashed message authentication code"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/SmartUrlEncoder.java",
    "chars": 458,
    "preview": "package com.cloudinary;\n\nimport java.io.UnsupportedEncodingException;\nimport java.net.URLEncoder;\n\npublic final class Sm"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/StoredFile.java",
    "chars": 3608,
    "preview": "package com.cloudinary;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.regex.Matcher;\nimport java.uti"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/Transformation.java",
    "chars": 31903,
    "preview": "package com.cloudinary;\n\nimport java.io.Serializable;\nimport java.util.*;\nimport java.util.regex.Matcher;\nimport java.ut"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/Uploader.java",
    "chars": 28872,
    "preview": "package com.cloudinary;\n\nimport com.cloudinary.strategies.AbstractUploaderStrategy;\nimport com.cloudinary.utils.ObjectUt"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/Url.java",
    "chars": 27570,
    "preview": "package com.cloudinary;\n\nimport java.io.UnsupportedEncodingException;\nimport java.net.MalformedURLException;\nimport java"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/Util.java",
    "chars": 20368,
    "preview": "package com.cloudinary;\n\nimport com.cloudinary.utils.ObjectUtils;\nimport com.cloudinary.utils.StringUtils;\nimport org.cl"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/api/ApiResponse.java",
    "chars": 276,
    "preview": "package com.cloudinary.api;\n\nimport java.text.ParseException;\nimport java.util.Map;\n\n@SuppressWarnings(\"rawtypes\")\npubli"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/api/AuthorizationRequired.java",
    "chars": 293,
    "preview": "package com.cloudinary.api;\n\nimport com.cloudinary.api.exceptions.ApiException;\n\npublic class AuthorizationRequired exte"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/api/RateLimit.java",
    "chars": 642,
    "preview": "package com.cloudinary.api;\n\nimport java.util.Date;\n\npublic class RateLimit {\n    private long limit = 0L;\n    private l"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/api/exceptions/AlreadyExists.java",
    "chars": 235,
    "preview": "package com.cloudinary.api.exceptions;\n\npublic class AlreadyExists extends ApiException {\n    private static final long "
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/api/exceptions/ApiException.java",
    "chars": 232,
    "preview": "package com.cloudinary.api.exceptions;\n\npublic class ApiException extends Exception {\n    private static final long seri"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/api/exceptions/BadRequest.java",
    "chars": 231,
    "preview": "package com.cloudinary.api.exceptions;\n\n\npublic class BadRequest extends ApiException {\n    private static final long se"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/api/exceptions/GeneralError.java",
    "chars": 234,
    "preview": "package com.cloudinary.api.exceptions;\n\npublic class GeneralError extends ApiException {\n    private static final long s"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/api/exceptions/NotAllowed.java",
    "chars": 231,
    "preview": "package com.cloudinary.api.exceptions;\n\n\npublic class NotAllowed extends ApiException {\n    private static final long se"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/api/exceptions/NotFound.java",
    "chars": 228,
    "preview": "package com.cloudinary.api.exceptions;\n\n\npublic class NotFound extends ApiException {\n    private static final long seri"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/api/exceptions/RateLimited.java",
    "chars": 235,
    "preview": "package com.cloudinary.api.exceptions;\n\n\npublic class RateLimited extends ApiException {\n    private static final long s"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/api/signing/ApiResponseSignatureVerifier.java",
    "chars": 2808,
    "preview": "package com.cloudinary.api.signing;\n\nimport com.cloudinary.SignatureAlgorithm;\nimport com.cloudinary.Util;\nimport com.cl"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/api/signing/NotificationRequestSignatureVerifier.java",
    "chars": 3591,
    "preview": "package com.cloudinary.api.signing;\n\nimport com.cloudinary.SignatureAlgorithm;\n\nimport static com.cloudinary.utils.Strin"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/api/signing/SignedPayloadValidator.java",
    "chars": 961,
    "preview": "package com.cloudinary.api.signing;\n\nimport com.cloudinary.SignatureAlgorithm;\nimport com.cloudinary.Util;\nimport com.cl"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/api/signing/package-info.java",
    "chars": 487,
    "preview": "/**\n * The package holds classes used internally to implement verification procedures of authenticity and integrity of\n "
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/metadata/DateMetadataField.java",
    "chars": 1085,
    "preview": "package com.cloudinary.metadata;\n\nimport com.cloudinary.utils.ObjectUtils;\n\nimport java.text.ParseException;\nimport java"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/metadata/EnumMetadataField.java",
    "chars": 227,
    "preview": "package com.cloudinary.metadata;\n\n/**\n * Represents a metadata field with 'Enum' type.\n */\npublic class EnumMetadataFiel"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/metadata/IntMetadataField.java",
    "chars": 235,
    "preview": "package com.cloudinary.metadata;\n\n/**\n * Represents a metadata field with 'Int' type.\n */\npublic class IntMetadataField "
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataDataSource.java",
    "chars": 1900,
    "preview": "package com.cloudinary.metadata;\n\nimport org.cloudinary.json.JSONArray;\nimport org.cloudinary.json.JSONObject;\n\nimport j"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataField.java",
    "chars": 4500,
    "preview": "package com.cloudinary.metadata;\n\nimport org.cloudinary.json.JSONObject;\n\nimport java.text.ParseException;\n\n/**\n * Repre"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataFieldType.java",
    "chars": 278,
    "preview": "package com.cloudinary.metadata;\n\n/**\n * Enum represneting all the valid field types.\n */\npublic enum MetadataFieldType "
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataRule.java",
    "chars": 1643,
    "preview": "package com.cloudinary.metadata;\n\nimport com.cloudinary.utils.ObjectUtils;\n\nimport java.util.HashMap;\nimport java.util.M"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataRuleCondition.java",
    "chars": 1479,
    "preview": "package com.cloudinary.metadata;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class MetadataRuleCondition {\n "
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataRuleResult.java",
    "chars": 1471,
    "preview": "package com.cloudinary.metadata;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class MetadataRuleResult {\n   "
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/metadata/MetadataValidation.java",
    "chars": 5459,
    "preview": "package com.cloudinary.metadata;\n\nimport com.cloudinary.utils.ObjectUtils;\nimport org.cloudinary.json.JSONArray;\nimport "
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/metadata/Restrictions.java",
    "chars": 908,
    "preview": "package com.cloudinary.metadata;\n\nimport java.util.HashMap;\n\n/**\n * Represents the restrictions metadata field.\n */\npubl"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/metadata/SetMetadataField.java",
    "chars": 260,
    "preview": "package com.cloudinary.metadata;\n\nimport java.util.List;\n\n/**\n * Represents a metadata field with 'Set' type.\n */\npublic"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/metadata/StringMetadataField.java",
    "chars": 241,
    "preview": "package com.cloudinary.metadata;\n\n/**\n * Represents a metadata field with 'String' type.\n */\npublic class StringMetadata"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/provisioning/Account.java",
    "chars": 33647,
    "preview": "package com.cloudinary.provisioning;\n\nimport com.cloudinary.Api;\nimport com.cloudinary.Cloudinary;\nimport com.cloudinary"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/provisioning/AccountConfiguration.java",
    "chars": 1383,
    "preview": "package com.cloudinary.provisioning;\n\nimport com.cloudinary.utils.StringUtils;\n\nimport java.net.URI;\n\npublic class Accou"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/strategies/AbstractApiStrategy.java",
    "chars": 681,
    "preview": "package com.cloudinary.strategies;\n\nimport com.cloudinary.Api;\nimport com.cloudinary.Api.HttpMethod;\nimport com.cloudina"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/strategies/AbstractUploaderStrategy.java",
    "chars": 4130,
    "preview": "package com.cloudinary.strategies;\n\nimport com.cloudinary.Cloudinary;\nimport com.cloudinary.ProgressCallback;\nimport com"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/strategies/StrategyLoader.java",
    "chars": 772,
    "preview": "package com.cloudinary.strategies;\n\nimport java.util.List;\n\npublic class StrategyLoader {\n\n    @SuppressWarnings(\"unchec"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/transformation/AbstractLayer.java",
    "chars": 1686,
    "preview": "package com.cloudinary.transformation;\n\nimport java.io.Serializable;\nimport java.util.ArrayList;\n\nimport com.cloudinary."
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/transformation/BaseExpression.java",
    "chars": 8002,
    "preview": "package com.cloudinary.transformation;\n\nimport com.cloudinary.Transformation;\nimport com.cloudinary.utils.ObjectUtils;\ni"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/transformation/Condition.java",
    "chars": 2205,
    "preview": "package com.cloudinary.transformation;\n\nimport com.cloudinary.Transformation;\n\n/**\n * Represents a condition for {@link "
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/transformation/Expression.java",
    "chars": 2705,
    "preview": "package com.cloudinary.transformation;\n\n/**\n * Represents a transformation parameter expression.\n */\npublic class Expres"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/transformation/FetchLayer.java",
    "chars": 569,
    "preview": "package com.cloudinary.transformation;\n\nimport com.cloudinary.utils.Base64Coder;\n\npublic class FetchLayer extends Abstra"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/transformation/Layer.java",
    "chars": 154,
    "preview": "package com.cloudinary.transformation;\n\npublic class Layer extends AbstractLayer<Layer> {\n    @Override\n    Layer getThi"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/transformation/SubtitlesLayer.java",
    "chars": 167,
    "preview": "package com.cloudinary.transformation;\n\npublic class SubtitlesLayer extends TextLayer {\n    public SubtitlesLayer() {\n  "
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/transformation/TextLayer.java",
    "chars": 7162,
    "preview": "package com.cloudinary.transformation;\n\nimport java.util.ArrayList;\nimport java.util.regex.Matcher;\nimport java.util.reg"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/utils/Analytics.java",
    "chars": 5414,
    "preview": "package com.cloudinary.utils;\n\nimport com.cloudinary.Cloudinary;\n\nimport java.util.Arrays;\nimport java.util.List;\n\npubli"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/utils/Base64Coder.java",
    "chars": 11169,
    "preview": "//Copyright 2003-2010 Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland\n//www.source-code.biz, www.inven"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/utils/Base64Map.java",
    "chars": 2449,
    "preview": "package com.cloudinary.utils;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic final class Base64Map {\n    priva"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/utils/HtmlEscape.java",
    "chars": 7737,
    "preview": "package com.cloudinary.utils;\n\n\n/**\n * HtmlEscape in Java, which is compatible with utf-8\n *\n * @author Ulrich Jensen, h"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/utils/ObjectUtils.java",
    "chars": 7435,
    "preview": "package com.cloudinary.utils;\n\nimport org.cloudinary.json.JSONArray;\nimport org.cloudinary.json.JSONException;\nimport or"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/utils/Rectangle.java",
    "chars": 359,
    "preview": "package com.cloudinary.utils;\n\nimport java.io.Serializable;\n\npublic class Rectangle implements Serializable{\n\n    public"
  },
  {
    "path": "cloudinary-core/src/main/java/com/cloudinary/utils/StringUtils.java",
    "chars": 14731,
    "preview": "package com.cloudinary.utils;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.InputStr"
  },
  {
    "path": "cloudinary-core/src/main/java/org/cloudinary/json/JSONArray.java",
    "chars": 30939,
    "preview": "package org.cloudinary.json;\n\n/*\n Copyright (c) 2002 JSON.org\n\n Permission is hereby granted, free of charge, to any per"
  },
  {
    "path": "cloudinary-core/src/main/java/org/cloudinary/json/JSONException.java",
    "chars": 1057,
    "preview": "package org.cloudinary.json;\n\n/**\n * The JSONException is thrown by the JSON.org classes when things are amiss.\n *\n * @a"
  },
  {
    "path": "cloudinary-core/src/main/java/org/cloudinary/json/JSONObject.java",
    "chars": 56311,
    "preview": "package org.cloudinary.json;\n\n/*\n Copyright (c) 2002 JSON.org\n\n Permission is hereby granted, free of charge, to any per"
  },
  {
    "path": "cloudinary-core/src/main/java/org/cloudinary/json/JSONString.java",
    "chars": 720,
    "preview": "package org.cloudinary.json;\n\n/**\n * The <code>JSONString</code> interface allows a <code>toJSONString()</code>\n * metho"
  },
  {
    "path": "cloudinary-core/src/main/java/org/cloudinary/json/JSONTokener.java",
    "chars": 13344,
    "preview": "package org.cloudinary.json;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStream;\nimp"
  },
  {
    "path": "cloudinary-core/src/test/java/com/cloudinary/AuthTokenTest.java",
    "chars": 8525,
    "preview": "package com.cloudinary;\n\nimport com.cloudinary.utils.ObjectUtils;\n\nimport org.hamcrest.CoreMatchers;\nimport org.hamcrest"
  },
  {
    "path": "cloudinary-core/src/test/java/com/cloudinary/TransformationTest.java",
    "chars": 16205,
    "preview": "package com.cloudinary;\n\nimport com.cloudinary.transformation.Condition;\nimport com.cloudinary.transformation.TextLayer;"
  },
  {
    "path": "cloudinary-core/src/test/java/com/cloudinary/UtilTest.java",
    "chars": 7612,
    "preview": "package com.cloudinary;\n\nimport com.cloudinary.utils.ObjectUtils;\nimport com.cloudinary.utils.StringUtils;\nimport org.cl"
  },
  {
    "path": "cloudinary-core/src/test/java/com/cloudinary/analytics/AnalyticsTest.java",
    "chars": 5338,
    "preview": "package com.cloudinary.analytics;\n\nimport com.cloudinary.AuthToken;\nimport com.cloudinary.Cloudinary;\nimport com.cloudin"
  },
  {
    "path": "cloudinary-core/src/test/java/com/cloudinary/api/signing/ApiResponseSignatureVerifierTest.java",
    "chars": 1235,
    "preview": "package com.cloudinary.api.signing;\n\nimport com.cloudinary.SignatureAlgorithm;\nimport org.junit.Test;\n\nimport static org"
  },
  {
    "path": "cloudinary-core/src/test/java/com/cloudinary/api/signing/NotificationRequestSignatureVerifierTest.java",
    "chars": 2610,
    "preview": "package com.cloudinary.api.signing;\n\nimport com.cloudinary.SignatureAlgorithm;\nimport org.junit.Test;\n\nimport static org"
  },
  {
    "path": "cloudinary-core/src/test/java/com/cloudinary/test/CloudinaryTest.java",
    "chars": 73719,
    "preview": "package com.cloudinary.test;\n\nimport com.cloudinary.*;\nimport com.cloudinary.transformation.*;\nimport com.cloudinary.uti"
  },
  {
    "path": "cloudinary-core/src/test/java/com/cloudinary/transformation/ExpressionTest.java",
    "chars": 5609,
    "preview": "package com.cloudinary.transformation;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.assertEquals;\nimport stat"
  },
  {
    "path": "cloudinary-core/src/test/java/com/cloudinary/transformation/LayerTest.java",
    "chars": 5576,
    "preview": "package com.cloudinary.transformation;\n\nimport com.cloudinary.Cloudinary;\nimport com.cloudinary.Transformation;\nimport o"
  },
  {
    "path": "cloudinary-http5/build.gradle",
    "chars": 983,
    "preview": "plugins {\n    id 'java-library'\n}\n\napply from: \"../java_shared.gradle\"\napply from: \"../publish.gradle\"\n\ntask ciTest( typ"
  },
  {
    "path": "cloudinary-http5/src/main/java/com/cloudinary/http5/ApiStrategy.java",
    "chars": 8108,
    "preview": "package com.cloudinary.http5;\n\n\nimport com.cloudinary.Api;\nimport com.cloudinary.api.ApiResponse;\nimport com.cloudinary."
  },
  {
    "path": "cloudinary-http5/src/main/java/com/cloudinary/http5/ApiUtils.java",
    "chars": 2766,
    "preview": "package com.cloudinary.http5;\n\nimport com.cloudinary.utils.ObjectUtils;\nimport org.apache.hc.client5.http.classic.method"
  },
  {
    "path": "cloudinary-http5/src/main/java/com/cloudinary/http5/UploaderStrategy.java",
    "chars": 7770,
    "preview": "package com.cloudinary.http5;\n\nimport com.cloudinary.ProgressCallback;\nimport com.cloudinary.Uploader;\nimport com.cloudi"
  },
  {
    "path": "cloudinary-http5/src/main/java/com/cloudinary/http5/api/Response.java",
    "chars": 2408,
    "preview": "package com.cloudinary.http5.api;\n\nimport com.cloudinary.api.ApiResponse;\nimport com.cloudinary.api.RateLimit;\nimport or"
  },
  {
    "path": "cloudinary-http5/src/test/java/com/cloudinary/test/AccountApiTest.java",
    "chars": 93,
    "preview": "package com.cloudinary.test;\n\npublic class AccountApiTest extends AbstractAccountApiTest {\n}\n"
  },
  {
    "path": "cloudinary-http5/src/test/java/com/cloudinary/test/ApiTest.java",
    "chars": 3971,
    "preview": "package com.cloudinary.test;\n\nimport com.cloudinary.Cloudinary;\nimport com.cloudinary.api.ApiResponse;\nimport com.cloudi"
  },
  {
    "path": "cloudinary-http5/src/test/java/com/cloudinary/test/ContextTest.java",
    "chars": 87,
    "preview": "package com.cloudinary.test;\n\npublic class ContextTest extends AbstractContextTest {\n\n}"
  },
  {
    "path": "cloudinary-http5/src/test/java/com/cloudinary/test/FoldersApiTest.java",
    "chars": 93,
    "preview": "package com.cloudinary.test;\n\npublic class FoldersApiTest extends AbstractFoldersApiTest {\n}\n"
  },
  {
    "path": "cloudinary-http5/src/test/java/com/cloudinary/test/SearchTest.java",
    "chars": 85,
    "preview": "package com.cloudinary.test;\n\npublic class SearchTest extends AbstractSearchTest {\n}\n"
  },
  {
    "path": "cloudinary-http5/src/test/java/com/cloudinary/test/StreamingProfilesApiTest.java",
    "chars": 155,
    "preview": "package com.cloudinary.test;\n\n/**\n * Created by amir on 25/10/2016.\n */\npublic class StreamingProfilesApiTest extends Ab"
  },
  {
    "path": "cloudinary-http5/src/test/java/com/cloudinary/test/StructuredMetadataTest.java",
    "chars": 108,
    "preview": "package com.cloudinary.test;\n\npublic class StructuredMetadataTest extends AbstractStructuredMetadataTest {\n}"
  },
  {
    "path": "cloudinary-http5/src/test/java/com/cloudinary/test/UploaderTest.java",
    "chars": 89,
    "preview": "package com.cloudinary.test;\n\npublic class UploaderTest extends AbstractUploaderTest {\n\n}"
  },
  {
    "path": "cloudinary-taglib/build.gradle",
    "chars": 906,
    "preview": "plugins {\n    id 'java-library'\n}\n\napply from: \"../java_shared.gradle\"\napply from: \"../publish.gradle\"\n\ntask ciTest( typ"
  },
  {
    "path": "cloudinary-taglib/src/main/java/com/cloudinary/Singleton.java",
    "chars": 1071,
    "preview": "package com.cloudinary;\n\n/**\n * This class contains a singleton in a generic way. This class is used by the tags to\n * r"
  },
  {
    "path": "cloudinary-taglib/src/main/java/com/cloudinary/SingletonManager.java",
    "chars": 354,
    "preview": "package com.cloudinary;\n\npublic class SingletonManager {\n\n    private Cloudinary cloudinary;\n\n    public void setCloudin"
  },
  {
    "path": "cloudinary-taglib/src/main/java/com/cloudinary/taglib/CloudinaryImageTag.java",
    "chars": 1871,
    "preview": "package com.cloudinary.taglib;\n\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport java"
  },
  {
    "path": "cloudinary-taglib/src/main/java/com/cloudinary/taglib/CloudinaryJsConfigTag.java",
    "chars": 1415,
    "preview": "package com.cloudinary.taglib;\n\nimport java.io.IOException;\n\nimport javax.servlet.jsp.JspException;\nimport javax.servlet"
  },
  {
    "path": "cloudinary-taglib/src/main/java/com/cloudinary/taglib/CloudinaryJsIncludeTag.java",
    "chars": 1607,
    "preview": "package com.cloudinary.taglib;\n\nimport com.cloudinary.Cloudinary;\nimport com.cloudinary.Singleton;\n\nimport javax.servlet"
  },
  {
    "path": "cloudinary-taglib/src/main/java/com/cloudinary/taglib/CloudinaryTransformationTag.java",
    "chars": 824,
    "preview": "package com.cloudinary.taglib;\n\nimport com.cloudinary.Transformation;\n\nimport javax.servlet.jsp.JspException;\nimport jav"
  },
  {
    "path": "cloudinary-taglib/src/main/java/com/cloudinary/taglib/CloudinaryUnsignedUploadTag.java",
    "chars": 460,
    "preview": "package com.cloudinary.taglib;\n\nimport java.util.Map;\n\nimport com.cloudinary.Uploader;\n\npublic class CloudinaryUnsignedU"
  },
  {
    "path": "cloudinary-taglib/src/main/java/com/cloudinary/taglib/CloudinaryUploadTag.java",
    "chars": 12232,
    "preview": "package com.cloudinary.taglib;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport"
  },
  {
    "path": "cloudinary-taglib/src/main/java/com/cloudinary/taglib/CloudinaryUrl.java",
    "chars": 5412,
    "preview": "package com.cloudinary.taglib;\n\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport java"
  },
  {
    "path": "cloudinary-taglib/src/main/java/com/cloudinary/taglib/CloudinaryVideoTag.java",
    "chars": 3291,
    "preview": "package com.cloudinary.taglib;\n\nimport java.io.IOException;\nimport java.util.Map;\n\nimport javax.servlet.jsp.JspException"
  },
  {
    "path": "cloudinary-taglib/src/main/resources/META-INF/cloudinary.tld",
    "chars": 18127,
    "preview": "<taglib xmlns=\"http://java.sun.com/xml/ns/j2ee\"\n        xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n        xs"
  },
  {
    "path": "cloudinary-test-common/build.gradle",
    "chars": 458,
    "preview": "plugins {\n    id 'java-library'\n}\n\napply from: \"../java_shared.gradle\"\napply from: \"../publish.gradle\"\n\ntask ciTest( typ"
  },
  {
    "path": "cloudinary-test-common/src/main/java/com/cloudinary/test/AbstractAccountApiTest.java",
    "chars": 21575,
    "preview": "package com.cloudinary.test;\n\n\nimport com.cloudinary.Cloudinary;\nimport com.cloudinary.api.ApiResponse;\nimport com.cloud"
  },
  {
    "path": "cloudinary-test-common/src/main/java/com/cloudinary/test/AbstractApiTest.java",
    "chars": 70187,
    "preview": "package com.cloudinary.test;\n\nimport com.cloudinary.*;\nimport com.cloudinary.api.ApiResponse;\nimport com.cloudinary.api."
  },
  {
    "path": "cloudinary-test-common/src/main/java/com/cloudinary/test/AbstractContextTest.java",
    "chars": 4170,
    "preview": "package com.cloudinary.test;\n\nimport com.cloudinary.Cloudinary;\nimport com.cloudinary.Transformation;\nimport com.cloudin"
  },
  {
    "path": "cloudinary-test-common/src/main/java/com/cloudinary/test/AbstractFoldersApiTest.java",
    "chars": 3872,
    "preview": "package com.cloudinary.test;\n\nimport com.cloudinary.Api;\nimport com.cloudinary.Cloudinary;\nimport com.cloudinary.api.Api"
  },
  {
    "path": "cloudinary-test-common/src/main/java/com/cloudinary/test/AbstractSearchTest.java",
    "chars": 9517,
    "preview": "package com.cloudinary.test;\n\nimport com.cloudinary.Cloudinary;\nimport com.cloudinary.Search;\nimport com.cloudinary.util"
  },
  {
    "path": "cloudinary-test-common/src/main/java/com/cloudinary/test/AbstractStreamingProfilesApiTest.java",
    "chars": 5820,
    "preview": "package com.cloudinary.test;\n\nimport com.cloudinary.Api;\nimport com.cloudinary.Cloudinary;\nimport com.cloudinary.Transfo"
  },
  {
    "path": "cloudinary-test-common/src/main/java/com/cloudinary/test/AbstractStructuredMetadataTest.java",
    "chars": 19040,
    "preview": "package com.cloudinary.test;\n\nimport com.cloudinary.Api;\nimport com.cloudinary.Cloudinary;\nimport com.cloudinary.api.Api"
  },
  {
    "path": "cloudinary-test-common/src/main/java/com/cloudinary/test/AbstractUploaderTest.java",
    "chars": 45750,
    "preview": "package com.cloudinary.test;\n\nimport com.cloudinary.*;\nimport com.cloudinary.metadata.StringMetadataField;\nimport com.cl"
  },
  {
    "path": "cloudinary-test-common/src/main/java/com/cloudinary/test/MetadataTestHelper.java",
    "chars": 904,
    "preview": "package com.cloudinary.test;\n\nimport com.cloudinary.Api;\nimport com.cloudinary.api.ApiResponse;\nimport com.cloudinary.me"
  },
  {
    "path": "cloudinary-test-common/src/main/java/com/cloudinary/test/MockableTest.java",
    "chars": 3483,
    "preview": "package com.cloudinary.test;\n\nimport com.cloudinary.Cloudinary;\nimport com.cloudinary.test.helpers.Feature;\nimport com.c"
  },
  {
    "path": "cloudinary-test-common/src/main/java/com/cloudinary/test/TimeoutTest.java",
    "chars": 114,
    "preview": "package com.cloudinary.test;\n\n/***\n * Marker interface for Junit categories.\n */\npublic interface TimeoutTest {\n}\n"
  },
  {
    "path": "cloudinary-test-common/src/main/java/com/cloudinary/test/helpers/Feature.java",
    "chars": 365,
    "preview": "package com.cloudinary.test.helpers;\n\npublic final class Feature {\n    private Feature() {}\n\n    public static final Str"
  },
  {
    "path": "cloudinary-test-common/src/main/java/com/cloudinary/test/rules/RetryRule.java",
    "chars": 1505,
    "preview": "package com.cloudinary.test.rules;\n\nimport org.junit.rules.TestRule;\nimport org.junit.runner.Description;\nimport org.jun"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "chars": 202,
    "preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dist"
  },
  {
    "path": "gradle.properties",
    "chars": 1348,
    "preview": "publishRepo=https://central.sonatype.com/\nsnapshotRepo=https://central.sonatype.com/\npublishDescription=Cloudinary is a "
  },
  {
    "path": "gradlew",
    "chars": 5296,
    "preview": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up"
  },
  {
    "path": "gradlew.bat",
    "chars": 2176,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem "
  },
  {
    "path": "java_shared.gradle",
    "chars": 874,
    "preview": "sourceCompatibility = 1.8\ntargetCompatibility = 1.8\n\njavadoc {\n    options.encoding = 'UTF-8'\n}\n\ntest {\n    testLogging."
  },
  {
    "path": "publish.gradle",
    "chars": 2446,
    "preview": "apply plugin: 'maven-publish'\napply plugin: 'signing'\n\n// Simple module-level publishing for manual upload to Central Po"
  },
  {
    "path": "samples/photo_album/META-INF/persistence.xml",
    "chars": 129,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<persistence xmlns=\"http://java.sun.com/xml/ns/persistence\" version=\"2.0\">\n\n</per"
  },
  {
    "path": "samples/photo_album/README.md",
    "chars": 2637,
    "preview": "Cloudinary Java/Spring MVC Sample Project\n=========================================\n\nA simple web application that allow"
  },
  {
    "path": "samples/photo_album/pom.xml",
    "chars": 4867,
    "preview": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n         xsi:s"
  },
  {
    "path": "samples/photo_album/src/main/java/cloudinary/controllers/PhotoController.java",
    "chars": 3994,
    "preview": "package cloudinary.controllers;\n\nimport cloudinary.lib.PhotoUploadValidator;\nimport cloudinary.models.Photo;\nimport clou"
  },
  {
    "path": "samples/photo_album/src/main/java/cloudinary/lib/PhotoUploadValidator.java",
    "chars": 729,
    "preview": "package cloudinary.lib;\n\nimport cloudinary.models.PhotoUpload;\nimport org.springframework.validation.Errors;\nimport org."
  },
  {
    "path": "samples/photo_album/src/main/java/cloudinary/models/Photo.java",
    "chars": 1160,
    "preview": "package cloudinary.models;\n\nimport com.cloudinary.StoredFile;\n\nimport javax.persistence.*;\nimport java.util.Date;\n\n@Enti"
  },
  {
    "path": "samples/photo_album/src/main/java/cloudinary/models/PhotoUpload.java",
    "chars": 1611,
    "preview": "package cloudinary.models;\n\nimport com.cloudinary.Singleton;\nimport com.cloudinary.StoredFile;\nimport com.cloudinary.Tra"
  },
  {
    "path": "samples/photo_album/src/main/java/cloudinary/repositories/PhotoRepository.java",
    "chars": 200,
    "preview": "package cloudinary.repositories;\n\nimport cloudinary.models.Photo;\nimport org.springframework.data.jpa.repository.JpaRepo"
  },
  {
    "path": "samples/photo_album/src/main/resources/META-INF/persistence.xml",
    "chars": 1026,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<persistence version=\"2.0\" xmlns=\"http://java.sun.com/xml/ns/persistence\" xmlns:x"
  },
  {
    "path": "samples/photo_album/src/main/webapp/WEB-INF/messages.properties",
    "chars": 75,
    "preview": "title.empty = Title cannot be empty\nsignature.mismatch = Signature mismatch"
  },
  {
    "path": "samples/photo_album/src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml",
    "chars": 2469,
    "preview": "<beans xmlns=\"http://www.springframework.org/schema/beans\"\r\n       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
  },
  {
    "path": "samples/photo_album/src/main/webapp/WEB-INF/pages/direct_upload_form.jsp",
    "chars": 4914,
    "preview": "<!doctype html>\n<%@taglib uri=\"http://www.springframework.org/tags\" prefix=\"spring\" %>\n<%@taglib uri=\"http://www.springf"
  },
  {
    "path": "samples/photo_album/src/main/webapp/WEB-INF/pages/photos.jsp",
    "chars": 9343,
    "preview": "<!doctype html>\r\n<%@include file=\"pre.jsp\"%>\r\n<%@taglib uri=\"http://www.springframework.org/tags\" prefix=\"spring\" %>\r\n<%"
  },
  {
    "path": "samples/photo_album/src/main/webapp/WEB-INF/pages/post.jsp",
    "chars": 23,
    "preview": "</div>\n</body>\n</html>\n"
  },
  {
    "path": "samples/photo_album/src/main/webapp/WEB-INF/pages/pre.jsp",
    "chars": 733,
    "preview": "<%@taglib uri=\"http://java.sun.com/jsp/jstl/core\" prefix=\"c\" %>\n<%@taglib uri=\"http://cloudinary.com/jsp/taglib\" prefix="
  },
  {
    "path": "samples/photo_album/src/main/webapp/WEB-INF/pages/upload.jsp",
    "chars": 1070,
    "preview": "<!doctype html>\n<%@taglib uri=\"http://www.springframework.org/tags\" prefix=\"spring\" %>\n<%@taglib uri=\"http://www.springf"
  },
  {
    "path": "samples/photo_album/src/main/webapp/WEB-INF/pages/upload_form.jsp",
    "chars": 2223,
    "preview": "<!doctype html>\n<%@taglib uri=\"http://www.springframework.org/tags\" prefix=\"spring\" %>\n<%@taglib uri=\"http://www.springf"
  },
  {
    "path": "samples/photo_album/src/main/webapp/WEB-INF/web.xml",
    "chars": 637,
    "preview": "<web-app version=\"2.4\"\r\n         xmlns=\"http://java.sun.com/xml/ns/j2ee\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-ins"
  },
  {
    "path": "samples/photo_album/src/main/webapp/assets/cloudinary_cors.html",
    "chars": 3866,
    "preview": "<!DOCTYPE HTML>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n</head>\n<body>\n  <script>\n/*\n    json2.js\n    2011-10-19\n\n    Pub"
  },
  {
    "path": "samples/photo_album/src/main/webapp/assets/javascripts/cloudinary/jquery.cloudinary.js",
    "chars": 30107,
    "preview": "/*\r\n * Cloudinary's jQuery library - v1.0.19\r\n * Copyright Cloudinary\r\n * see https://github.com/cloudinary/cloudinary_j"
  },
  {
    "path": "samples/photo_album/src/main/webapp/assets/javascripts/cloudinary/jquery.fileupload-image.js",
    "chars": 11296,
    "preview": "/*\n * jQuery File Upload Image Preview & Resize Plugin 1.2.2\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copy"
  },
  {
    "path": "samples/photo_album/src/main/webapp/assets/javascripts/cloudinary/jquery.fileupload-process.js",
    "chars": 5573,
    "preview": "/*\n * jQuery File Upload Processing Plugin 1.2.2\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2012, "
  },
  {
    "path": "samples/photo_album/src/main/webapp/assets/javascripts/cloudinary/jquery.fileupload-validate.js",
    "chars": 4019,
    "preview": "/*\n * jQuery File Upload Validation Plugin 1.1\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Se"
  },
  {
    "path": "samples/photo_album/src/main/webapp/assets/javascripts/cloudinary/jquery.fileupload.js",
    "chars": 56491,
    "preview": "/*\n * jQuery File Upload Plugin 5.31.6\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian "
  },
  {
    "path": "samples/photo_album/src/main/webapp/assets/javascripts/cloudinary/jquery.iframe-transport.js",
    "chars": 10049,
    "preview": "/*\n * jQuery Iframe Transport Plugin 1.7\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2011, Sebastia"
  },
  {
    "path": "samples/photo_album/src/main/webapp/assets/javascripts/cloudinary/jquery.ui.widget.js",
    "chars": 15324,
    "preview": "/*\n * jQuery UI Widget 1.10.3+amd\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013 jQuery Foundatio"
  },
  {
    "path": "samples/photo_album/src/main/webapp/assets/stylesheets/application.css",
    "chars": 2731,
    "preview": "body { font-family: Helvetica, Arial, sans-serif; color: #333; margin: 10px; width: 960px }\n#posterframe { position: abs"
  },
  {
    "path": "samples/photo_album_gae/META-INF/persistence.xml",
    "chars": 129,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<persistence xmlns=\"http://java.sun.com/xml/ns/persistence\" version=\"2.0\">\n\n</per"
  },
  {
    "path": "samples/photo_album_gae/README.md",
    "chars": 2219,
    "preview": "Cloudinary Java/Spring MVC Sample Project on Google AppEngine\n=========================================================="
  },
  {
    "path": "samples/photo_album_gae/nbactions.xml",
    "chars": 1624,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<actions>\n    <action>\n        <actionName>CUSTOM-appengine:devserver</actionName"
  },
  {
    "path": "samples/photo_album_gae/pom.xml",
    "chars": 6635,
    "preview": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:sc"
  },
  {
    "path": "samples/photo_album_gae/src/main/java/cloudinary/controllers/PhotoController.java",
    "chars": 3872,
    "preview": "package cloudinary.controllers;\n\nimport cloudinary.lib.PhotoUploadValidator;\nimport cloudinary.models.PhotoUpload;\nimpor"
  },
  {
    "path": "samples/photo_album_gae/src/main/java/cloudinary/lib/PhotoUploadValidator.java",
    "chars": 729,
    "preview": "package cloudinary.lib;\n\nimport cloudinary.models.PhotoUpload;\nimport org.springframework.validation.Errors;\nimport org."
  },
  {
    "path": "samples/photo_album_gae/src/main/java/cloudinary/models/PhotoUpload.java",
    "chars": 2546,
    "preview": "package cloudinary.models;\n\nimport com.cloudinary.Singleton;\nimport com.cloudinary.StoredFile;\nimport com.cloudinary.Tra"
  },
  {
    "path": "samples/photo_album_gae/src/main/java/org/esxx/js/protocol/GAEClientConnection.java",
    "chars": 7559,
    "preview": "/*\n     ESXX - The friendly ECMAscript/XML Application Server\n     Copyright (C) 2007-2010 Martin Blom <martin@blom.org>"
  },
  {
    "path": "samples/photo_album_gae/src/main/java/org/esxx/js/protocol/GAEConnectionManager.java",
    "chars": 2748,
    "preview": "/*\n     ESXX - The friendly ECMAscript/XML Application Server\n     Copyright (C) 2007-2010 Martin Blom <martin@blom.org>"
  },
  {
    "path": "samples/photo_album_gae/src/main/webapp/WEB-INF/appengine-web.xml.sample",
    "chars": 598,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<appengine-web-app xmlns=\"http://appengine.google.com/ns/1.0\">\n    <application>{"
  },
  {
    "path": "samples/photo_album_gae/src/main/webapp/WEB-INF/logging.properties",
    "chars": 457,
    "preview": "# A default java.util.logging configuration.\n# (All App Engine logging is through java.util.logging by default).\n#\n# To "
  },
  {
    "path": "samples/photo_album_gae/src/main/webapp/WEB-INF/messages.properties",
    "chars": 75,
    "preview": "title.empty = Title cannot be empty\nsignature.mismatch = Signature mismatch"
  },
  {
    "path": "samples/photo_album_gae/src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml",
    "chars": 1672,
    "preview": "<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
  },
  {
    "path": "samples/photo_album_gae/src/main/webapp/WEB-INF/pages/direct_upload_form.jsp",
    "chars": 4712,
    "preview": "<!doctype html>\n<%@taglib uri=\"http://www.springframework.org/tags\" prefix=\"spring\" %>\n<%@taglib uri=\"http://www.springf"
  },
  {
    "path": "samples/photo_album_gae/src/main/webapp/WEB-INF/pages/photos.jsp",
    "chars": 7596,
    "preview": "<!doctype html>\n<%@include file=\"pre.jsp\"%>\n<%@taglib uri=\"http://www.springframework.org/tags\" prefix=\"spring\" %>\n<%@ta"
  },
  {
    "path": "samples/photo_album_gae/src/main/webapp/WEB-INF/pages/post.jsp",
    "chars": 23,
    "preview": "</div>\n</body>\n</html>\n"
  },
  {
    "path": "samples/photo_album_gae/src/main/webapp/WEB-INF/pages/pre.jsp",
    "chars": 721,
    "preview": "<%@taglib uri=\"http://java.sun.com/jsp/jstl/core\" prefix=\"c\" %>\n<%@taglib uri=\"http://cloudinary.com/jsp/taglib\" prefix="
  },
  {
    "path": "samples/photo_album_gae/src/main/webapp/WEB-INF/pages/upload.jsp",
    "chars": 1044,
    "preview": "<!doctype html>\n<%@taglib uri=\"http://www.springframework.org/tags\" prefix=\"spring\" %>\n<%@taglib uri=\"http://www.springf"
  },
  {
    "path": "samples/photo_album_gae/src/main/webapp/WEB-INF/pages/upload_form.jsp",
    "chars": 2175,
    "preview": "<!doctype html>\n<%@taglib uri=\"http://www.springframework.org/tags\" prefix=\"spring\" %>\n<%@taglib uri=\"http://www.springf"
  },
  {
    "path": "samples/photo_album_gae/src/main/webapp/WEB-INF/web.xml",
    "chars": 620,
    "preview": "<web-app version=\"2.4\"\n         xmlns=\"http://java.sun.com/xml/ns/j2ee\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-inst"
  },
  {
    "path": "samples/photo_album_gae/src/main/webapp/assets/cloudinary_cors.html",
    "chars": 3866,
    "preview": "<!DOCTYPE HTML>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n</head>\n<body>\n  <script>\n/*\n    json2.js\n    2011-10-19\n\n    Pub"
  },
  {
    "path": "samples/photo_album_gae/src/main/webapp/assets/javascripts/cloudinary/jquery.cloudinary.js",
    "chars": 18784,
    "preview": "/*\n * Cloudinary's jQuery library - v1.0.10\n * Copyright Cloudinary\n * see https://github.com/cloudinary/cloudinary_js\n "
  },
  {
    "path": "samples/photo_album_gae/src/main/webapp/assets/javascripts/cloudinary/jquery.fileupload-image.js",
    "chars": 11296,
    "preview": "/*\n * jQuery File Upload Image Preview & Resize Plugin 1.2.2\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copy"
  },
  {
    "path": "samples/photo_album_gae/src/main/webapp/assets/javascripts/cloudinary/jquery.fileupload-process.js",
    "chars": 5573,
    "preview": "/*\n * jQuery File Upload Processing Plugin 1.2.2\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2012, "
  },
  {
    "path": "samples/photo_album_gae/src/main/webapp/assets/javascripts/cloudinary/jquery.fileupload-validate.js",
    "chars": 4019,
    "preview": "/*\n * jQuery File Upload Validation Plugin 1.1\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Se"
  },
  {
    "path": "samples/photo_album_gae/src/main/webapp/assets/javascripts/cloudinary/jquery.fileupload.js",
    "chars": 56491,
    "preview": "/*\n * jQuery File Upload Plugin 5.31.6\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian "
  },
  {
    "path": "samples/photo_album_gae/src/main/webapp/assets/javascripts/cloudinary/jquery.iframe-transport.js",
    "chars": 10049,
    "preview": "/*\n * jQuery Iframe Transport Plugin 1.7\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2011, Sebastia"
  },
  {
    "path": "samples/photo_album_gae/src/main/webapp/assets/javascripts/cloudinary/jquery.ui.widget.js",
    "chars": 15324,
    "preview": "/*\n * jQuery UI Widget 1.10.3+amd\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013 jQuery Foundatio"
  },
  {
    "path": "samples/photo_album_gae/src/main/webapp/assets/stylesheets/application.css",
    "chars": 2731,
    "preview": "body { font-family: Helvetica, Arial, sans-serif; color: #333; margin: 10px; width: 960px }\n#posterframe { position: abs"
  },
  {
    "path": "settings.gradle",
    "chars": 158,
    "preview": "rootProject.name = 'cloudinary-parent'\ninclude ':cloudinary-core'\ninclude ':cloudinary-taglib'\ninclude ':cloudinary-http"
  },
  {
    "path": "tools/update_version.sh",
    "chars": 747,
    "preview": "#!/usr/bin/env bash\nnew_version=$1\n\ncurrent_version=`grep -oP \"(?<=VERSION \\= \\\")([0-9.]+)(?=\\\")\" cloudinary-core/src/ma"
  }
]

// ... and 3 more files (download for full content)

About this extraction

This page contains the full source code of the cloudinary/cloudinary_java GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 199 files (1.2 MB), approximately 291.4k tokens, and a symbol index with 2001 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!