text:
package com.google.android.exoplayer2.testutil;

import android.app.Instrumentation;
import android.content.Context;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.extractor.PositionHolder;
import com.google.android.exoplayer2.extractor.SeekMap;
import com.google.android.exoplayer2.testutil.FakeExtractorInput.SimulatedIOException;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Random;
import junit.framework.Assert;
import org.mockito.MockitoAnnotations;

/**
 * Utility methods for tests.
 */
public class TestUtil {

  /**
   * A factory for {@link Extractor} instances.
   */
  public interface ExtractorFactory {
    Extractor create();
  }

  private static final String DUMP_EXTENSION = ".dump";
  private static final String UNKNOWN_LENGTH_EXTENSION = ".unklen" + DUMP_EXTENSION;

  private TestUtil() {}

  public static boolean sniffTestData(Extractor extractor, byte[] data)
      throws IOException, InterruptedException {
    return sniffTestData(extractor, newExtractorInput(data));
  }

  public static boolean sniffTestData(Extractor extractor, FakeExtractorInput input)
      throws IOException, InterruptedException {
    while (true) {
      try {
        return extractor.sniff(input);
      } catch (SimulatedIOException e) {
        // Ignore.
      }
    }
  }

  public static FakeExtractorOutput consumeTestData(Extractor extractor, FakeExtractorInput input,
      long timeUs) throws IOException, InterruptedException {
    return consumeTestData(extractor, input, timeUs, false);
  }

  public static FakeExtractorOutput consumeTestData(Extractor extractor, FakeExtractorInput input,
      long timeUs, boolean retryFromStartIfLive) throws IOException, InterruptedException {
    FakeExtractorOutput output = new FakeExtractorOutput();
    extractor.init(output);
    consumeTestData(extractor, input, timeUs, output, retryFromStartIfLive);
    return output;
  }

  private static void consumeTestData(Extractor extractor, FakeExtractorInput input, long timeUs,
      FakeExtractorOutput output, boolean retryFromStartIfLive)
      throws IOException, InterruptedException {
    extractor.seek(input.getPosition(), timeUs);
    PositionHolder seekPositionHolder = new PositionHolder();
    int readResult = Extractor.RESULT_CONTINUE;
    while (readResult != Extractor.RESULT_END_OF_INPUT) {
      try {
        // Extractor.read should not read seekPositionHolder.position. Set it to a value that's
        // likely to cause test failure if a read does occur.
        seekPositionHolder.position = Long.MIN_VALUE;
        readResult = extractor.read(input, seekPositionHolder);
        if (readResult == Extractor.RESULT_SEEK) {
          long seekPosition = seekPositionHolder.position;
          Assertions.checkState(0 <= seekPosition && seekPosition <= Integer.MAX_VALUE);
          input.setPosition((int) seekPosition);
        }
      } catch (SimulatedIOException e) {
        if (!retryFromStartIfLive) {
          continue;
        }
        boolean isOnDemand = input.getLength() != C.LENGTH_UNSET
            || (output.seekMap != null && output.seekMap.getDurationUs() != C.TIME_UNSET);
        if (isOnDemand) {
          continue;
        }
        input.setPosition(0);
        for (int i = 0; i < output.numberOfTracks; i++) {
          output.trackOutputs.valueAt(i).clear();
        }
        extractor.seek(0, 0);
      }
    }
  }

  public static byte[] buildTestData(int length) {
    return buildTestData(length, length);
  }

  public static byte[] buildTestData(int length, int seed) {
    return buildTestData(length, new Random(seed));
  }

  public static byte[] buildTestData(int length, Random random) {
    byte[] source = new byte[length];
    random.nextBytes(source);
    return source;
  }

  public static String buildTestString(int maxLength, Random random) {
    int length = random.nextInt(maxLength);
    StringBuilder builder = new StringBuilder(length);
    for (int i = 0; i < length; i++) {
      builder.append((char) random.nextInt());
    }
    return builder.toString();
  }

  /**
   * Converts an array of integers in the range [0, 255] into an equivalent byte array.
   *
   * @param intArray An array of integers, all of which must be in the range [0, 255].
   * @return The equivalent byte array.
   */
  public static byte[] createByteArray(int... intArray) {
    byte[] byteArray = new byte[intArray.length];
    for (int i = 0; i < byteArray.length; i++) {
      Assertions.checkState(0x00 <= intArray[i] && intArray[i] <= 0xFF);
      byteArray[i] = (byte) intArray[i];
    }
    return byteArray;
  }

  public static byte[] joinByteArrays(byte[]... byteArrays) {
    int length = 0;
    for (byte[] byteArray : byteArrays) {
      length += byteArray.length;
    }
    byte[] joined = new byte[length];
    length = 0;
    for (byte[] byteArray : byteArrays) {
      System.arraycopy(byteArray, 0, joined, length, byteArray.length);
      length += byteArray.length;
    }
    return joined;
  }

  public static void setUpMockito(InstrumentationTestCase instrumentationTestCase) {
    // Workaround for https://code.google.com/p/dexmaker/issues/detail?id=2.
    System.setProperty("dexmaker.dexcache",
        instrumentationTestCase.getInstrumentation().getTargetContext().getCacheDir().getPath());
    MockitoAnnotations.initMocks(instrumentationTestCase);
  }

  public static boolean assetExists(Instrumentation instrumentation, String fileName)
      throws IOException {
    int i = fileName.lastIndexOf('/');
    String path = i >= 0 ? fileName.substring(0, i) : "";
    String file = i >= 0 ? fileName.substring(i + 1) : fileName;
    return Arrays.asList(instrumentation.getContext().getResources().getAssets().list(path))
        .contains(file);
  }

  public static byte[] getByteArray(Instrumentation instrumentation, String fileName)
      throws IOException {
    return Util.toByteArray(getInputStream(instrumentation, fileName));
  }

  public static InputStream getInputStream(Instrumentation instrumentation, String fileName)
      throws IOException {
    return instrumentation.getContext().getResources().getAssets().open(fileName);
  }

  public static String getString(Instrumentation instrumentation, String fileName)
      throws IOException {
    return new String(getByteArray(instrumentation, fileName));
  }

  private static FakeExtractorInput newExtractorInput(byte[] data) {
    return new FakeExtractorInput.Builder().setData(data).build();
  }

  /**
   * Calls {@link #assertOutput(Extractor, String, byte[], Instrumentation, boolean, boolean,
   * boolean)} with all possible combinations of "simulate" parameters.
   *
   * @param factory An {@link ExtractorFactory} which creates instances of the {@link Extractor}
   *     class which is to be tested.
   * @param sampleFile The path to the input sample.
   * @param instrumentation To be used to load the sample file.
   * @throws IOException If reading from the input fails.
   * @throws InterruptedException If interrupted while reading from the input.
   * @see #assertOutput(Extractor, String, byte[], Instrumentation, boolean, boolean, boolean)
   */
  public static void assertOutput(ExtractorFactory factory, String sampleFile,
      Instrumentation instrumentation) throws IOException, InterruptedException {
    byte[] fileData = getByteArray(instrumentation, sampleFile);
    assertOutput(factory, sampleFile, fileData, instrumentation);
  }

  /**
   * Calls {@link #assertOutput(Extractor, String, byte[], Instrumentation, boolean, boolean,
   * boolean)} with all possible combinations of "simulate" parameters.
   *
   * @param factory An {@link ExtractorFactory} which creates instances of the {@link Extractor}
   *     class which is to be tested.
   * @param sampleFile The path to the input sample.
   * @param fileData Content of the input file.
   * @param instrumentation To be used to load the sample file.
   * @throws IOException If reading from the input fails.
   * @throws InterruptedException If interrupted while reading from the input.
   * @see #assertOutput(Extractor, String, byte[], Instrumentation, boolean, boolean, boolean)
   */
  public static void assertOutput(ExtractorFactory factory, String sampleFile, byte[] fileData,
      Instrumentation instrumentation) throws IOException, InterruptedException {
    assertOutput(factory.create(), sampleFile, fileData, instrumentation, false, false, false);
    assertOutput(factory.create(), sampleFile, fileData, instrumentation,  true, false, false);
    assertOutput(factory.create(), sampleFile, fileData, instrumentation, false,  true, false);
    assertOutput(factory.create(), sampleFile, fileData, instrumentation,  true,  true, false);
    assertOutput(factory.create(), sampleFile, fileData, instrumentation, false, false,  true);
    assertOutput(factory.create(), sampleFile, fileData, instrumentation,  true, false,  true);
    assertOutput(factory.create(), sampleFile, fileData, instrumentation, false,  true,  true);
    assertOutput(factory.create(), sampleFile, fileData, instrumentation,  true,  true,  true);
  }

  /**
   * Asserts that {@code extractor} consumes {@code sampleFile} successfully and its output equals
   * to a prerecorded output dump file with the name {@code sampleFile} + "{@value
   * #DUMP_EXTENSION}". If {@code simulateUnknownLength} is true and {@code sampleFile} + "{@value
   * #UNKNOWN_LENGTH_EXTENSION}" exists, it's preferred.
   *
   * @param extractor The {@link Extractor} to be tested.
   * @param sampleFile The path to the input sample.
   * @param fileData Content of the input file.
   * @param instrumentation To be used to load the sample file.
   * @param simulateIOErrors If true simulates IOErrors.
   * @param simulateUnknownLength If true simulates unknown input length.
   * @param simulatePartialReads If true simulates partial reads.
   * @return The {@link FakeExtractorOutput} used in the test.
   * @throws IOException If reading from the input fails.
   * @throws InterruptedException If interrupted while reading from the input.
   */
  public static FakeExtractorOutput assertOutput(Extractor extractor, String sampleFile,
      byte[] fileData, Instrumentation instrumentation, boolean simulateIOErrors,
      boolean simulateUnknownLength, boolean simulatePartialReads) throws IOException,
      InterruptedException {
    FakeExtractorInput input = new FakeExtractorInput.Builder().setData(fileData)
        .setSimulateIOErrors(simulateIOErrors)
        .setSimulateUnknownLength(simulateUnknownLength)
        .setSimulatePartialReads(simulatePartialReads).build();

    Assert.assertTrue(sniffTestData(extractor, input));
    input.resetPeekPosition();
    FakeExtractorOutput extractorOutput = consumeTestData(extractor, input, 0, true);

    if (simulateUnknownLength
        && assetExists(instrumentation, sampleFile + UNKNOWN_LENGTH_EXTENSION)) {
      extractorOutput.assertOutput(instrumentation, sampleFile + UNKNOWN_LENGTH_EXTENSION);
    } else {
      extractorOutput.assertOutput(instrumentation, sampleFile + ".0" + DUMP_EXTENSION);
    }

    SeekMap seekMap = extractorOutput.seekMap;
    if (seekMap.isSeekable()) {
      long durationUs = seekMap.getDurationUs();
      for (int j = 0; j < 4; j++) {
        long timeUs = (durationUs * j) / 3;
        long position = seekMap.getPosition(timeUs);
        input.setPosition((int) position);
        for (int i = 0; i < extractorOutput.numberOfTracks; i++) {
          extractorOutput.trackOutputs.valueAt(i).clear();
        }

        consumeTestData(extractor, input, timeUs, extractorOutput, false);
        extractorOutput.assertOutput(instrumentation, sampleFile + '.' + j + DUMP_EXTENSION);
      }
    }

    return extractorOutput;
  }

  /**
   * Calls {@link #assertThrows(Extractor, byte[], Class, boolean, boolean, boolean)} with all
   * possible combinations of "simulate" parameters.
   *
   * @param factory An {@link ExtractorFactory} which creates instances of the {@link Extractor}
   *     class which is to be tested.
   * @param sampleFile The path to the input sample.
   * @param instrumentation To be used to load the sample file.
   * @param expectedThrowable Expected {@link Throwable} class.
   * @throws IOException If reading from the input fails.
   * @throws InterruptedException If interrupted while reading from the input.
   * @see #assertThrows(Extractor, byte[], Class, boolean, boolean, boolean)
   */
  public static void assertThrows(ExtractorFactory factory, String sampleFile,
      Instrumentation instrumentation, Class<? extends Throwable> expectedThrowable)
      throws IOException, InterruptedException {
    byte[] fileData = getByteArray(instrumentation, sampleFile);
    assertThrows(factory, fileData, expectedThrowable);
  }

  /**
   * Calls {@link #assertThrows(Extractor, byte[], Class, boolean, boolean, boolean)} with all
   * possible combinations of "simulate" parameters.
   *
   * @param factory An {@link ExtractorFactory} which creates instances of the {@link Extractor}
   *     class which is to be tested.
   * @param fileData Content of the input file.
   * @param expectedThrowable Expected {@link Throwable} class.
   * @throws IOException If reading from the input fails.
   * @throws InterruptedException If interrupted while reading from the input.
   * @see #assertThrows(Extractor, byte[], Class, boolean, boolean, boolean)
   */
  public static void assertThrows(ExtractorFactory factory, byte[] fileData,
      Class<? extends Throwable> expectedThrowable) throws IOException, InterruptedException {
    assertThrows(factory.create(), fileData, expectedThrowable, false, false, false);
    assertThrows(factory.create(), fileData, expectedThrowable,  true, false, false);
    assertThrows(factory.create(), fileData, expectedThrowable, false,  true, false);
    assertThrows(factory.create(), fileData, expectedThrowable,  true,  true, false);
    assertThrows(factory.create(), fileData, expectedThrowable, false, false,  true);
    assertThrows(factory.create(), fileData, expectedThrowable,  true, false,  true);
    assertThrows(factory.create(), fileData, expectedThrowable, false,  true,  true);
    assertThrows(factory.create(), fileData, expectedThrowable,  true,  true,  true);
  }

  /**
   * Asserts {@code extractor} throws {@code expectedThrowable} while consuming {@code sampleFile}.
   *
   * @param extractor The {@link Extractor} to be tested.
   * @param fileData Content of the input file.
   * @param expectedThrowable Expected {@link Throwable} class.
   * @param simulateIOErrors If true simulates IOErrors.
   * @param simulateUnknownLength If true simulates unknown input length.
   * @param simulatePartialReads If true simulates partial reads.
   * @throws IOException If reading from the input fails.
   * @throws InterruptedException If interrupted while reading from the input.
   */
  public static void assertThrows(Extractor extractor, byte[] fileData,
      Class<? extends Throwable> expectedThrowable, boolean simulateIOErrors,
      boolean simulateUnknownLength, boolean simulatePartialReads) throws IOException,
      InterruptedException {
    FakeExtractorInput input = new FakeExtractorInput.Builder().setData(fileData)
        .setSimulateIOErrors(simulateIOErrors)
        .setSimulateUnknownLength(simulateUnknownLength)
        .setSimulatePartialReads(simulatePartialReads).build();
    try {
      consumeTestData(extractor, input, 0, true);
      throw new AssertionError(expectedThrowable.getSimpleName() + " expected but not thrown");
    } catch (Throwable throwable) {
      if (expectedThrowable.equals(throwable.getClass())) {
        return; // Pass!
      }
      throw throwable;
    }
  }

  public static void recursiveDelete(File fileOrDirectory) {
    if (fileOrDirectory.isDirectory()) {
      for (File child : fileOrDirectory.listFiles()) {
        recursiveDelete(child);
      }
    }
    fileOrDirectory.delete();
  }

  /** Creates an empty folder in the application specific cache directory. */
  public static File createTempFolder(Context context) throws IOException {
    File tempFolder = File.createTempFile("ExoPlayerTest", null, context.getCacheDir());
    Assert.assertTrue(tempFolder.delete());
    Assert.assertTrue(tempFolder.mkdir());
    return tempFolder;
  }

}


text:
package de.wellenvogel.avnav.charts;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
import android.os.ParcelFileDescriptor;
import android.support.v4.provider.DocumentFile;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import de.wellenvogel.avnav.appapi.DirectoryRequestHandler;
import de.wellenvogel.avnav.appapi.ExtendedWebResourceResponse;
import de.wellenvogel.avnav.appapi.INavRequestHandler;
import de.wellenvogel.avnav.appapi.PostVars;
import de.wellenvogel.avnav.appapi.RequestHandler;
import de.wellenvogel.avnav.main.Constants;
import de.wellenvogel.avnav.util.AvnLog;
import de.wellenvogel.avnav.util.AvnUtil;

import static de.wellenvogel.avnav.charts.Chart.CFG_EXTENSION;
import static de.wellenvogel.avnav.main.Constants.CHARTOVERVIEW;
import static de.wellenvogel.avnav.main.Constants.CHARTPREFIX;
import static de.wellenvogel.avnav.main.Constants.DEMOCHARTS;
import static de.wellenvogel.avnav.main.Constants.REALCHARTS;

public class ChartHandler implements INavRequestHandler {
    private static final String GEMFEXTENSION =".gemf";
    private static final String MBTILESEXTENSION =".mbtiles";
    private static final String XMLEXTENSION=".xml";
    private static final String TYPE_GEMF="gemf";
    private static final String TYPE_MBTILES="mbtiles";
    private static final String TYPE_XML="xml";
    public static final String INDEX_INTERNAL = "1";
    public static final String INDEX_EXTERNAL = "2";
    private static final String DEFAULT_CFG="default.cfg";
    private static final long MAX_CONFIG_SIZE=100000;
    private Context context;
    private RequestHandler handler;
    //mapping of url name to char descriptors
    private HashMap<String, Chart> chartList =new HashMap<String, Chart>();
    private boolean isStopped=false;

    public ChartHandler(Context a, RequestHandler h){
        handler=h;
        context =a;

    }

    public void stop(){
        isStopped=true;
    }

    /**
     * create the name part for the content provider uri
     * @param fileName
     * @param url charts/charts/index/type/name/
     *            this is created by {@link Chart#toJson()}
     * @return basically the same url after some checks
     */
    public static String uriPath(String fileName, String url) throws Exception {
        if (url == null) return null;
        KeyAndParts kp=urlToKey(url,true);
        return CHARTPREFIX+"/"+REALCHARTS+"/"+kp.originalParts[2]+"/"+kp.originalParts[3]+"/"+DirectoryRequestHandler.safeName(kp.originalParts[4],true);
    }

    /**
     * open a file for download
     * @param uriPart - corresponds to the path we returned from {@link #uriPath(String, String)}
     *                chart/index/type/name/
     *                it is the same like the url returned by {@link Chart#toJson()}
     * @return
     */
    public static ParcelFileDescriptor getFileFromUri(String uriPart, Context ctx) throws Exception {
        if (uriPart == null) return null;
        KeyAndParts kp=urlToKey(uriPart,true);
        if (kp.originalParts[2].equals(INDEX_INTERNAL)){
            File chartBase=getInternalChartsDir(ctx);
            File chartFile=new File(chartBase,DirectoryRequestHandler.safeName(URLDecoder.decode(kp.originalParts[4],"UTF-8"),true));
            if (!chartFile.exists() || ! chartFile.canRead()) return null;
            return ParcelFileDescriptor.open(chartFile,ParcelFileDescriptor.MODE_READ_ONLY);
        }
        if (kp.originalParts[2].equals(INDEX_EXTERNAL)){
            String secondChartDirStr=AvnUtil.getSharedPreferences(ctx).getString(Constants.CHARTDIR,"");
            if (secondChartDirStr.isEmpty()) return null;
            if (!secondChartDirStr.startsWith("content:")) return null;
            DocumentFile dirFile=DocumentFile.fromTreeUri(ctx,Uri.parse(secondChartDirStr));
            DocumentFile chartFile=dirFile.findFile(DirectoryRequestHandler.safeName(URLDecoder.decode(kp.originalParts[4],"UTF-8"),true));
            if (chartFile == null) return null;
            return ctx.getContentResolver().openFileDescriptor(chartFile.getUri(),"r");
        }
        return null;
    }

    public void updateChartList(){
        HashMap<String, Chart> newGemfFiles=new HashMap<String, Chart>();
        SharedPreferences prefs=AvnUtil.getSharedPreferences(context);
        File workDir=AvnUtil.getWorkDir(prefs, context);
        File chartDir = getInternalChartsDir(context);
        readChartDir(chartDir.getAbsolutePath(), INDEX_INTERNAL,newGemfFiles);
        String secondChartDirStr=prefs.getString(Constants.CHARTDIR,"");
        if (! secondChartDirStr.isEmpty()){
            if (! secondChartDirStr.equals(workDir.getAbsolutePath())){
                readChartDir(secondChartDirStr, INDEX_EXTERNAL,newGemfFiles);
            }
        }
        if (handler.getSharedPreferences().getBoolean(Constants.SHOWDEMO,false)) {
            try {
                for (String demo : context.getAssets().list("charts")) {
                    if (!demo.endsWith(".xml")) continue;
                    String name = demo.replaceAll("\\.xml$", "");
                    DemoChart demoChart = new DemoChart(name, context);
                    newGemfFiles.put(demoChart.getChartKey(),demoChart);
                }
            }catch(Exception e){
                AvnLog.e("error when adding demo charts",e);
            }
        }
        boolean modified = false;
        final ArrayList<Chart> modifiedCharts=new ArrayList<>();
        synchronized (this) {
            //now we have all current charts - compare to the existing list and create/delete entries
            //currently we assume only one thread to change the chartlist...
            for (String url : newGemfFiles.keySet()) {
                Chart chart = newGemfFiles.get(url);
                long lastModified = chart.getLastModified();
                if (chartList.get(url) == null) {
                    chartList.put(url, chart);
                    modifiedCharts.add(chart);
                    modified = true;
                } else {
                    if (chartList.get(url).getLastModified() < lastModified) {
                        modified = true;
                        chartList.get(url).close();
                        chartList.put(url, chart);
                        modifiedCharts.add(chart);
                    }
                }
            }

            Iterator<String> it = chartList.keySet().iterator();
            while (it.hasNext()) {
                String url = it.next();
                if (newGemfFiles.get(url) == null) {
                    it.remove();
                    modified = true;
                } else {
                    Chart chart = chartList.get(url);
                    if (chart.closeInactive()) {
                        AvnLog.i("closing gemf file " + url);
                        modified = true;
                    }
                }
            }
        }
        if (modified){
            context.sendBroadcast(new Intent(Constants.BC_RELOAD_DATA));
            Thread overviewCreator=new Thread(new Runnable() {
                @Override
                public void run() {
                    AvnLog.i("creating chart overviews");
                    boolean readAgain=false;
                    for (Chart chart :modifiedCharts){
                        try{
                            chart.computeOverview();
                        }catch (Throwable t){
                            AvnLog.e("error computing chart overview, deleting "+t);
                            if (chart.canDelete()){
                                try{
                                    chart.deleteFile();
                                    readAgain=true;
                                }catch (Throwable tdel){
                                    AvnLog.e("error deleting chart ",tdel);
                                }
                            }
                        }
                        if (isStopped) break;
                    }
                    AvnLog.i("done creating chart overviews");
                    if (readAgain){
                        AvnLog.i("errors when creating chart overview, files have been deleted - read again");
                        updateChartList();
                    }
                }
            });
            overviewCreator.setDaemon(true);
            overviewCreator.start();
        }
    }

    public Chart getChartDescription(String url){
        return chartList.get(url);
    }
    public Chart getChartDescriptionByChartKey(String key){
        if (key == null) return null;
        //we rely on the the key (url) being the same as our chart key
        return chartList.get(key);
    }

    private void readChartDir(String chartDirStr,String index,HashMap<String, Chart> arr) {
        if (chartDirStr == null) return;
        if (Build.VERSION.SDK_INT >= 21) {
            if (chartDirStr.startsWith("content:")) {
                //see https://github.com/googlesamples/android-DirectorySelection/blob/master/Application/src/main/java/com/example/android/directoryselection/DirectorySelectionFragment.java
                //and https://stackoverflow.com/questions/36862675/android-sd-card-write-permission-using-saf-storage-access-framework
                Uri dirUri = Uri.parse(chartDirStr);
                DocumentFile dirFile=DocumentFile.fromTreeUri(context,dirUri);
                for (DocumentFile f : dirFile.listFiles()){
                    try {
                        if (f.getName().endsWith(GEMFEXTENSION)) {
                            String urlName = Constants.REALCHARTS + "/" + index + "/"+TYPE_GEMF+"/" + URLEncoder.encode(f.getName(), "UTF-8");
                            arr.put(urlName, new Chart(Chart.TYPE_GEMF, context, f, urlName, f.lastModified()));
                            AvnLog.d(Constants.LOGPRFX, "readCharts: adding gemf url " + urlName + " for " + f.getUri());
                        }
                        if (f.getName().endsWith(MBTILESEXTENSION)){
                            //we cannot handle this!
                            AvnLog.e("unable to read mbtiles from external dir: "+f.getName());
                        }
                        if (f.getName().endsWith(XMLEXTENSION)) {
                            String name = f.getName();
                            String urlName = Constants.REALCHARTS + "/" + index + "/"+TYPE_XML+"/" + URLEncoder.encode(name, "UTF-8");
                            Chart newChart = new Chart(Chart.TYPE_XML, context, f, urlName, f.lastModified());
                            arr.put(urlName, newChart);
                            AvnLog.d(Constants.LOGPRFX, "readCharts: adding xml url " + urlName + " for " + f.getUri());
                        }
                    }catch (Throwable t){
                        AvnLog.e("unable to handle chart "+f.getName()+": "+t.getLocalizedMessage());
                    }
                }
                return;
            }
        }
        File chartDir=new File(chartDirStr);
        if (! chartDir.isDirectory()) return;
        File[] files=chartDir.listFiles();
        if (files == null) return;
        for (File f : files) {
            if (f.getName().startsWith(DirectoryRequestHandler.TMP_PRFX)) continue;
            try {
                if (f.getName().endsWith(GEMFEXTENSION)){
                    String gemfName = f.getName();
                    String urlName= Constants.REALCHARTS + "/"+index+"/"+TYPE_GEMF+"/" + URLEncoder.encode(gemfName,"UTF-8");
                    arr.put(urlName,new Chart(Chart.TYPE_GEMF, context, f,urlName,f.lastModified()));
                    AvnLog.d(Constants.LOGPRFX,"readCharts: adding gemf url "+urlName+" for "+f.getAbsolutePath());
                }
                if (f.getName().endsWith(MBTILESEXTENSION)){
                    String name = f.getName();
                    String urlName= Constants.REALCHARTS + "/"+index+"/"+TYPE_MBTILES+"/" + URLEncoder.encode(name,"UTF-8");
                    arr.put(urlName,new Chart(Chart.TYPE_MBTILES, context, f,urlName,f.lastModified()));
                    AvnLog.d(Constants.LOGPRFX,"readCharts: adding mbtiles url "+urlName+" for "+f.getAbsolutePath());

                }
                if (f.getName().endsWith(XMLEXTENSION)){
                    String name=f.getName();
                    String urlName=Constants.REALCHARTS+"/"+index+"/"+TYPE_XML+"/"+URLEncoder.encode(name,"UTF-8");
                    Chart newChart=new Chart(Chart.TYPE_XML, context, f,urlName,f.lastModified());
                    arr.put(urlName,newChart);
                    AvnLog.d(Constants.LOGPRFX,"readCharts: adding xml url "+urlName+" for "+f.getAbsolutePath());
                }
            } catch (Exception e) {
                Log.e(Constants.LOGPRFX, "exception handling file " + f.getAbsolutePath());
            }
        }
    }

    /**
     * download chart - only works for single file charts
     * otherwise we would pick up only the first file
     * @param name - ignored
     * @param uri - we expect an url parameter that has been filled by {@link Chart#toJson()}
     *              so it has charts/charts/index/typ/name
     * @return
     * @throws Exception
     */
    @Override
    public ExtendedWebResourceResponse handleDownload(String name, Uri uri) throws Exception {
        String url=AvnUtil.getMandatoryParameter(uri,"url");
        ParcelFileDescriptor fd=getFileFromUri(url, context);
        if (fd == null) return null;
        return new ExtendedWebResourceResponse(fd.getStatSize(),
                "application/octet-stream",
                "",
                new FileInputStream(fd.getFileDescriptor()));
    }

    @Override
    public boolean handleUpload(PostVars postData, String name, boolean ignoreExisting) throws Exception {
        String safeName= DirectoryRequestHandler.safeName(name,true);
        if (! safeName.endsWith(GEMFEXTENSION) && ! safeName.endsWith(MBTILESEXTENSION)
                && ! safeName.endsWith(XMLEXTENSION) && ! safeName.endsWith(CFG_EXTENSION))
            throw new Exception("only "+GEMFEXTENSION+" or "+MBTILESEXTENSION+" or "+XMLEXTENSION+" or "+CFG_EXTENSION+" files allowed");
        File outFile=new File(getInternalChartsDir(context),safeName);
        if (postData == null) throw new Exception("no data in file");
        DirectoryRequestHandler.writeAtomic(outFile,postData.getStream(),ignoreExisting,postData.getContentLength());
        postData.closeInput();
        updateChartList();
        return true;
    }

    @Override
    public JSONArray handleList(Uri uri, RequestHandler.ServerInfo serverInfo) throws Exception {
        //here we will have more dirs in the future...
        AvnLog.i(Constants.LOGPRFX,"start chartlist request "+Thread.currentThread().getId());
        JSONArray rt=new JSONArray();
        try {
            for (String url : chartList.keySet()) {
                Chart chart = chartList.get(url);
                try {
                    rt.put(chart.toJson());
                }catch (Throwable t){
                    AvnLog.e("error reading chart "+url,t);
                }
            }
        } catch (Exception e) {
            Log.e(Constants.LOGPRFX, "exception reading chartlist:", e);
        }
        AvnLog.i(Constants.LOGPRFX,"finish chartlist request "+Thread.currentThread().getId());
        return rt;
    }

    @Override
    public boolean handleDelete(String name, Uri uri) throws Exception {
        if (name.endsWith(CFG_EXTENSION)){
            name=DirectoryRequestHandler.safeName(name,true);
            File cfgFile=new File(getInternalChartsDir(this.context),name);
            if (cfgFile.isFile()){
                return cfgFile.delete();
            }
            return false;
        }
        String charturl=AvnUtil.getMandatoryParameter(uri,"url");
        KeyAndParts kp=urlToKey(charturl,true);
        Chart chart= getChartDescription(kp.key);
        if (chart == null){
            return false;
        }
        else {
            File chartfile=chart.deleteFile();
            String cfgName=chart.getConfigName();
            File cfgFile=new File(getInternalChartsDir(this.context),cfgName);
            if (cfgFile.exists()) cfgFile.delete();
            deleteFromOverlays("chart",chart.getChartKey());
            updateChartList();
            return chartfile != null;
        }
    }

    private static void merge(JSONObject target, JSONObject source, List<String> blacklist) throws JSONException {
        for (Iterator<String> it = source.keys(); it.hasNext(); ) {
            String sk = it.next();
            if (blacklist.contains(sk)) continue;
            target.put(sk,source.get(sk));
        }
    }

    /**
     * delete an entry from the overlay configs
     * @param type
     * @param name
     */
    public int deleteFromOverlays(String type, String name){
        int numChanges=0;
        if (type == null || name == null) return numChanges;
        File baseDir=getInternalChartsDir(this.context);
        for (File f : baseDir.listFiles()){
            if (!f.getName().endsWith(CFG_EXTENSION)) continue;
            try{
                JSONObject config=AvnUtil.readJsonFile(f,MAX_CONFIG_SIZE);
                if (!config.has("overlays")) continue;
                JSONArray overlays=config.getJSONArray("overlays");
                JSONArray newOverlays=new JSONArray();
                boolean hasChanges=false;
                for (int i=0;i<overlays.length();i++){
                    JSONObject overlay=overlays.getJSONObject(i);
                    if (type.equals(overlay.optString("type"))) {
                        String overlayName = type.equals("chart") ? overlay.optString("chartKey") : overlay.optString("name");
                        if (name.equals(overlayName)){
                            AvnLog.d("removing overlay "+name+" from "+f.getAbsolutePath());
                            hasChanges=true;
                            continue;
                        }
                    }
                    newOverlays.put(overlay);
                }
                if (hasChanges){
                    config.put("overlays",newOverlays);
                    numChanges++;
                    DirectoryRequestHandler.writeAtomic(f,
                            new ByteArrayInputStream(config.toString(2).getBytes(StandardCharsets.UTF_8)),
                            true);
                }
            } catch(Exception e){
                AvnLog.e("error reading/updating overlay config "+f.getAbsolutePath(),e);
                continue;
            }
        }
        return numChanges;
    }
    @Override
    public JSONObject handleApiRequest(Uri uri, PostVars postData, RequestHandler.ServerInfo serverInfo) throws Exception {
        String command=AvnUtil.getMandatoryParameter(uri,"command");
        if (command.equals("scheme")){
            String scheme=AvnUtil.getMandatoryParameter(uri,"newScheme");
            String url=AvnUtil.getMandatoryParameter(uri,"url");
            KeyAndParts kp=urlToKey(url,true);
            Chart chart= getChartDescription(kp.key);
            if (chart == null){
                return RequestHandler.getErrorReturn("chart not found");
            }
            chart.setScheme(scheme);
            return RequestHandler.getReturn();
        }
        if (command.equals("getConfig")){
            String configName=DirectoryRequestHandler.safeName(AvnUtil.getMandatoryParameter(uri,"overlayConfig"),true);
            boolean expandCharts=AvnUtil.getFlagParameter(uri,"expandCharts",false);
            boolean mergeDefault=AvnUtil.getFlagParameter(uri,"mergeDefault",false);
            if (configName.equals(DEFAULT_CFG)) mergeDefault=false;
            File cfgFile=new File(getInternalChartsDir(this.context),configName);
            JSONObject localConfig=new JSONObject();
            JSONObject globalConfig=new JSONObject();
            if (cfgFile.exists()){
                try{
                    localConfig=AvnUtil.readJsonFile(cfgFile,MAX_CONFIG_SIZE);
                }
                catch (Exception e){
                    AvnLog.e("unable to read chart config "+cfgFile.getAbsolutePath(),e);
                }
            }
            localConfig.put("name",configName);
            File globalCfgFile=new File(getInternalChartsDir(this.context),DEFAULT_CFG);
            if (mergeDefault && globalCfgFile.exists()){
                try{
                    globalConfig=AvnUtil.readJsonFile(globalCfgFile,MAX_CONFIG_SIZE);
                }
                catch (Exception e){
                    AvnLog.e("unable to read default chart config "+globalCfgFile.getAbsolutePath(),e);
                }
                if (globalConfig.has("overlays")){
                    localConfig.put("defaults",globalConfig.get("overlays"));
                }
            }
            if (expandCharts){
                List<String> blackList= Arrays.asList("type", "chartKey", "opacity", "chart");
                String[] expandKeys=new String[]{"overlays","defaults"};
                for (String key : expandKeys){
                    if (! localConfig.has(key)) continue;
                    JSONArray overlays=localConfig.getJSONArray(key);
                    JSONArray newOverlays=new JSONArray();
                    for (int idx=0;idx<overlays.length();idx++){
                        JSONObject overlay=overlays.getJSONObject(idx);
                        if (overlay.has("type") && "chart".equals(overlay.getString("type"))){
                            Chart chart=getChartDescriptionByChartKey(overlay.optString("chartKey"));
                            if (chart != null){
                                merge(overlay,chart.toJson(),blackList);
                            }
                            else{
                                continue; //skip this entry in the returned list
                            }
                        }
                        newOverlays.put(overlay);
                    }
                    localConfig.put(key,newOverlays);
                }
            }
            JSONObject rt=new JSONObject();
            rt.put("status","OK");
            rt.put("data",localConfig);
            return rt;
        }
        if (command.equals("listOverlays")){
           JSONArray rt=new JSONArray();
            File baseDir=getInternalChartsDir(this.context);
            for (File f : baseDir.listFiles()) {
                if (!f.getName().endsWith(CFG_EXTENSION)) continue;
                JSONObject overlay=new JSONObject();
                overlay.put("name",f.getName());
                rt.put(overlay);
            }
            return RequestHandler.getReturn(new AvnUtil.KeyValue("data",rt));

        }
        return RequestHandler.getErrorReturn("unknown request");
    }

    @Override
    public ExtendedWebResourceResponse handleDirectRequest(Uri uri, RequestHandler handler, String method) throws Exception {
        return handleChartRequest(uri);
    }

    @Override
    public String getPrefix() {
        return CHARTPREFIX;
    }

    public static File getInternalChartsDir(Context ctx){
        File workDir=AvnUtil.getWorkDir(null,ctx);
        File chartDir = new File(workDir, "charts");
        return chartDir;
    }

    // charts/charts/index/type/name/avnav.xml|/src/z/x/y

    static class KeyAndParts{
        String key;
        String parts[];
        String originalParts[];
        boolean isDemo=false;
        KeyAndParts(String key,String parts[],int start){
            this.key=key;
            this.originalParts=parts;
            if (parts.length <= start){
                this.parts=new String[0];
            }
            else{
                this.parts=new String[parts.length-start];
                for (int i=0;i< parts.length-start;i++){
                    this.parts[i]=parts[i+start];
                }
            }
        }

    }

    /**
     * get the key and the remaining parts from the (decoded) url
     * @param url
     * @return
     * @throws Exception
     */
    private static KeyAndParts urlToKey(String url, boolean noDemo) throws Exception {
        url=url.replaceAll("^//*","");
        url=url.replaceAll("\\?.*", "");
        String parts[]=url.split("/");
        if (parts.length < 3) {
            throw new Exception("no chart url");
        }
        if (!parts[0].equals(CHARTPREFIX)){
            throw new Exception("no chart url");
        }
        if (parts[1].equals(DEMOCHARTS)){
            if (noDemo) throw new Exception("not permitted for demo charts");
            if (parts.length < 4) throw new Exception("invalid chart url");
            String key=parts[1]+"/"+parts[2];
            KeyAndParts rt=new KeyAndParts(key,parts,3);
            rt.isDemo=true;
            return rt;
        }
        if (!parts[1].equals(REALCHARTS)){
            throw new Exception("no chart url");
        }
        if (!parts[3].equals(TYPE_MBTILES) && ! parts[3].equals(TYPE_GEMF) && ! parts[3].equals(TYPE_XML))
            throw new Exception("invalid chart type "+parts[3]);
        if (!parts[2].equals(INDEX_EXTERNAL) && ! parts[2].equals(INDEX_INTERNAL))
            throw new Exception("invalid chart index "+parts[2]);
        if (parts.length < 5) throw new Exception("invalid chart request " + url);
        //the name is url encoded in the key
        String key=parts[1]+"/"+parts[2]+"/"+parts[3]+"/"+parts[4];
        return new KeyAndParts(key,parts,5);
    }

    private ExtendedWebResourceResponse handleChartRequest(Uri uri) throws Exception {
        String fname=uri.getPath();
        if (fname == null) return null;
        KeyAndParts kp = urlToKey(fname,false);
        try {
            Chart chart = getChartDescription(kp.key);
            if (chart == null) {
                throw new Exception("request a file that is not in the list: " + fname);
            }
            if (kp.parts[0].equals(CHARTOVERVIEW)) {
                try {
                    return chart.getOverview();
                } catch (Exception e) {
                    Log.e(Constants.LOGPRFX, "unable to read chart file " + fname + ": " + e.getLocalizedMessage());
                }
            } else if (kp.parts[0].equals("sequence")){
                JSONObject sq= RequestHandler.getReturn(new AvnUtil.KeyValue("sequence",chart.getSequence()));
                byte o[]=sq.toString().getBytes("UTF-8");
                return new ExtendedWebResourceResponse(o.length,"application/json","UTF-8",new ByteArrayInputStream(o));
            }
            else{
                if (chart.isXml()) throw new Exception("only overview for xml charts");
                if (kp.parts.length < 4) {
                    throw new Exception("invalid parameter for chart call " + fname);
                }
                int z = Integer.parseInt(kp.parts[1]);
                int x = Integer.parseInt(kp.parts[2]);
                int y = Integer.parseInt(kp.parts[3].replaceAll("\\.png", ""));
                return chart.getChartData(x, y, z, Integer.parseInt(kp.parts[0]));
            }

            Log.e(Constants.LOGPRFX, "unknown chart path " + fname);
        } catch (Exception e) {
            Log.e(Constants.LOGPRFX, "chart file " + fname + " not found: " + e.getLocalizedMessage());
        }
        return null;
    }
}

redpajama_set_name: RedPajamaGithub


text:
package org.apache.synapse.rest;

import org.apache.axis2.Constants;
import org.apache.http.protocol.HTTP;
import org.apache.synapse.ManagedLifecycle;
import org.apache.synapse.Mediator;
import org.apache.synapse.MessageContext;
import org.apache.synapse.SynapseConstants;
import org.apache.synapse.core.SynapseEnvironment;
import org.apache.synapse.core.axis2.Axis2MessageContext;
import org.apache.synapse.rest.dispatch.DispatcherHelper;
import org.apache.synapse.rest.dispatch.RESTDispatcher;
import org.apache.synapse.rest.version.DefaultStrategy;
import org.apache.synapse.rest.version.URLBasedVersionStrategy;
import org.apache.synapse.rest.version.VersionStrategy;
import org.apache.synapse.config.xml.rest.VersionStrategyFactory;
import org.apache.synapse.transport.nhttp.NhttpConstants;

import java.util.*;

public class API extends AbstractRESTProcessor implements ManagedLifecycle {

    private String host;
    private int port = -1;
    private String context;
    private Map<String,Resource> resources = new LinkedHashMap<String,Resource>();
    private List<Handler> handlers = new ArrayList<Handler>();

    private int protocol = RESTConstants.PROTOCOL_HTTP_AND_HTTPS;

    private VersionStrategy versionStrategy = new DefaultStrategy(this);

    private String fileName;

    public API(String name, String context) {
        super(name);
        setContext(context);
    }

    public void setContext(String context) {
        if (!context.startsWith("/")) {
            handleException("API context must begin with '/' character");
        }
        this.context = RESTUtils.trimTrailingSlashes(context);
    }

    /**
     * Get the fully qualified name of this API
     *
     * @return returns the key combination for API NAME + VERSION
     */
    public String getName() {
        // check if a versioning strategy exists
        if (versionStrategy.getVersion() != null && !"".equals(versionStrategy.getVersion()) ) {
            return name + ":v" +versionStrategy.getVersion();
        }
        return name;
    }

    public int getProtocol() {
        return protocol;
    }

    public void setProtocol(int protocol) {
        this.protocol = protocol;
    }

    public String getAPIName() {
        return name;
    }

    public String getVersion(){
        return versionStrategy.getVersion();
    }

    public String getContext() {
        return context;
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public void addResource(Resource resource) {
        DispatcherHelper dispatcherHelper = resource.getDispatcherHelper();
        if (dispatcherHelper != null) {
            String mapping = dispatcherHelper.getString();
            for (Resource r : resources.values()) {
                DispatcherHelper helper = r.getDispatcherHelper();
                if (helper != null && helper.getString().equals(mapping) &&
                        resourceMatches(resource, r)) {
                    handleException("Two resources cannot have the same path mapping and methods");
                }
            }
        } else {
            for (Resource r : resources.values()) {
                DispatcherHelper helper = r.getDispatcherHelper();
                if (helper == null) {
                    handleException("Only one resource can be designated as default");
                }
            }
        }
        resources.put(resource.getName(), resource);
    }

    private boolean resourceMatches(Resource r1, Resource r2) {
        String[] methods1 = r1.getMethods();
        String[] methods2 = r2.getMethods();
        for (String m1 : methods1) {
            for (String m2 : methods2) {
                if (m1.equals(m2)) {
                    return true;
                }
            }
        }
        return false;
    }

    public Resource[] getResources() {
        return resources.values().toArray(new Resource[resources.size()]);
    }

    public void addHandler(Handler handler) {
        handlers.add(handler);
    }

    public Handler[] getHandlers() {
        return handlers.toArray(new Handler[handlers.size()]);
    }

    boolean canProcess(MessageContext synCtx) {
        if (synCtx.isResponse()) {
            String apiName = (String) synCtx.getProperty(RESTConstants.SYNAPSE_REST_API);
            String version = synCtx.getProperty(RESTConstants.SYNAPSE_REST_API_VERSION) == null ?
                             "": (String) synCtx.getProperty(RESTConstants.SYNAPSE_REST_API_VERSION);
            //if api name is not matching OR versions are different
            if (!getName().equals(apiName) || !versionStrategy.getVersion().equals(version)) {
                return false;
            }
        } else {
            String path = RESTUtils.getFullRequestPath(synCtx);
            if (!path.startsWith(context + "/") && !path.startsWith(context + "?") &&
                    !context.equals(path) && !"/".equals(context)) {
                if (log.isDebugEnabled()) {
                    log.debug("API context: " + context + " does not match request URI: " + path);
                }
                return false;
            }

            if(!versionStrategy.isMatchingVersion(synCtx)){
                return false;
            }

            org.apache.axis2.context.MessageContext msgCtx =
                    ((Axis2MessageContext) synCtx).getAxis2MessageContext();

            if (host != null || port != -1) {
                String hostHeader = getHostHeader(msgCtx);
                if (hostHeader != null) {
                    if (host != null && !host.equals(extractHostName(hostHeader))) {
                        if (log.isDebugEnabled()) {
                            log.debug("API host: " + host + " does not match host information " +
                                    "in the request: " + hostHeader);
                        }
                        return false;
                    }

                    if (port != -1 && port != extractPortNumber(hostHeader,
                            msgCtx.getIncomingTransportName())) {
                        if (log.isDebugEnabled()) {
                            log.debug("API port: " + port + " does not match port information " +
                                    "in the request: " + hostHeader);
                        }
                        return false;
                    }
                } else {
                    if (log.isDebugEnabled()) {
                        log.debug("Host information not available on the message");
                    }
                    return false;
                }
            }
            if (protocol == RESTConstants.PROTOCOL_HTTP_ONLY &&
                    !Constants.TRANSPORT_HTTP.equals(msgCtx.getIncomingTransportName())) {
                if (log.isDebugEnabled()) {
                    log.debug("Protocol information does not match - Expected HTTP");
                }
                synCtx.setProperty(SynapseConstants.TRANSPORT_DENIED,new Boolean(true));
                synCtx.setProperty(SynapseConstants.IN_TRANSPORT,msgCtx.getTransportIn().getName());
                log.warn("Trying to access API : "+name+" on restricted transport chanel ["+msgCtx.getTransportIn().getName()+"]");
                return false;
            }

            if (protocol == RESTConstants.PROTOCOL_HTTPS_ONLY &&
                    !Constants.TRANSPORT_HTTPS.equals(msgCtx.getIncomingTransportName())) {
                if (log.isDebugEnabled()) {
                    log.debug("Protocol information does not match - Expected HTTPS");
                }
                synCtx.setProperty(SynapseConstants.TRANSPORT_DENIED,new Boolean(true));
                synCtx.setProperty(SynapseConstants.IN_TRANSPORT,msgCtx.getTransportIn().getName());
                log.warn("Trying to access API : "+name+" on restricted transport chanel ["+msgCtx.getTransportIn().getName()+"]");
                return false;
            }
        }

        return true;
    }

    void process(MessageContext synCtx) {
        if (log.isDebugEnabled()) {
            log.debug("Processing message with ID: " + synCtx.getMessageID() + " through the " +
                    "API: " + name);
        }

        synCtx.setProperty(RESTConstants.SYNAPSE_REST_API, getName());
        synCtx.setProperty(RESTConstants.SYNAPSE_REST_API_VERSION, versionStrategy.getVersion());
        synCtx.setProperty(RESTConstants.REST_API_CONTEXT, context);
        synCtx.setProperty(RESTConstants.SYNAPSE_REST_API_VERSION_STRATEGY, versionStrategy.getVersionType());

        // Calculate REST_URL_POSTFIX from full request path
        String restURLPostfix = (String) synCtx.getProperty(RESTConstants.REST_FULL_REQUEST_PATH);
        if (!synCtx.isResponse() && restURLPostfix != null) {  // Skip for response path
            if (!restURLPostfix.startsWith("/")) {
				restURLPostfix = "/" + restURLPostfix;
			}
			if (restURLPostfix.startsWith(context)) {
				restURLPostfix = restURLPostfix.substring(context.length());
			}
			if (versionStrategy instanceof URLBasedVersionStrategy) {
				String version = versionStrategy.getVersion();
				if (restURLPostfix.startsWith(version)) {
					restURLPostfix = restURLPostfix.substring(version.length());
				} else if (restURLPostfix.startsWith("/" + version)) {
					restURLPostfix = restURLPostfix.substring(version.length() + 1);
				}
			}
			((Axis2MessageContext) synCtx).getAxis2MessageContext().
							setProperty(NhttpConstants.REST_URL_POSTFIX,restURLPostfix);
		}

        for (Handler handler : handlers) {
            if (log.isDebugEnabled()) {
                log.debug("Processing message with ID: " + synCtx.getMessageID() + " through " +
                        "handler: " + handler.getClass().getName());
            }

            boolean proceed;
            if (synCtx.isResponse()) {
                proceed = handler.handleResponse(synCtx);
            } else {
                proceed = handler.handleRequest(synCtx);
            }

            if (!proceed) {
                return;
            }
        }

        if (synCtx.isResponse()) {
            String resourceName = (String) synCtx.getProperty(RESTConstants.SYNAPSE_RESOURCE);
            if (resourceName != null) {
                Resource resource = resources.get(resourceName);
                if (resource != null) {
                    resource.process(synCtx);
                }
            } else if (log.isDebugEnabled()) {
                log.debug("No resource information on the response: " + synCtx.getMessageID());
            }
            return;
        }

        String path = RESTUtils.getFullRequestPath(synCtx);
        String subPath;
        if (versionStrategy.getVersionType().equals(VersionStrategyFactory.TYPE_URL)) {
            //for URL based
            //request --> http://{host:port}/context/version/path/to/resource
            subPath = path.substring(context.length() + versionStrategy.getVersion().length() + 1);
        } else {
            subPath = path.substring(context.length());
        }
        if ("".equals(subPath)) {
            subPath = "/";
        }
        synCtx.setProperty(RESTConstants.REST_SUB_REQUEST_PATH, subPath);

        org.apache.axis2.context.MessageContext msgCtx =
                        ((Axis2MessageContext) synCtx).getAxis2MessageContext();
        String hostHeader = getHostHeader(msgCtx);
        if (hostHeader != null) {
            synCtx.setProperty(RESTConstants.REST_URL_PREFIX,
                    msgCtx.getIncomingTransportName() + "://" + hostHeader);
        }

        Set<Resource> acceptableResources = new HashSet<Resource>();
        for (Resource r : resources.values()) {
            if (r.canProcess(synCtx)) {
                acceptableResources.add(r);
            }
        }

        boolean processed = false;
        if (!acceptableResources.isEmpty()) {
            for (RESTDispatcher dispatcher : RESTUtils.getDispatchers()) {
                Resource resource = dispatcher.findResource(synCtx, acceptableResources);
                if (resource != null) {
                    resource.process(synCtx);
                    processed = true;
                    break;
                }
            }
        }

        if (!processed) {
            if (log.isDebugEnabled()) {
                log.debug("No matching resource was found for the request: " + synCtx.getMessageID());
            }

            Mediator sequence = synCtx.getSequence(RESTConstants.NO_MATCHING_RESOURCE_HANDLER);
            if (sequence != null) {
                sequence.mediate(synCtx);
            }
        }
    }

    private String getHostHeader(org.apache.axis2.context.MessageContext msgCtx) {
        Map transportHeaders = (Map) msgCtx.getProperty(
                org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
        String hostHeader = null;
        if (transportHeaders != null) {
            hostHeader = (String) transportHeaders.get(HTTP.TARGET_HOST);
        }

        if (hostHeader == null) {
            hostHeader = (String) msgCtx.getProperty(NhttpConstants.SERVICE_PREFIX);
        }
        return hostHeader;
    }

    private String extractHostName(String hostHeader) {
        int index = hostHeader.indexOf(':');
        if (index != -1) {
            return hostHeader.substring(0, index);
        } else {
            return hostHeader;
        }
    }

    private int extractPortNumber(String hostHeader, String transport) {
        int index = hostHeader.indexOf(':');
        if (index != -1) {
            return Integer.parseInt(hostHeader.substring(index + 1));
        } else if (Constants.TRANSPORT_HTTP.equals(transport)) {
            return 80;
        } else {
            return 443;
        }
    }

    public void init(SynapseEnvironment se) {
        if (resources.isEmpty()) {
            handleException("The API: " + getName() + " has been configured without " +
                    "any resource definitions");
        }

        log.info("Initializing API: " + getName());
        for (Resource resource : resources.values()) {
            resource.init(se);
        }

        for (Handler handler : handlers) {
            if (handler instanceof ManagedLifecycle) {
                ((ManagedLifecycle) handler).init(se);
            }
        }
    }

    public void destroy() {
        log.info("Destroying API: " + getName());
        for (Resource resource : resources.values()) {
            resource.destroy();
        }

        for (Handler handler : handlers) {
            if (handler instanceof ManagedLifecycle) {
                ((ManagedLifecycle) handler).destroy();
            }
        }
    }

    public VersionStrategy getVersionStrategy() {
        return versionStrategy;
    }

    public void setVersionStrategy(VersionStrategy versionStrategy) {
        this.versionStrategy = versionStrategy;
    }

    public Resource getResource(String resourceName) {
        return resources.get(resourceName);
    }
}


text:
<!doctype html>

    <meta charset="UTF-8"/>
    <title>DOCX To TEI Conversion</title>

    <link rel="stylesheet" href="bootstrap-3.3.5/css/bootstrap.css"/>
    <link rel="stylesheet" href="css/myapp.css"/>

loading...

DOCX to TEI Conversion Webapplication

Main

Help

Impressum


text:
<?php

namespace Magento\Backend\Cron;

/**
 * Backend event observer
 */
class CleanCache
{
    /**
     * @var \Magento\Framework\App\Cache\Frontend\Pool
     */
    private $cacheFrontendPool;

    /**
     * @param \Magento\Framework\App\Cache\Frontend\Pool $cacheFrontendPool
     */
    public function __construct(
        \Magento\Framework\App\Cache\Frontend\Pool $cacheFrontendPool
    ) {
        $this->cacheFrontendPool = $cacheFrontendPool;
    }

    /**
     * Cron job method to clean old cache resources
     *
     * @return void
     */
    public function execute()
    {
        /** @var $cacheFrontend \Magento\Framework\Cache\FrontendInterface */
        foreach ($this->cacheFrontendPool as $cacheFrontend) {
            // Magento cache frontend does not support the 'old' cleaning mode, that's why backend is used directly
            $cacheFrontend->getBackend()->clean(\Zend_Cache::CLEANING_MODE_OLD);
        }
    }
}


text:
#ifndef GLOBUS_INCLUDE_OPENSSL_ERROR_H
#define GLOBUS_INCLUDE_OPENSSL_ERROR_H

/**
 * @file globus_error_openssl.h
 * @brief Globus Generic Error
 */
#ifndef GLOBUS_GLOBAL_DOCUMENT_SET
/**
 * @mainpage Globus OpenSSL Error API
 * @copydoc globus_openssl_error_api
 */
#endif
/**
 * @defgroup globus_openssl_error_api Globus OpenSSL Error API
 *
 * The globus_gsi_openssl_error functions provide a wrapper to error
 * types defined by OpenSSL. The types and prototypes for the
 * globus_gsi_openssl_error library are defined in the
 * globus_error_openssl.h header. Applications which use these functions
 * must link with the libglobus_openssl_error library. The library is
 * distributed with a pkg-config module called globus-gsi-openssl-error
 * to automatically find header and library paths.
 *
 * @section globus_gsi_openssl_error_activation_section Library Initialization
 * @copydoc globus_gsi_openssl_error_activation
 * @section globus_openssl_error_object_section Error Object Data Definition
 * @copydoc globus_openssl_error_object
 * @section globus_openssl_error_utility_section Error Object Manipulators
 * @copydoc globus_openssl_error_utility
 */

#include "globus_common.h"
#include "globus_error_generic.h"
#include "openssl/err.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 @defgroup globus_gsi_openssl_error_activation Activation
 @ingroup globus_openssl_error_api

 Globus GSI OpenSSL Error uses standard Globus module activation and
 deactivation. Before any Globus GSI OpenSSL Error functions are called, the
 following function must be called:

 @code
      globus_module_activate(GLOBUS_GSI_OPENSSL_ERROR_MODULE)
 @endcode

 This function returns GLOBUS_SUCCESS if Globus GSI OpenSSL Error was
 successfully initialized, and you are therefore allowed to
 subsequently call Globus GSI OpenSSL Error functions.  Otherwise, an error
 code is returned, and Globus GSI OpenSSL Error functions should not be
 subsequently called. This function may be called multiple times.

 To deactivate Globus GSI OpenSSL Error, the
 following function must be called:

 @code
    globus_module_deactivate(GLOBUS_GSI_OPENSSL_ERROR_MODULE)
 @endcode

 This function should be called once for each time Globus GSI OpenSSL Error
 was activated.
 */

/** Module descriptor
 * @ingroup globus_gsi_openssl_error_activation
 * @hideinitializer
 */
#define GLOBUS_GSI_OPENSSL_ERROR_MODULE (&globus_i_gsi_openssl_error_module)

extern
globus_module_descriptor_t		globus_i_gsi_openssl_error_module;

/** Error type definition
 * @ingroup globus_openssl_error_object
 * @hideinitializer
 */
#define GLOBUS_ERROR_TYPE_OPENSSL \
                                (&GLOBUS_ERROR_TYPE_OPENSSL_DEFINITION)

extern const globus_object_type_t GLOBUS_ERROR_TYPE_OPENSSL_DEFINITION;

#define _GOESL(s) globus_common_i18n_get_string(\
		GLOBUS_GSI_OPENSSL_ERROR_MODULE, \
		s)
/**
 * @defgroup globus_openssl_error_object Globus OpenSSL Error Object
 * @ingroup globus_openssl_error_api
 *
 * The globus_openssl_error_handle_t is an opaque structure pointer which
 * contains information about the OpenSSL call which generated an error. The
 * functions in the @link globus_openssl_error_object Globus OpenSSL Error Object @endlink section of
 * the API are used to create, manipulate, and destroy Globus
 * OpenSSL Error object data.
 */

typedef struct globus_l_openssl_error_handle_s *
                                        globus_openssl_error_handle_t;

unsigned long
globus_openssl_error_handle_get_error_code(
    globus_openssl_error_handle_t       error_code);

const char *
globus_openssl_error_handle_get_filename(
    globus_openssl_error_handle_t       handle);

int
globus_openssl_error_handle_get_linenumber(
    globus_openssl_error_handle_t       handle);

const char *
globus_openssl_error_handle_get_library(
    globus_openssl_error_handle_t       handle);

const char *
globus_openssl_error_handle_get_function(
    globus_openssl_error_handle_t       handle);

const char *
globus_openssl_error_handle_get_reason(
    globus_openssl_error_handle_t       handle);

const char *
globus_openssl_error_handle_get_data(
    globus_openssl_error_handle_t       handle);

int
globus_openssl_error_handle_get_data_flags(
    globus_openssl_error_handle_t       handle);

globus_object_t *
globus_error_construct_openssl_error(
    globus_module_descriptor_t *        base_source,
    globus_object_t *                   base_cause);

globus_object_t *
globus_error_initialize_openssl_error(
    globus_object_t *                   error,
    globus_module_descriptor_t *        base_source,
    globus_object_t *                   base_cause,
    globus_openssl_error_handle_t       openssl_error_handle);

/**
 * @defgroup globus_openssl_error_utility Error Object Helper Functions
 * @ingroup globus_openssl_error_api
 *
 * The functions in the @link globus_openssl_error_utility Error Object Helper Functions @endlink section
 * deal with Globus error objects constructed with OpenSSL error data.
 * These functions manipulate the generic globus_object_t representation
 * of an OpenSSL error.
 */

globus_object_t *
globus_error_wrap_openssl_error(
    globus_module_descriptor_t *        base_source,
    int                                 error_type,
    const char *                        source_file,
    const char *                        source_func,
    int                                 source_line,
    const char *                        format,
    ...);

globus_bool_t
globus_error_match_openssl_error(
    globus_object_t *                   error,
    unsigned long                       library,
    unsigned long                       function,
    unsigned long                       reason);

const char *
globus_error_openssl_error_get_filename(
    globus_object_t *                   error);

int
globus_error_openssl_error_get_linenumber(
    globus_object_t *                   error);

const char *
globus_error_openssl_error_get_library(
    globus_object_t *                   error);

const char *
globus_error_openssl_error_get_function(
    globus_object_t *                   error);

const char *
globus_error_openssl_error_get_reason(
    globus_object_t *                   error);

const char *
globus_error_openssl_error_get_data(
    globus_object_t *                   error);

int
globus_error_openssl_error_get_data_flags(
    globus_object_t *                   error);

#ifdef __cplusplus
}
#endif

#endif /* GLOBUS_INCLUDE_OPENSSL_ERROR_H */


text:
namespace OneDrive.Api
{
    public class AuthorizationParameters
    {
        public string client_id { get; set; }
        public string client_secret { get; set; }
        public string refresh_token { get; set; }
        public string grant_type { get; set; }
        public string code { get; set; }
    }
}


text:
ActiveRecord::Schema.define(version: 20150221233100) do

  create_table "topics", force: :cascade do |t|
    t.string   "title"
    t.text     "description"
    t.datetime "created_at",  null: false
    t.datetime "updated_at",  null: false
  end

  create_table "users", force: :cascade do |t|
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true
  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true

  create_table "votes", force: :cascade do |t|
    t.integer  "topic_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

end


text:
<title>loop-iv - GNU Compiler Collection (GCC) Internals</title>
<meta http-equiv="Content-Type" content="text/html">
<meta name="description" content="GNU Compiler Collection (GCC) Internals">
<meta name="generator" content="makeinfo 4.7">
<link title="Top" rel="start" href="index.html#Top">
<link rel="up" href="Loop-Analysis-and-Representation.html#Loop-Analysis-and-Representation" title="Loop Analysis and Representation">
<link rel="prev" href="Scalar-evolutions.html#Scalar-evolutions" title="Scalar evolutions">
<link rel="next" href="Number-of-iterations.html#Number-of-iterations" title="Number of iterations">
<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">

<meta http-equiv="Content-Style-Type" content="text/css">

Next: Number of iterations,
Previous: Scalar evolutions,
Up: Loop Analysis and Representation

11.6 IV analysis on RTL

The induction variable on RTL is simple and only allows analysis of
affine induction variables, and only in one loop at once.  The interface
is declared in cfgloop.h.  Before analyzing induction variables
in a loop L, iv_analysis_loop_init function must be called on L.
After the analysis (possibly calling iv_analysis_loop_init for
several loops) is finished, iv_analysis_done should be called.
The following functions can be used to access the results of the
analysis:

iv_analyze: Analyzes a single register used in the given
insn.  If no use of the register in this insn is found, the following
insns are scanned, so that this function can be called on the insn
returned by get_condition.

iv_analyze_result: Analyzes result of the assignment in the
given insn.

iv_analyze_expr: Analyzes a more complicated expression.
All its operands are analyzed by iv_analyze, and hence they must
be used in the specified insn or one of the following insns.

The description of the induction variable is provided in struct
rtx_iv.  In order to handle subregs, the representation is a bit
complicated; if the value of the extend field is not
UNKNOWN, the value of the induction variable in the i-th
iteration is

     delta + mult * extend_{extend_mode} (subreg_{mode} (base + i * step)),

with the following exception:  if first_special is true, then the
value in the first iteration (when i is zero) is delta +
mult * base.  However, if extend is equal to UNKNOWN,
then first_special must be false, delta 0, mult 1
and the value in the i-th iteration is

     subreg_{mode} (base + i * step)

The function get_iv_value can be used to perform these
calculations.


text:
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>W29303_text</title>
        <link rel="stylesheet" type="text/css" href="style.css" />

                «

    <p class="styleSans120.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle>">PRELIMINARY DRiLLING PROGRAM 5/3/2014

Lease and Weli No. Frisco 2—31H1 MUD PROGRAM Depth Type Weight Remarks 0 ' - 2130 ' Freshwater 8.4-8.8 Add Soa Sticks for Mud Rin s 2130 ' - 6500 ' Invert 93—95 35-50 sec, 10—30 eds 6500 ' — 11076 ' invert 9.6-100 40-55 sec, 10-15 cc's ONV 70/30 to 80/20 11076 ' - TD Brine 07-105 29 Vis, No control. D Cuttin s TUBULAR PROGRAM
T .- Size Deth Feet Diameter Weiht, Grade, Connection Seamless Insection BCI & Drift _— _—_———— mm BCI & Drift —— BCI & Drift _— BCI & Drift _— BCI & Drift __ BCI & Drift _ Float shoe, shoe 'oint&floatcoliar. Centralize eve 'oint from shoe to 200' above hihest salt and eve other -___ "— ———____ — 10380 ' 10380 ' — ————___
Notes: Pipe to end up in hole from top to bottom as shown

    <p class="styleSans168.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle>">CEMENT PROGRAM
String SHOE/DV Stage Cement Cement No Cement System Cement T e Deth Lead/Tait Bottom To Sacks Yield
— 1490 '35/65 Poz/CIass"C". 3% CaCI. 12% gel
———— 11076 -_ — 11076'

Additional Comments: Continental Resources, Inc. will not use any of the below iisted diesel based compounds in the Hydraulic Stimulation ftuids of this wetl. Any compounds/fluids with the following Chemical Abstract Service Registry Numbers will not be used:
68334—30-5 (Primary Name: Fuels, diesel)
68476-34-6 (Primary Name: Fuels, diesel, No. 2)
68476-30—2 (Primary Name: Fuel oil No. 2)
68476-31-3 (Primary Name: Fuel oil, No. 4)
8008-20—6 (Primary Name: Kerosene)

    <p class="styleSans5.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle>">Frisco 2-3 AFE v1


text:
#import "EC2DescribeSubnetsResponse.h"

@implementation EC2DescribeSubnetsResponse

@synthesize subnets;

-(id)init
{
    if (self = [super init]) {
        subnets = [[NSMutableArray alloc] initWithCapacity:1];
    }

    return self;
}

-(void)setException:(AmazonServiceException *)theException
{
    AmazonServiceException *newException = nil;

    if (newException != nil) {
        [newException setPropertiesWithException:theException];
        [exception release];
        exception = newException;
    }
    else {
        [exception release];
        exception = [theException retain];
    }
}

-(EC2Subnet *)subnetsObjectAtIndex:(int)index
{
    return (EC2Subnet *)[subnets objectAtIndex:index];
}

-(NSString *)description
{
    NSMutableString *buffer = [[NSMutableString alloc] initWithCapacity:256];

    [buffer appendString:@"{"];
    [buffer appendString:[[[NSString alloc] initWithFormat:@"Subnets: %@,", subnets] autorelease]];
    [buffer appendString:[super description]];
    [buffer appendString:@"}"];

    return [buffer autorelease];
}

-(void)dealloc
{
    [subnets release];

    [super dealloc];
}

@end


text:
using System;
using System.Drawing;
using System.Runtime.InteropServices;

namespace iRobot
{
    public static class Utils
    {

        /// <summary>
        /// Converts byte aray to structure.
        /// </summary>
        /// <typeparam name="T">Type of the structure.</typeparam>
        /// <param name="bytes">Bytes for the structure.</param>
        /// <returns>Type of the structure.</returns>
        public static T ByteArrayToStructure<T>(byte[] bytes) where T : struct
        {
            var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
            var result = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
            handle.Free();
            return result;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="value"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public static byte BitSet(byte value, byte index)
        {
            return (byte)(value | (1 << index));
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="value"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public static byte BitClear(byte value, byte index)
        {
            return (byte)(value & ~(1 << index));
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="value"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public static byte BitToggle(byte value, byte index)
        {
            return (byte)(value ^ (1 << index));
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="value"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public static bool GetBit(this byte value, int index)
        {
            return (value & (1 << index)) != 0;
        }
    }
}


text:
<!DOCTYPE HTML>

<title>Test that mIsTopOfPage is not set when clearing</title>


text:
package com.nobigsoftware.dfalex;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Converts a DFA into a minimal DFA using a fast variant of Hopcroft's algorithm
 */
class DfaMinimizer<RESULT> {
    private final RawDfa<RESULT> m_origDfa;
    private final List<DfaStateInfo> m_origStates;
    private final int[] m_newStartStates;

    //map from transition target to all sources, using original state numbers
    private final int[][] m_origBackReferences;

    //for each original state, it's current partition number
    //during partitioning, partition numbers are the partition start position in m_partitionOrderStates
    //when that's done, they are contiguous ints
    private final int[] m_origOrderPartNums;

    //the original state numbers, sorted by partition number
    private final int[] m_partitionOrderStates;

    private final int[] m_origOrderHashes;
    private final int[] m_hashBuckets;
    private final int[] m_scratchSpace;
    private final int[] m_scratchPartitions;
    private final int m_hashTableSize;
    private final ArrayList<DfaStateInfo> m_minStates = new ArrayList<>();

    public DfaMinimizer(RawDfa<RESULT> dfa) {
        m_origDfa = dfa;
        m_origStates = dfa.getStates();
        m_origBackReferences = _createBackReferences();
        m_origOrderPartNums = new int[m_origStates.size()];
        m_partitionOrderStates = new int[m_origStates.size()];
        m_origOrderHashes = new int[m_origStates.size()];
        m_scratchSpace = new int[m_origStates.size()];
        m_scratchPartitions = new int[m_origStates.size()];
        m_hashTableSize = PrimeSizeFinder.findPrimeSize(m_origStates.size());
        m_hashBuckets = new int[m_hashTableSize];
        m_newStartStates = new int[m_origDfa.getStartStates().length];
        _createMinimalPartitions();
        _createNewStates();
    }

    public RawDfa<RESULT> getMinimizedDfa() {
        return new RawDfa<RESULT>(m_minStates, m_origDfa.getAcceptSets(), m_newStartStates);
    }

    private void _createNewStates() {
        m_minStates.clear();
        ArrayList<NfaTransition> m_tempTrans = new ArrayList<>();
        for (int i = 0; i < m_partitionOrderStates.length; ++i) {
            int statenum = m_partitionOrderStates[i];
            int partnum = m_origOrderPartNums[statenum];
            if (partnum < m_minStates.size()) {
                continue;
            }
            assert (partnum == m_minStates.size());

            //compress and redirect transitions
            m_tempTrans.clear();
            final DfaStateInfo instate = m_origStates.get(statenum);
            final int inlen = instate.getTransitionCount();
            int inpos = 0;
            while (inpos < inlen) {
                NfaTransition trans = instate.getTransition(inpos++);
                char startc = trans.m_firstChar;
                char endc = trans.m_lastChar;
                int dest = m_origOrderPartNums[trans.m_stateNum];
                for (; inpos < inlen; ++inpos) {
                    trans = instate.getTransition(inpos);
                    if (trans.m_firstChar - endc > 1 || m_origOrderPartNums[trans.m_stateNum] != dest) {
                        break;
                    }
                    endc = trans.m_lastChar;
                }
                m_tempTrans.add(new NfaTransition(startc, endc, dest));
            }

            m_minStates.add(new DfaStateInfo(m_tempTrans, instate.getAcceptSetIndex()));
        }

        int[] origStartStates = m_origDfa.getStartStates();
        for (int i = 0; i < m_newStartStates.length; ++i) {
            m_newStartStates[i] = m_origOrderPartNums[origStartStates[i]];
        }
    }

    private void _createMinimalPartitions() {
        if (m_partitionOrderStates.length <= 0) {
            return;
        }
        //create initial partitioning
        //States in a partition are contiguous in m_partitionOrderStates
        //m_origOrderPartNums maps from state to partition number

        //initially, we just set these up so that states with different accept
        //sets will not compare equal
        for (int i = 0; i < m_origOrderPartNums.length; ++i) {
            m_origOrderPartNums[i] = m_origStates.get(i).getAcceptSetIndex();
            m_partitionOrderStates[i] = i;
        }
        //Then we repartition the whole state set, which will set m_origOrderPartNums and
        //m_partitionOrderStates properly and do an initial partitioning by previous
        //partition (accept set) AND transitions
        _repartition(0, m_partitionOrderStates.length);

        //from now on during partitioning, partition numbers are the partition start position in m_partitionOrderStates

        //We use this queue to keep track of all partitions that might need to split.  When it's
        //empty we are done.  Note that partition numbers are stable, since they are the index
        //of the partition's first state in m_partitionOrderStates
        IntRangeClosureQueue closureQ = new IntRangeClosureQueue(m_partitionOrderStates.length);

        //Initially, all of our partitions are new and need to be checked
        for (int i = 0; i < m_partitionOrderStates.length; i++) {
            closureQ.add(m_origOrderPartNums[m_partitionOrderStates[i]]);
        }

        //split partitions as necessary until we're done
        int targetPart;
        while ((targetPart = closureQ.poll()) >= 0) {
            //find contiguous range in m_partitionOrderStates conrresponding to the target partition
            int targetEnd = targetPart + 1;
            while (targetEnd < m_partitionOrderStates.length && m_origOrderPartNums[m_partitionOrderStates[targetEnd]] == targetPart) {
                ++targetEnd;
            }
            //repartition it if necessary
            _repartition(targetPart, targetEnd);

            //queue other partitions.  Two states that were assumed to be equivalent,
            //because they had transitions into targetPart on the same character, might
            //now be recognizable as distict, because those transitions now go to different
            //partitions.
            //Any partition that transitions to two or more of our new partitions
            //needs to be queued for repartitioning

            //STEP 1: for each partition that transitions to the old target, remember
            //ONE of the new partitions it transitions to.
            for (int i = targetPart; i < targetEnd; ++i) {
                int st = m_partitionOrderStates[i];
                int partNum = m_origOrderPartNums[st]; //NEW partition number for st!
                for (int src : m_origBackReferences[st]) {
                    int srcPart = m_origOrderPartNums[src];
                    m_scratchSpace[srcPart] = partNum;
                }
            }
            //STEP 2: for each partition that transitions to the old target, see if any
            //of the new transitions it goes to are different from the one we remembered
            for (int i = targetPart; i < targetEnd; ++i) {
                int st = m_partitionOrderStates[i];
                int partNum = m_origOrderPartNums[st];
                for (int src : m_origBackReferences[st]) {
                    int srcPart = m_origOrderPartNums[src];
                    if (m_scratchSpace[srcPart] != partNum) {
                        closureQ.add(srcPart);
                    }
                }
            }
        }

        //now renumber the partitions with contiguous ints instead of start positions
        int st = m_partitionOrderStates[0];
        int prevPartIn = m_origOrderPartNums[st];
        m_origOrderPartNums[st] = 0;
        int prevPartOut = 0;
        for (int i = 1; i < m_partitionOrderStates.length; ++i) {
            st = m_partitionOrderStates[i];
            int partIn = m_origOrderPartNums[st];
            if (partIn != prevPartIn) {
                prevPartIn = partIn;
                ++prevPartOut;
            }
            m_origOrderPartNums[st] = prevPartOut;
        }
    }

    //given the start and end of a partition in m_partitionOrderStartStates, repartition it
    //into smaller partitions (equivalence classes) according to current information
    //each partition will end up with a number equal to its start position in m_partitionOrderStartStates
    private void _repartition(final int start, final int end) {
        if (end <= start) {
            return;
        }
        //hash all the states and initialize negated counts in the hash buckets
        for (int i = start; i < end; i++) {
            int state = m_partitionOrderStates[i];
            int h = _hashOrig(state);
            m_origOrderHashes[state] = h;
            int bucket = (h & Integer.MAX_VALUE) % m_hashTableSize;
            m_hashBuckets[bucket] = ~0;
        }
        //calculate negated counts
        for (int i = start; i < end; i++) {
            int state = m_partitionOrderStates[i];
            int h = m_origOrderHashes[state];
            int bucket = (h & Integer.MAX_VALUE) % m_hashTableSize;
            m_hashBuckets[bucket] -= 1;
        }
        //turn counts into start positions
        int totalLen = 0;
        for (int i = start; i < end; i++) {
            int state = m_partitionOrderStates[i];
            int h = m_origOrderHashes[state];
            int bucket = (h & Integer.MAX_VALUE) % m_hashTableSize;
            int oldVal = m_hashBuckets[bucket];
            if (oldVal < 0) {
                m_hashBuckets[bucket] = totalLen;
                totalLen += ~oldVal;
            }
        }
        assert (totalLen == end - start);
        //copy states in bucket order, turning start positions into end positions
        for (int i = start; i < end; i++) {
            int state = m_partitionOrderStates[i];
            int h = m_origOrderHashes[state];
            int bucket = (h & Integer.MAX_VALUE) % m_hashTableSize;
            int pos = m_hashBuckets[bucket]++;
            m_scratchSpace[pos] = state;
        }
        //copy bucket order back into partition order, separating different states in the same bucket
        int destpos = start;
        for (int bucketStart = 0; bucketStart < totalLen; ) {
            int state = m_scratchSpace[bucketStart];
            int hash = m_origOrderHashes[state];
            int bucket = (hash & Integer.MAX_VALUE) % m_hashTableSize;
            final int bucketEnd = m_hashBuckets[bucket];
            assert (destpos == bucketStart + start);
            m_partitionOrderStates[destpos++] = state;
            m_scratchPartitions[state] = bucketStart + start;
            int missPos = bucketStart;
            int nextPos = bucketStart + 1;
            //add equivalent states in the same bucket
            for (; nextPos < bucketEnd; ++nextPos) {
                int tempst = m_scratchSpace[nextPos];

                if (m_origOrderHashes[tempst] == hash && _compareOrig(tempst, state)) {
                    m_partitionOrderStates[destpos++] = tempst;
                    m_scratchPartitions[tempst] = bucketStart + start;
                } else {
                    m_scratchSpace[missPos++] = tempst;
                }
            }
            while (missPos > bucketStart) {
                m_scratchSpace[--nextPos] = m_scratchSpace[--missPos];
            }

            bucketStart = nextPos;
        }
        //all the counts line up and all states copied
        assert (destpos == end);

        //update partition numbers
        for (int i = start; i < end; ++i) {
            int state = m_partitionOrderStates[i];
            m_origOrderPartNums[state] = m_scratchPartitions[state];
        }
    }

    //compute back-references for all states, for m_origBackReferences
    private int[][] _createBackReferences() {
        final int nstates = m_origStates.size();
        final int[] backRefCounts = new int[m_origStates.size()];
        for (int st = 0; st < nstates; ++st) {
            m_origStates.get(st).forEachTransition(new ObjToVoid<NfaTransition>() {
                public void accept(NfaTransition trans) {
                    backRefCounts[trans.m_stateNum]++;
                }
            });
        }
        final int[][] backrefs = new int[nstates][];
        for (int st = 0; st < nstates; ++st) {
            backrefs[st] = new int[backRefCounts[st]];
            backRefCounts[st] = 0;
        }
        final int captureFix[] = new int[1]; //avoid making a new consumer for each st
        for (int st = 0; st < nstates; ++st) {
            captureFix[0] = st;
            m_origStates.get(st).forEachTransition(
                    new ObjToVoid<NfaTransition>() {
                        public void accept(NfaTransition trans) {
                            int target = trans.m_stateNum;
                            backrefs[target][backRefCounts[target]++] = captureFix[0];
                        }
                    });
        }

        //dedup
        for (int st = 0; st < nstates; ++st) {
            int[] refs = backrefs[st];
            if (refs.length < 1) {
                continue;
            }
            Arrays.sort(refs);
            int newLen = 1;
            for (int s = 1; s < refs.length; ++s) {
                if (refs[s] != refs[s - 1]) {
                    refs[newLen++] = refs[s];
                }
            }
            if (newLen != refs.length) {
                backrefs[st] = Arrays.copyOf(refs, newLen);
            }
        }

        return backrefs;
    }

    //Make a hash of the original state, using its transitions and
    //the current partition
    private int _hashOrig(int st) {
        int h = m_origOrderPartNums[st] * 5381;
        int nextc = 0;
        int prevtarget = -1;
        final DfaStateInfo info = m_origStates.get(st);
        final int len = info.getTransitionCount();
        for (int i = 0; i < len; i++) {
            NfaTransition trans = info.getTransition(i);
            int curtarget = m_origOrderPartNums[trans.m_stateNum] & 0x7FFFFFFF;
            if (trans.m_firstChar != nextc && prevtarget != -1) {
                h *= 65599;
                h += nextc;
                h *= 65599;
                prevtarget = -1;
            }
            if (curtarget != prevtarget) {
                h *= 65599;
                h += trans.m_firstChar;
                h *= 65599;
                h += curtarget + 1;
                prevtarget = curtarget;
            }
            nextc = trans.m_lastChar + 1;
        }
        if (nextc < 0x10000 && prevtarget != -1) {
            h *= 65599;
            h += nextc;
        }
        h *= 65599;
        h ^= (h >> 16);
        h ^= (h >> 8);
        h ^= (h >> 4);
        h ^= (h >> 2);
        return h;
    }

    //Compare two original states to see if they're equivalent, as far as
    //we know based on the current partitioning and transitions
    private boolean _compareOrig(int st1, int st2) {
        if (m_origOrderPartNums[st1] != m_origOrderPartNums[st2]) {
            return false;
        }
        final DfaStateInfo info1 = m_origStates.get(st1);
        final DfaStateInfo info2 = m_origStates.get(st2);
        final int len1 = info1.getTransitionCount();
        final int len2 = info2.getTransitionCount();
        if (len2 <= 0) {
            return (len1 <= 0);
        }
        if (len1 <= 0) {
            return false;
        }
        int pos1 = 1, pos2 = 1;
        NfaTransition trans1 = info1.getTransition(0);
        NfaTransition trans2 = info2.getTransition(0);
        int nextc = 0;
        for (; ; ) {
            while (trans1.m_lastChar < nextc) {
                if (pos1 >= len1) {
                    trans1 = null;
                    break;
                }
                trans1 = info1.getTransition(pos1++);
            }
            while (trans2.m_lastChar < nextc) {
                if (pos2 >= len2) {
                    trans2 = null;
                    break;
                }
                trans2 = info2.getTransition(pos2++);
            }
            if (trans1 == null || trans2 == null) {
                return trans1 == trans2;
            }
            if (trans1.m_firstChar > nextc || trans2.m_firstChar > nextc) {
                if (trans1.m_firstChar != trans2.m_firstChar) {
                    return false;
                }
                nextc = trans1.m_firstChar;
            }
            if (m_origOrderPartNums[trans1.m_stateNum] != m_origOrderPartNums[trans2.m_stateNum]) {
                return false;
            }
            nextc = Math.min(trans1.m_lastChar + 1, trans2.m_lastChar + 1);
        }
    }
}


text:
#ifndef AVDEVICE_DECKLINK_COMMON_C_H
#define AVDEVICE_DECKLINK_COMMON_C_H

typedef enum DecklinkPtsSource {
    PTS_SRC_AUDIO     = 1,
    PTS_SRC_VIDEO     = 2,
    PTS_SRC_REFERENCE = 3,
    PTS_SRC_WALLCLOCK = 4,
    PTS_SRC_ABS_WALLCLOCK = 5,
    PTS_SRC_NB
} DecklinkPtsSource;

struct decklink_cctx {
    const AVClass *cclass;

    void *ctx;

    /* Options */
    int list_devices;
    int list_formats;
    int64_t teletext_lines;
    double preroll;
    int v210;
    int audio_channels;
    int audio_depth;
    int duplex_mode;
    DecklinkPtsSource audio_pts_source;
    DecklinkPtsSource video_pts_source;
    int audio_input;
    int video_input;
    int draw_bars;
    char *format_code;
    int raw_format;
    int64_t queue_size;
    int copyts;
};

#endif /* AVDEVICE_DECKLINK_COMMON_C_H */


text:
<?xml version="1.0" encoding="utf-8"?>
<openerp>
    <data>
        <record id="view_account_chart" model="ir.ui.view">
            <field name="name">account.chart.form</field>
            <field name="model">account.chart</field>
            <field name="arch" type="xml">
                <form string="Account charts">
                    <group>
                        <label for="fiscalyear"/>
                        <div>
                            <field name="fiscalyear" on_change="onchange_fiscalyear(fiscalyear)" class="oe_inline"/>
                            <label align="0.7" string="(If you do not select a specific fiscal year, all open fiscal years will be selected.)" class="oe_inline"/>
                        </div>
                        <field name="target_move"/>
                        <label for="period_from" string="Periods"/>
                        <div>
                            <field name="period_from" class="oe_inline"/> -
                            <field name="period_to" class="oe_inline"/>
                        </div>
                    </group>
                    <footer>
                        <button string="Open Charts" name="account_chart_open_window" type="object" class="oe_highlight"/>
                        or
                        <button string="Cancel" class="oe_link" special="cancel"/>
                    </footer>
                </form>
            </field>
        </record>

        <record id="action_account_chart" model="ir.actions.act_window">
            <field name="name">Chart of Accounts</field>
            <field name="res_model">account.chart</field>
            <field name="view_type">form</field>
            <field name="view_mode">tree,form</field>
            <field name="view_id" ref="view_account_chart"/>
            <field name="target">new</field>
        </record>

        <menuitem icon="STOCK_INDENT" action="action_account_chart"
            id="menu_action_account_tree2"
            parent="account.menu_finance_charts" />
    </data>
</openerp>


text:
package com.fsck.k9.cache;

import android.content.Context;
import timber.log.Timber;

import com.fsck.k9.K9;
import com.fsck.k9.helper.FileHelper;

import java.io.File;
import java.io.IOException;

public class TemporaryAttachmentStore {
    private static String TEMPORARY_ATTACHMENT_DIRECTORY = "attachments";
    private static long MAX_FILE_AGE = 12 * 60 * 60 * 1000;   // 12h

    public static File getFile(Context context, String attachmentName) {
        File directory = getTemporaryAttachmentDirectory(context);
        String filename = FileHelper.sanitizeFilename(attachmentName);
        return new File(directory, filename);
    }

    public static File getFileForWriting(Context context, String attachmentName) throws IOException {
        File directory = createOrCleanAttachmentDirectory(context);
        String filename = FileHelper.sanitizeFilename(attachmentName);
        return new File(directory, filename);
    }

    private static File createOrCleanAttachmentDirectory(Context context) throws IOException {
        File directory = getTemporaryAttachmentDirectory(context);
        if (directory.exists()) {
            cleanOldFiles(directory);
        } else {
            if (!directory.mkdir()) {
                throw new IOException("Couldn't create temporary attachment store: " + directory.getAbsolutePath());
            }
        }
        return directory;
    }

    private static File getTemporaryAttachmentDirectory(Context context) {
        return new File(context.getExternalCacheDir(), TEMPORARY_ATTACHMENT_DIRECTORY);
    }

    private static void cleanOldFiles(File directory) {
        File[] files = directory.listFiles();
        if (files == null) {
            return;
        }

        long cutOffTime = System.currentTimeMillis() - MAX_FILE_AGE;
        for (File file : files) {
            if (file.lastModified() < cutOffTime) {
                if (file.delete()) {
                    Timber.d("Deleted from temporary attachment store: %s", file.getName());
                } else {
                    Timber.w("Couldn't delete from temporary attachment store: %s", file.getName());
                }
            }
        }
    }
}