text: /*
    ==============================================================================
  
     This file is part of the JUCE library.
     Copyright (c) 2020 - Raw Material Software Limited
  
     JUCE is an open source library subject to commercial or open-source
     licensing.
  
     The code included in this file is provided under the terms of the ISC license
     http://www.isc.org/downloads/software-support-policy/isc-license. Permission
     To use, copy, modify, and/or distribute this software for any purpose with or
     without fee is hereby granted provided that the above copyright notice and
     this permission notice appear in all copies.
  
     JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
     EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
     DISCLAIMED.
  
    ==============================================================================
  */
  
  namespace juce
  {
  
  //==============================================================================
  // This byte-code is generated from native/java/com/rmsl/juce/JuceHTTPStream.java with min sdk version 16
  // See juce_core/native/java/README.txt on how to generate this byte-code.
  static const uint8 javaJuceHttpStream[] =
  {31,139,8,8,71,116,161,94,0,3,106,97,118,97,74,117,99,101,72,116,116,112,83,116,114,101,97,109,46,100,101,120,0,125,154,11,124,
  84,87,157,199,255,231,222,185,119,30,153,153,220,76,30,147,132,60,38,33,132,4,18,38,80,104,41,9,148,242,42,144,80,40,12,84,8,
  91,29,50,23,50,48,185,19,102,238,64,168,180,133,62,233,67,75,223,184,86,173,72,45,186,85,171,86,173,182,174,109,105,93,31,181,
  85,87,119,171,187,186,186,91,171,246,211,221,118,235,171,171,31,55,251,59,143,201,76,218,44,132,239,253,255,207,255,252,207,
  185,231,241,63,143,153,36,101,79,4,250,46,88,66,151,94,114,238,181,147,179,244,212,201,205,225,159,190,152,158,247,165,219,39,
  126,178,240,215,230,173,135,207,118,18,141,19,209,196,142,197,17,82,255,94,153,67,244,35,146,246,69,224,105,157,40,14,121,194,
  67,84,15,249,148,73,116,5,228,81,47,17,178,200,19,32,90,211,68,148,130,124,171,150,232,15,224,109,240,23,240,191,64,171,35,50,
  64,8,84,129,40,232,6,23,131,45,96,27,184,18,236,6,123,128,13,174,6,215,128,227,224,102,112,27,184,19,156,2,103,192,89,240,44,
  120,5,52,70,137,150,129,171,192,13,224,19,224,155,224,87,128,161,193,49,112,17,184,28,236,5,199,192,3,224,81,240,34,120,5,188,
  13,194,13,68,237,96,0,92,9,14,128,235,193,67,224,49,240,29,240,11,240,22,240,55,18,189,7,164,193,213,224,111,193,147,224,183,
  160,102,22,234,0,87,129,163,224,195,224,39,96,18,244,96,156,222,3,70,192,94,176,31,56,32,15,222,15,142,129,59,192,73,112,15,120,
  0,124,24,124,12,124,2,60,1,158,2,223,2,63,6,63,7,175,130,55,192,159,192,95,129,209,76,20,4,81,16,3,61,96,13,216,1,70,193,213,
  224,14,240,17,240,48,120,18,156,3,47,129,87,193,95,128,217,130,62,2,11,52,130,14,48,31,44,2,23,129,77,224,111,128,3,174,5,55,
  131,7,192,25,240,37,240,60,248,30,248,103,240,91,240,22,152,4,190,86,162,58,208,9,250,193,101,96,35,216,6,222,7,246,131,195,224,
  24,56,1,238,3,31,3,15,131,207,128,47,130,175,130,23,193,207,192,107,224,45,240,103,64,49,244,29,84,130,57,160,31,236,0,123,193,
  1,48,14,14,129,163,224,102,112,18,124,12,60,12,62,11,190,1,126,12,126,6,254,29,252,26,252,25,120,219,136,102,131,62,176,18,
  108,5,123,193,24,112,193,81,112,2,124,8,60,2,62,7,190,6,190,13,126,14,126,7,244,118,196,5,104,4,237,160,23,44,7,151,129,4,200,
  128,2,184,6,220,6,238,2,167,64,16,221,178,0,194,138,16,62,132,233,37,76,15,97,40,73,117,153,80,61,193,149,102,131,14,128,229,
  75,88,214,52,23,116,129,110,48,15,204,7,61,160,23,44,32,185,166,251,192,66,181,206,47,0,139,193,18,112,33,184,8,44,5,23,131,126,
  48,0,86,128,75,192,74,112,41,88,5,214,128,117,224,50,176,30,108,4,91,193,118,176,3,92,73,178,31,197,127,33,37,151,98,111,8,
  43,125,101,153,190,30,122,165,210,183,212,202,254,51,149,230,251,143,1,118,195,30,41,171,151,235,197,242,13,74,119,149,79,177,
  174,90,229,183,84,217,107,149,189,90,233,71,149,61,90,102,143,42,123,141,210,111,132,94,167,244,59,148,189,94,217,107,149,190,
  84,233,13,101,58,159,183,123,107,101,57,174,63,168,222,213,92,214,254,150,50,189,181,76,111,47,211,103,151,245,133,207,239,163,
  170,126,62,199,93,170,206,121,202,135,207,67,175,210,7,149,206,251,178,89,233,143,67,31,82,250,83,101,122,95,153,206,219,191,
  73,233,207,65,223,162,116,62,254,151,43,253,133,50,159,127,173,149,103,67,175,26,255,98,61,175,212,202,152,88,160,218,179,77,
  233,175,195,158,80,186,171,250,178,80,189,87,199,76,127,139,184,92,64,223,135,244,96,228,108,33,107,105,159,144,61,148,22,50,
  76,31,20,178,155,190,65,60,62,154,40,37,164,244,51,148,159,129,17,43,8,57,159,110,20,50,74,183,40,121,171,144,178,30,3,239,187,
  155,100,156,157,22,146,209,167,132,140,211,167,133,172,167,207,10,217,71,95,23,178,248,94,172,121,37,95,0,26,85,209,125,162,
  253,109,100,10,233,165,247,10,25,20,210,131,246,152,66,182,210,231,69,185,78,145,230,237,222,169,218,57,34,100,29,237,21,210,
  164,81,101,63,40,164,159,142,8,105,208,117,74,30,87,249,39,133,212,233,81,33,91,233,51,106,28,190,76,124,205,180,139,247,132,
  176,91,112,25,70,126,82,72,143,240,175,68,250,176,144,243,232,135,34,238,42,232,128,138,191,59,69,236,181,138,114,81,140,203,
  30,37,63,64,50,182,239,23,114,1,125,77,200,74,122,70,72,75,200,122,172,168,221,66,70,104,76,72,89,174,30,35,37,165,44,95,175,
  252,27,212,123,26,176,202,118,11,25,166,239,18,223,11,103,11,123,35,242,159,36,190,158,90,201,17,210,71,87,11,217,72,239,87,233,
  163,66,6,232,90,146,235,238,152,144,81,186,94,200,24,125,81,200,110,122,92,201,47,41,251,87,132,236,160,39,132,156,67,95,37,
  190,86,229,120,53,99,87,149,178,158,206,8,41,219,213,138,113,191,73,200,32,125,148,248,222,28,162,9,226,251,115,144,174,81,242,
  6,226,235,121,22,185,196,215,114,3,221,75,124,29,55,211,211,196,247,234,22,202,8,217,68,31,34,190,166,123,233,125,66,6,69,61,
  243,213,120,204,199,143,76,119,211,23,136,239,233,210,206,229,3,66,206,167,23,85,250,37,146,119,52,34,185,182,248,30,81,5,249,
  4,54,174,196,28,105,247,148,229,247,169,252,151,145,63,166,242,121,60,51,42,237,151,60,255,109,228,223,164,242,121,253,255,132,
  131,231,103,224,213,14,233,251,39,37,249,97,164,65,248,33,173,57,210,214,168,100,183,146,171,148,28,156,195,235,210,133,254,32,
  54,61,31,228,48,18,187,53,70,227,214,44,17,161,60,151,215,247,112,187,220,35,219,89,144,182,199,24,206,41,139,18,49,162,131,
  150,87,68,184,99,245,9,57,30,171,70,137,42,54,61,111,129,144,93,111,241,182,49,241,190,207,182,203,126,58,22,183,4,69,31,77,
  252,240,188,199,219,229,121,34,219,48,204,52,26,214,12,26,214,61,52,236,209,105,216,48,197,202,225,237,50,232,165,118,121,30,38,
  250,60,168,139,239,180,1,156,159,181,148,88,168,83,51,75,244,153,104,169,143,184,140,68,114,177,245,136,145,22,38,125,47,23,165,
  52,228,123,133,116,172,94,97,49,148,197,128,165,118,170,230,45,98,52,66,40,61,23,207,146,173,235,143,72,45,148,41,38,78,8,
  194,234,213,1,151,76,157,93,186,56,231,121,207,151,8,169,163,237,23,92,23,186,112,57,86,102,128,248,40,189,218,46,247,110,222,
  103,31,70,185,7,218,38,120,14,31,247,35,85,43,236,60,197,243,230,35,181,81,164,42,176,47,241,155,64,144,29,180,46,227,227,200,
  134,143,7,104,247,109,149,52,124,123,132,134,239,8,210,206,15,212,209,240,7,107,104,248,206,106,138,252,247,206,227,81,188,217,
  162,157,199,44,188,165,138,134,143,133,104,251,13,149,148,184,49,66,137,155,130,180,21,87,255,196,45,33,242,30,247,222,125,
  200,235,87,53,122,209,115,77,221,8,170,103,203,248,75,96,110,171,68,108,122,69,140,52,194,158,231,241,225,107,70,12,44,195,58,
  118,172,1,188,35,232,107,245,53,145,247,198,86,79,19,69,124,78,236,66,156,4,78,108,49,253,30,207,139,240,108,244,189,7,90,43,
  206,129,160,22,209,219,186,150,220,16,167,117,62,77,111,244,235,176,55,211,41,10,152,203,205,118,97,115,112,57,246,81,192,183,
  228,230,70,145,142,248,29,92,17,79,153,65,198,83,47,251,77,230,196,98,40,17,244,114,79,47,60,151,251,48,139,125,23,83,141,247,
  101,93,103,93,63,72,156,13,161,214,165,104,195,210,96,132,34,245,78,108,9,215,67,60,70,23,34,166,130,134,131,15,47,63,70,42,
  138,216,170,242,132,68,84,120,208,171,16,53,250,253,232,89,13,234,159,235,147,119,156,43,249,140,178,89,251,170,113,46,4,160,31,
  153,45,239,23,253,225,90,138,132,219,81,131,247,227,236,11,222,115,222,31,177,95,121,255,232,243,90,164,249,170,200,231,143,208,
  161,128,41,198,238,226,240,127,77,86,135,251,10,93,175,133,88,132,186,222,150,99,91,37,235,109,172,16,49,30,166,7,103,243,
  25,198,216,251,78,178,72,77,68,79,60,236,167,102,35,113,186,2,173,27,132,71,64,91,138,245,209,98,176,69,149,90,36,50,30,11,226,
  28,9,106,195,167,195,148,56,93,67,17,51,241,136,23,158,139,248,136,120,7,189,154,41,173,107,52,205,92,124,253,63,82,68,155,
  94,130,251,198,81,107,80,203,89,171,149,92,195,165,153,179,86,96,133,242,183,61,71,57,235,18,232,65,214,202,218,160,95,202,35,
  5,246,55,39,115,214,42,165,191,54,153,120,164,26,35,215,128,104,237,194,188,21,189,90,181,40,230,160,27,187,110,80,107,244,121,
  132,126,61,226,164,209,175,81,177,116,171,86,67,7,99,98,39,214,74,190,84,244,213,28,107,158,104,153,19,107,199,154,43,175,185,
  209,27,128,87,19,229,208,206,139,181,179,147,165,26,99,20,241,230,98,43,145,35,61,15,90,13,178,14,171,81,140,225,206,211,81,
  234,186,51,36,198,177,155,118,79,134,212,88,44,18,185,75,174,111,147,163,233,73,124,82,90,49,18,230,160,169,121,164,87,47,188,
  102,206,151,245,45,158,156,121,46,186,105,217,100,72,107,49,230,106,33,45,113,230,221,30,30,115,238,59,230,180,155,226,40,209,
  77,61,147,168,121,85,55,121,39,249,254,225,199,174,84,45,246,80,175,184,7,243,216,233,16,123,86,181,248,172,113,29,210,95,20,
  123,79,72,156,177,252,204,255,190,242,251,23,101,255,55,149,254,79,149,126,83,236,218,140,254,42,234,173,38,31,147,118,227,186,
  208,23,216,235,236,186,206,175,176,55,24,189,206,232,13,118,109,231,77,154,48,122,49,14,252,76,249,205,108,249,121,39,162,37,
  182,249,168,89,79,92,33,163,149,81,128,45,101,136,86,221,219,134,83,226,138,0,181,99,79,31,239,99,148,48,115,177,181,248,140,
  131,29,231,138,90,228,39,240,204,89,27,196,30,212,202,194,212,245,219,16,107,209,231,50,236,78,109,93,255,33,158,191,144,103,
  105,3,124,248,186,243,225,189,115,213,62,171,81,167,86,221,61,167,167,6,186,23,173,15,97,48,248,157,161,26,31,110,34,161,67,172,
  2,253,9,88,23,91,134,176,84,90,47,135,66,204,7,219,86,102,209,133,205,255,51,201,245,4,195,124,232,107,170,152,94,205,122,25,
  191,93,46,178,106,168,154,45,80,58,198,150,197,149,14,127,118,129,208,47,176,126,170,74,87,83,163,190,1,209,216,129,27,118,128,
  189,28,102,129,146,29,177,220,55,135,22,134,3,149,23,189,241,172,242,231,243,126,129,232,175,99,45,231,210,95,244,119,250,230,
  210,47,43,131,21,197,221,245,20,181,7,161,245,245,211,29,21,220,55,136,216,88,116,247,71,167,222,27,209,133,230,65,73,171,19,
  99,20,240,56,125,179,105,161,71,88,17,43,62,92,45,155,35,210,187,124,94,42,197,104,180,68,186,105,98,18,163,29,193,104,7,184,
  165,155,198,203,218,216,11,111,158,218,174,87,146,124,79,68,74,35,40,228,86,179,78,166,189,33,196,76,53,21,79,18,110,27,70,13,
  188,254,149,147,178,102,174,175,154,36,113,63,159,139,150,222,172,246,191,7,196,60,122,232,35,144,94,104,252,222,199,119,255,
  103,85,90,167,251,176,69,158,98,215,205,122,158,221,199,72,221,98,136,110,239,144,123,232,182,88,149,248,28,91,180,223,213,33,
  99,101,107,44,138,59,187,53,117,158,61,208,33,239,75,17,236,232,126,120,123,248,59,59,228,103,67,156,137,123,176,211,106,137,
  100,152,150,50,63,113,25,209,157,149,117,116,240,134,0,181,104,203,209,158,109,123,170,232,184,231,201,85,187,32,43,9,99,166,
  97,204,88,215,239,24,201,187,149,71,173,161,70,21,151,179,166,206,255,6,22,106,226,49,203,16,157,26,125,185,67,126,119,208,142,
  18,137,131,184,127,228,176,23,231,241,78,23,183,151,66,45,29,50,121,77,137,156,104,207,193,10,138,84,59,177,33,196,85,132,13,
  195,187,69,107,55,27,17,25,243,81,151,99,245,16,191,33,201,182,68,196,141,136,137,239,39,152,248,153,131,55,200,27,234,139,101,
  125,231,223,37,242,127,26,149,164,27,144,99,121,20,242,198,128,188,51,22,191,23,224,231,215,201,128,28,211,83,144,15,169,252,
  242,187,47,207,55,85,61,126,37,249,247,7,103,149,111,135,170,175,78,201,168,122,111,81,198,85,125,113,85,167,159,228,103,157,
  184,240,232,19,159,95,162,170,236,130,178,182,149,247,193,162,26,97,55,84,155,75,229,163,194,62,79,249,241,207,160,140,228,189,
  83,182,33,42,202,52,193,210,131,222,116,43,123,179,42,23,167,226,120,48,12,111,23,225,194,198,150,145,182,44,70,108,128,204,129,
  180,147,118,87,144,182,162,159,60,43,250,187,119,144,181,58,235,56,246,136,155,206,58,49,59,151,203,230,40,12,139,107,59,110,
  239,144,237,236,115,71,169,118,77,58,63,50,229,180,181,224,56,201,61,25,155,216,6,210,54,12,145,190,97,104,3,121,240,192,126,
  184,145,170,55,22,70,236,245,137,196,150,109,110,206,78,142,45,216,159,60,148,36,54,68,26,156,116,238,163,13,161,200,16,30,222,
  161,161,93,67,67,168,32,160,20,174,107,67,187,168,126,40,233,164,114,217,116,42,238,218,19,110,60,129,199,118,55,157,201,247,
  83,108,104,36,59,22,207,141,229,51,241,253,120,77,124,250,187,58,22,246,211,226,243,123,204,216,145,126,106,57,111,169,126,106,
  31,74,37,51,135,210,7,226,73,199,201,186,73,94,56,190,214,25,201,100,243,105,103,223,234,76,50,143,182,205,62,159,207,38,219,
  29,205,166,248,139,222,237,180,1,237,201,169,74,218,102,200,223,100,143,237,81,14,54,92,154,103,112,217,150,222,231,36,221,66,
  14,93,105,156,33,59,49,154,203,30,22,69,249,108,196,211,217,248,170,194,222,189,118,206,78,109,112,198,11,110,177,151,181,83,
  217,27,54,175,157,24,177,199,121,225,105,230,114,239,186,41,243,230,130,91,102,175,151,246,76,210,217,23,95,61,154,204,109,179,
  15,22,108,103,196,158,170,72,228,148,213,95,93,102,222,128,184,219,103,231,248,76,79,55,230,114,133,113,215,78,149,21,171,41,
  247,128,131,156,201,72,153,117,243,158,253,152,232,233,158,165,57,47,247,68,219,49,73,211,219,46,109,114,160,250,169,97,134,156,
  116,38,197,179,202,43,194,72,219,201,212,244,174,138,209,151,239,108,146,102,199,118,227,235,93,119,124,251,214,161,210,218,
  235,167,112,41,23,57,83,173,81,233,114,79,213,163,2,86,133,236,187,155,69,67,172,50,235,80,58,239,78,53,67,88,54,37,199,59,214,
  58,110,238,72,63,109,154,201,60,240,238,241,120,71,125,51,120,172,192,15,85,78,175,110,186,97,155,237,242,176,47,25,176,254,70,
  10,185,28,182,151,248,234,100,38,35,118,146,214,243,231,247,83,207,255,231,128,192,130,15,31,149,178,208,232,158,217,123,237,
  132,61,82,120,135,107,231,249,92,179,8,222,220,161,52,143,221,216,249,253,242,83,115,251,78,143,117,5,190,46,139,75,111,230,220,
  126,26,56,95,246,192,121,151,45,38,160,99,230,210,50,24,215,37,71,208,64,204,250,252,153,189,16,59,99,233,145,248,165,66,172,
  202,102,51,118,18,227,50,111,102,231,76,118,228,64,62,190,213,134,158,75,58,238,16,146,253,228,135,16,83,176,140,216,14,210,118,
  96,143,223,129,61,126,7,246,120,19,15,190,215,35,177,139,2,59,202,246,249,29,187,136,237,34,109,215,70,0,57,188,10,108,160,
  234,225,25,86,165,182,219,161,64,114,100,196,206,231,59,250,250,250,168,66,234,235,50,201,125,121,242,38,83,169,28,82,100,38,
  199,199,109,39,69,222,61,201,188,189,61,151,33,115,143,24,45,242,140,32,140,200,28,17,177,66,6,223,145,109,242,99,195,31,79,230,
  236,68,150,188,234,68,160,64,233,104,160,186,146,158,200,150,78,13,178,70,48,166,174,93,90,140,69,139,156,42,62,32,69,75,233,0,
  41,90,100,74,248,84,170,17,45,14,29,153,41,123,36,155,178,169,38,101,239,77,22,50,238,180,201,227,185,25,219,181,41,144,42,
  53,165,54,53,227,169,92,61,205,44,171,33,127,42,171,154,76,204,38,131,79,223,17,242,9,129,5,10,77,197,49,25,123,211,118,38,5,
  145,41,228,71,73,223,135,204,26,60,138,11,13,47,80,93,10,195,186,150,223,22,84,186,18,233,245,120,149,157,91,199,107,200,11,135,
  178,56,37,19,233,65,251,136,112,44,63,49,168,2,134,45,56,37,197,48,240,220,173,118,126,60,235,228,49,200,24,15,94,77,2,7,89,70,
  221,69,120,53,216,13,201,7,185,35,153,41,216,100,141,38,243,171,16,145,170,141,54,66,0,150,203,113,107,160,138,81,209,162,161,
  180,99,35,82,100,34,79,65,165,36,178,219,17,9,225,81,236,196,91,249,33,149,119,87,143,165,168,122,122,90,58,5,184,81,181,151,
  165,201,155,118,82,246,196,230,189,84,145,46,235,161,47,237,168,38,85,164,243,107,39,70,147,133,188,203,91,147,206,139,113,32,
  51,157,71,63,93,158,203,165,172,217,151,86,251,55,121,246,103,211,136,131,140,236,167,135,47,53,242,56,201,49,76,169,99,31,94,
  157,28,25,181,83,114,58,183,96,149,82,136,27,75,97,88,129,100,41,152,144,192,43,132,228,75,193,227,240,209,208,157,2,26,137,
  199,170,35,46,198,163,6,218,186,108,38,147,61,108,167,182,218,169,116,14,53,73,235,84,42,145,149,14,212,48,147,85,141,95,22,
  203,174,172,33,122,22,93,213,199,241,118,15,30,11,197,115,17,249,198,139,51,204,53,119,77,210,77,82,168,168,201,138,60,34,82,189,
  57,68,58,86,48,85,230,84,24,172,87,211,86,243,14,131,44,101,194,138,229,66,122,174,128,119,231,17,175,85,120,168,246,36,210,99,
  54,111,78,5,76,107,178,50,234,168,49,207,3,51,239,242,112,145,29,41,245,158,59,78,197,98,56,207,99,49,153,42,214,98,137,180,
  8,12,121,159,163,72,201,178,37,135,113,200,185,71,200,200,143,103,210,46,132,155,204,97,206,33,220,66,158,2,82,138,144,174,44,
  233,178,15,193,188,8,32,117,84,152,249,194,158,49,212,224,135,204,139,45,144,66,238,104,249,150,83,205,147,239,220,117,74,198,
  178,109,38,12,99,249,34,172,68,122,91,249,203,60,238,104,26,113,194,159,29,125,228,119,209,85,12,211,38,44,223,41,85,197,169,
  155,149,251,49,85,184,101,203,177,142,159,3,249,189,217,220,152,157,186,188,44,2,189,216,89,68,11,204,130,35,34,185,226,80,50,
  211,81,92,9,198,33,177,76,140,195,57,68,63,105,19,125,116,55,211,190,205,200,27,166,251,249,115,114,217,0,44,60,249,184,102,
  156,99,223,100,207,179,231,240,137,219,248,7,54,111,157,55,60,208,203,255,209,211,26,28,78,44,31,76,183,238,30,28,30,188,106,88,
  27,111,94,219,118,142,122,252,187,239,101,143,178,91,217,119,217,55,216,99,236,12,187,157,121,195,218,95,180,254,137,137,35,218,
  245,215,156,17,133,123,7,6,135,88,164,146,58,217,143,144,75,59,205,221,247,176,191,99,39,216,119,132,247,43,186,231,195,172,
  121,112,224,146,3,186,118,11,91,196,152,174,127,128,177,229,39,116,243,17,198,62,57,161,179,195,245,39,116,239,15,89,125,90,59,
  212,111,48,195,171,133,251,13,115,120,193,208,130,65,221,248,36,179,6,46,49,140,22,67,51,244,86,157,242,77,3,180,210,63,85,
  253,223,179,207,177,79,176,219,240,146,222,57,172,42,138,54,247,106,21,253,109,244,54,122,187,113,249,45,90,111,143,182,179,89,
  171,56,252,196,196,181,172,209,242,48,183,189,255,57,214,80,201,234,67,43,126,201,234,171,13,198,171,12,227,216,52,136,107,
  115,79,60,126,213,247,250,180,150,31,24,164,237,233,63,215,113,191,102,245,211,29,140,221,205,188,205,168,173,182,71,27,107,254,
  105,219,93,43,209,5,202,215,180,182,24,36,180,206,86,250,52,31,222,94,221,250,60,139,183,233,161,211,140,13,245,106,207,80,
  143,97,105,151,54,155,214,173,71,244,170,175,51,198,234,171,206,233,225,179,232,180,94,249,41,198,22,156,211,253,7,234,111,215,
  43,30,100,245,187,116,223,85,45,187,244,224,71,89,203,144,174,189,200,234,227,204,178,142,60,172,133,118,26,214,74,244,221,
  103,4,91,245,64,190,73,115,54,26,1,83,51,125,102,208,180,222,207,90,106,47,106,53,3,116,171,206,39,247,131,226,121,143,120,254,
  94,211,222,251,113,12,75,155,78,15,97,172,7,39,218,123,247,107,19,205,3,244,75,62,205,127,208,105,220,88,190,127,160,117,151,
  110,30,156,53,208,96,152,116,74,103,31,225,115,167,121,217,15,88,99,80,243,105,187,60,116,138,181,104,1,164,155,140,104,111,116,
  121,212,136,118,68,189,90,5,55,96,4,139,74,149,102,66,169,55,68,17,223,41,22,173,144,101,60,209,213,170,132,72,250,163,44,
  186,56,218,25,93,143,170,100,134,79,243,203,26,60,197,170,58,73,99,26,157,140,49,252,63,118,204,243,88,173,198,190,95,203,158,
  137,61,84,71,6,99,26,50,197,15,121,142,31,243,60,85,103,176,223,212,81,149,233,245,106,44,34,126,68,30,211,166,253,136,180,9,
  255,199,234,217,137,216,203,13,90,228,205,6,214,240,251,89,44,242,66,19,139,28,107,247,85,157,156,109,84,189,221,201,170,78,
  206,101,85,103,193,83,224,177,46,86,117,166,91,254,125,4,149,125,223,192,101,241,239,183,248,119,4,197,191,225,42,126,119,193,
  255,142,139,127,79,82,252,91,46,254,189,66,241,239,185,76,42,253,77,151,110,201,223,193,241,239,98,88,76,254,254,247,49,254,29,
  74,76,250,240,223,33,50,171,244,123,69,45,38,223,203,255,6,76,87,254,252,247,120,158,24,137,223,63,241,223,17,146,42,43,126,
  247,104,201,182,242,191,55,251,63,108,101,104,241,168,38,0,0,0,0};
  
  #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
   METHOD (constructor, "<init>", "()V") \
   METHOD (toString, "toString", "()Ljava/lang/String;") \
  
  DECLARE_JNI_CLASS (StringBuffer, "java/lang/StringBuffer")
  #undef JNI_CLASS_MEMBERS
  
  //==============================================================================
  #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
   STATICMETHOD (createHTTPStream, "createHTTPStream", "(Ljava/lang/String;Z[BLjava/lang/String;I[ILjava/lang/StringBuffer;ILjava/lang/String;)Lcom/rmsl/juce/JuceHTTPStream;") \
   METHOD (connect, "connect", "()Z") \
   METHOD (release, "release", "()V") \
   METHOD (read, "read", "([BI)I") \
   METHOD (getPosition, "getPosition", "()J") \
   METHOD (getTotalLength, "getTotalLength", "()J") \
   METHOD (isExhausted, "isExhausted", "()Z") \
   METHOD (setPosition, "setPosition", "(J)Z") \
  
  DECLARE_JNI_CLASS_WITH_BYTECODE (HTTPStream, "com/rmsl/juce/JuceHTTPStream", 16, javaJuceHttpStream, sizeof(javaJuceHttpStream))
  #undef JNI_CLASS_MEMBERS
  
  //==============================================================================
  #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
   METHOD (close,     "close",     "()V") \
   METHOD (read,      "read",      "([BII)I") \
  
  DECLARE_JNI_CLASS (AndroidInputStream, "java/io/InputStream")
  #undef JNI_CLASS_MEMBERS
  
  //==============================================================================
  #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
    METHOD (acquire, "acquire", "()V") \
    METHOD (release, "release", "()V") \
  
  DECLARE_JNI_CLASS (AndroidMulticastLock, "android/net/wifi/WifiManager$MulticastLock")
  #undef JNI_CLASS_MEMBERS
  
  #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
    METHOD (createMulticastLock, "createMulticastLock", "(Ljava/lang/String;)Landroid/net/wifi/WifiManager$MulticastLock;") \
  
  DECLARE_JNI_CLASS (AndroidWifiManager, "android/net/wifi/WifiManager")
  #undef JNI_CLASS_MEMBERS
  
  static LocalRef<jobject> getMulticastLock()
  {
      static LocalRef<jobject> multicastLock;
      static bool hasChecked = false;
  
      if (! hasChecked)
      {
          hasChecked = true;
  
          auto* env = getEnv();
  
          LocalRef<jobject> wifiManager (env->CallObjectMethod (getAppContext().get(),
                                                                AndroidContext.getSystemService,
                                                                javaString ("wifi").get()));
  
          if (wifiManager != nullptr)
          {
              multicastLock = LocalRef<jobject> (env->CallObjectMethod (wifiManager.get(),
                                                                        AndroidWifiManager.createMulticastLock,
                                                                        javaString ("JUCE_MulticastLock").get()));
          }
      }
  
      return multicastLock;
  }
  
  JUCE_API void JUCE_CALLTYPE acquireMulticastLock()
  {
      auto multicastLock = getMulticastLock();
  
      if (multicastLock != nullptr)
          getEnv()->CallVoidMethod (multicastLock.get(), AndroidMulticastLock.acquire);
  }
  
  JUCE_API void JUCE_CALLTYPE releaseMulticastLock()
  {
      auto multicastLock = getMulticastLock();
  
      if (multicastLock != nullptr)
          getEnv()->CallVoidMethod (multicastLock.get(), AndroidMulticastLock.release);
  }
  
  //==============================================================================
  void MACAddress::findAllAddresses (Array<MACAddress>& /*result*/)
  {
      // TODO
  }
  
  
  JUCE_API bool JUCE_CALLTYPE Process::openEmailWithAttachments (const String& /*targetEmailAddress*/,
                                                                 const String& /*emailSubject*/,
                                                                 const String& /*bodyText*/,
                                                                 const StringArray& /*filesToAttach*/)
  {
      // TODO
      return false;
  }
  
  //==============================================================================
  bool URL::isLocalFile() const
  {
      if (getScheme() == "file")
          return true;
  
      if (getScheme() == "content")
      {
          auto file = AndroidContentUriResolver::getLocalFileFromContentUri (*this);
          return (file != File());
      }
  
      return false;
  }
  
  File URL::getLocalFile() const
  {
      if (getScheme() == "content")
      {
          auto path = AndroidContentUriResolver::getLocalFileFromContentUri (*this);
  
          // This URL does not refer to a local file
          // Call URL::isLocalFile to first check if the URL
          // refers to a local file.
          jassert (path != File());
  
          return path;
      }
  
      return fileFromFileSchemeURL (*this);
  }
  
  String URL::getFileName() const
  {
      if (getScheme() == "content")
          return AndroidContentUriResolver::getFileNameFromContentUri (*this);
  
      return toString (false).fromLastOccurrenceOf ("/", false, true);
  }
  
  //==============================================================================
  class WebInputStream::Pimpl
  {
  public:
      enum { contentStreamCacheSize = 1024 };
  
      Pimpl (WebInputStream&, const URL& urlToCopy, bool shouldBePost)
          : url (urlToCopy),
            isContentURL (urlToCopy.getScheme() == "content"),
            isPost (shouldBePost),
            httpRequest (isPost ? "POST" : "GET")
      {}
  
      ~Pimpl()
      {
          cancel();
      }
  
      void cancel()
      {
          if (isContentURL)
          {
              stream.callVoidMethod (AndroidInputStream.close);
              return;
          }
  
          const ScopedLock lock (createStreamLock);
  
          if (stream != nullptr)
          {
              stream.callVoidMethod (HTTPStream.release);
              stream.clear();
          }
  
          hasBeenCancelled = true;
      }
  
      bool connect (WebInputStream::Listener* /*listener*/)
      {
          auto* env = getEnv();
  
          if (isContentURL)
          {
              auto inputStream = AndroidContentUriResolver::getStreamForContentUri (url, true);
  
              if (inputStream != nullptr)
              {
                  stream = GlobalRef (inputStream);
                  statusCode = 200;
  
                  return true;
              }
          }
          else
          {
              String address = url.toString (! isPost);
  
              if (! address.contains ("://"))
                  address = "http://" + address;
  
              MemoryBlock postData;
              if (isPost)
                  WebInputStream::createHeadersAndPostData (url, headers, postData);
  
              jbyteArray postDataArray = nullptr;
  
              if (postData.getSize() > 0)
              {
                  postDataArray = env->NewByteArray (static_cast<jsize> (postData.getSize()));
                  env->SetByteArrayRegion (postDataArray, 0, static_cast<jsize> (postData.getSize()), (const jbyte*) postData.getData());
              }
  
              LocalRef<jobject> responseHeaderBuffer (env->NewObject (StringBuffer, StringBuffer.constructor));
  
              // Annoyingly, the android HTTP functions will choke on this call if you try to do it on the message
              // thread. You'll need to move your networking code to a background thread to keep it happy..
              jassert (Thread::getCurrentThread() != nullptr);
  
              jintArray statusCodeArray = env->NewIntArray (1);
              jassert (statusCodeArray != nullptr);
  
              {
                  const ScopedLock lock (createStreamLock);
  
                  if (! hasBeenCancelled)
                      stream = GlobalRef (LocalRef<jobject> (env->CallStaticObjectMethod (HTTPStream,
                                                                                          HTTPStream.createHTTPStream,
                                                                                          javaString (address).get(),
                                                                                          (jboolean) isPost,
                                                                                          postDataArray,
                                                                                          javaString (headers).get(),
                                                                                          (jint) timeOutMs,
                                                                                          statusCodeArray,
                                                                                          responseHeaderBuffer.get(),
                                                                                          (jint) numRedirectsToFollow,
                                                                                          javaString (httpRequest).get())));
              }
  
              if (stream != nullptr && ! stream.callBooleanMethod (HTTPStream.connect))
                  stream.clear();
  
              jint* const statusCodeElements = env->GetIntArrayElements (statusCodeArray, nullptr);
              statusCode = statusCodeElements[0];
              env->ReleaseIntArrayElements (statusCodeArray, statusCodeElements, 0);
              env->DeleteLocalRef (statusCodeArray);
  
              if (postDataArray != nullptr)
                  env->DeleteLocalRef (postDataArray);
  
              if (stream != nullptr)
              {
                  StringArray headerLines;
  
                  {
                      LocalRef<jstring> headersString ((jstring) env->CallObjectMethod (responseHeaderBuffer.get(),
                                                                                        StringBuffer.toString));
                      headerLines.addLines (juceString (env, headersString));
                  }
  
                  for (int i = 0; i < headerLines.size(); ++i)
                  {
                      const String& header = headerLines[i];
                      const String key (header.upToFirstOccurrenceOf (": ", false, false));
                      const String value (header.fromFirstOccurrenceOf (": ", false, false));
                      const String previousValue (responseHeaders[key]);
  
                      responseHeaders.set (key, previousValue.isEmpty() ? value : (previousValue + "," + value));
                  }
  
                  return true;
              }
          }
  
          return false;
      }
  
      //==============================================================================
      // WebInputStream methods
      void withExtraHeaders (const String& extraHeaders)
      {
          if (! headers.endsWithChar ('\n') && headers.isNotEmpty())
              headers << "\r\n";
  
          headers << extraHeaders;
  
          if (! headers.endsWithChar ('\n') && headers.isNotEmpty())
              headers << "\r\n";
      }
  
      void withCustomRequestCommand (const String& customRequestCommand)    { httpRequest = customRequestCommand; }
      void withConnectionTimeout (int timeoutInMs)                          { timeOutMs = timeoutInMs; }
      void withNumRedirectsToFollow (int maxRedirectsToFollow)              { numRedirectsToFollow = maxRedirectsToFollow; }
      StringPairArray getRequestHeaders() const                             { return WebInputStream::parseHttpHeaders (headers); }
      StringPairArray getResponseHeaders() const                            { return responseHeaders; }
      int getStatusCode() const                                             { return statusCode; }
  
      //==============================================================================
      bool isError() const                         { return stream == nullptr; }
      bool isExhausted()                           { return (isContentURL ? eofStreamReached : stream != nullptr && stream.callBooleanMethod (HTTPStream.isExhausted)); }
      int64 getTotalLength()                       { return (isContentURL ? -1           : (stream != nullptr ? stream.callLongMethod (HTTPStream.getTotalLength) : 0)); }
      int64 getPosition()                          { return (isContentURL ? readPosition : (stream != nullptr ? stream.callLongMethod (HTTPStream.getPosition)    : 0)); }
  
      //==============================================================================
      bool setPosition (int64 wantedPos)
      {
          if (isContentURL)
          {
              if (wantedPos < readPosition)
                  return false;
  
              auto bytesToSkip = wantedPos - readPosition;
  
              if (bytesToSkip == 0)
                  return true;
  
              HeapBlock<char> buffer (bytesToSkip);
  
              return (read (buffer.getData(), (int) bytesToSkip) > 0);
          }
  
          return stream != nullptr && stream.callBooleanMethod (HTTPStream.setPosition, (jlong) wantedPos);
      }
  
      int read (void* buffer, int bytesToRead)
      {
          jassert (buffer != nullptr && bytesToRead >= 0);
  
          const ScopedLock lock (createStreamLock);
  
          if (stream == nullptr)
              return 0;
  
          JNIEnv* env = getEnv();
  
          jbyteArray javaArray = env->NewByteArray (bytesToRead);
  
          auto numBytes = (isContentURL ? stream.callIntMethod (AndroidInputStream.read, javaArray, 0, (jint) bytesToRead)
                                        : stream.callIntMethod (HTTPStream.read, javaArray, (jint) bytesToRead));
  
          if (numBytes > 0)
              env->GetByteArrayRegion (javaArray, 0, numBytes, static_cast<jbyte*> (buffer));
  
          env->DeleteLocalRef (javaArray);
  
          readPosition += jmax (0, numBytes);
  
          if (numBytes == -1)
              eofStreamReached = true;
  
          return numBytes;
      }
  
      //==============================================================================
      int statusCode = 0;
  
  private:
      const URL url;
      bool isContentURL, isPost, eofStreamReached = false;
      int numRedirectsToFollow = 5, timeOutMs = 0;
      String httpRequest, headers;
      StringPairArray responseHeaders;
      CriticalSection createStreamLock;
      bool hasBeenCancelled = false;
      int readPosition = 0;
  
      GlobalRef stream;
      JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl)
  };
  
  std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool shouldUsePost)
  {
      return URL::DownloadTask::createFallbackDownloader (*this, targetLocation, extraHeaders, listener, shouldUsePost);
  }
  
  //==============================================================================
  #if __ANDROID_API__ < 24   // Android support for getifadds was added in Android 7.0 (API 24) so the posix implementation does not apply
  
  static IPAddress makeAddress (const sockaddr_in *addr_in)
  {
      if (addr_in->sin_addr.s_addr == INADDR_NONE)
          return {};
  
      return IPAddress (ntohl (addr_in->sin_addr.s_addr));
  }
  
  struct InterfaceInfo
  {
      IPAddress interfaceAddress, broadcastAddress;
  };
  
  static Array<InterfaceInfo> findIPAddresses (int dummySocket)
  {
      ifconf cfg;
      HeapBlock<char> buffer;
      int bufferSize = 1024;
  
      do
      {
          bufferSize *= 2;
          buffer.calloc (bufferSize);
  
          cfg.ifc_len = bufferSize;
          cfg.ifc_buf = buffer;
  
          if (ioctl (dummySocket, SIOCGIFCONF, &cfg) < 0 && errno != EINVAL)
              return {};
  
      } while (bufferSize < cfg.ifc_len + 2 * (int) (IFNAMSIZ + sizeof (struct sockaddr_in6)));
  
      Array<InterfaceInfo> result;
  
      for (size_t i = 0; i < (size_t) cfg.ifc_len / (size_t) sizeof (struct ifreq); ++i)
      {
          auto& item = cfg.ifc_req[i];
  
          if (item.ifr_addr.sa_family == AF_INET)
          {
              InterfaceInfo info;
              info.interfaceAddress = makeAddress (reinterpret_cast<const sockaddr_in*> (&item.ifr_addr));
  
              if (! info.interfaceAddress.isNull())
              {
                  if (ioctl (dummySocket, SIOCGIFBRDADDR, &item) == 0)
                      info.broadcastAddress = makeAddress (reinterpret_cast<const sockaddr_in*> (&item.ifr_broadaddr));
  
                  result.add (info);
              }
          }
          else if (item.ifr_addr.sa_family == AF_INET6)
          {
              // TODO: IPv6
          }
      }
  
      return result;
  }
  
  static Array<InterfaceInfo> findIPAddresses()
  {
      auto dummySocket = socket (AF_INET, SOCK_DGRAM, 0); // a dummy socket to execute the IO control
  
      if (dummySocket < 0)
          return {};
  
      auto result = findIPAddresses (dummySocket);
      ::close (dummySocket);
      return result;
  }
  
  void IPAddress::findAllAddresses (Array<IPAddress>& result, bool /*includeIPv6*/)
  {
      for (auto& a : findIPAddresses())
          result.add (a.interfaceAddress);
  }
  
  IPAddress IPAddress::getInterfaceBroadcastAddress (const IPAddress& address)
  {
      for (auto& a : findIPAddresses())
          if (a.interfaceAddress == address)
              return a.broadcastAddress;
  
      return {};
  }
  
  #endif
  
  } // namespace juce
  