    protected void createGraphicalViewer(Composite parent) {
        final RulerComposite rc = new RulerComposite(parent, SWT.NONE);
        viewer = new ScrollingGraphicalViewer();
        viewer.createControl(rc);
        editDomain.addViewer(viewer);
        rc.setGraphicalViewer(viewer);
        viewer.getControl().setBackground(ColorConstants.white);
        viewer.setEditPartFactory(new EditPartFactory() {

            public EditPart createEditPart(EditPart context, Object model) {
                return new RecorderEditPart(TopLevelModel.getRecorderModel());
            }
        });
        viewer.setContents(TopLevelModel.getRecorderModel());
        Control control = viewer.getControl();
        System.out.println("widget: " + control);
        DropTarget dt = new DropTarget(control, DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT);
        dt.setTransfer(new Transfer[] { TextTransfer.getInstance() });
        dt.addDropListener(new SensorTransferDropTargetListener(viewer));
    }


    @Override
    public void save(File folder) {
        actInstance = instance;
        this.setProperty(EsomMapper.PROPERTY_INSTANCE, String.valueOf(actInstance));
        log.debug("instance: " + this.getProperty(EsomMapper.PROPERTY_INSTANCE));
        if (this.getProperty(EsomMapper.PROPERTY_LRN_RADIO_SELECTED) == EsomMapper.RADIO_LOAD_SELECTED) {
            File src = new File(this.getProperty(EsomMapper.PROPERTY_LRN_FILE));
            if (src.getParent() != folder.getPath()) {
                log.debug("saving lrn file in save folder " + folder.getPath());
                File dst = new File(folder.getAbsolutePath() + File.separator + src.getName() + String.valueOf(actInstance));
                try {
                    FileReader fr = new FileReader(src);
                    BufferedReader br = new BufferedReader(fr);
                    dst.createNewFile();
                    FileWriter fw = new FileWriter(dst);
                    BufferedWriter bw = new BufferedWriter(fw);
                    int i = 0;
                    while ((i = br.read()) != -1) bw.write(i);
                    bw.flush();
                    bw.close();
                    br.close();
                    fr.close();
                } catch (FileNotFoundException e) {
                    log.error("Error while opening lrn sourcefile! Saving wasn't possible!!!");
                    e.printStackTrace();
                } catch (IOException e) {
                    log.error("Error while creating lrn destfile! Creating wasn't possible!!!");
                    e.printStackTrace();
                }
                this.setProperty(EsomMapper.PROPERTY_LRN_FILE, dst.getName());
                log.debug("done saving lrn file");
            }
        }
        if (this.getProperty(EsomMapper.PROPERTY_WTS_RADIO_SELECTED) == EsomMapper.RADIO_LOAD_SELECTED) {
            File src = new File(this.getProperty(EsomMapper.PROPERTY_WTS_FILE));
            if (src.getParent() != folder.getPath()) {
                log.debug("saving wts file in save folder " + folder.getPath());
                File dst = new File(folder.getAbsolutePath() + File.separator + src.getName() + String.valueOf(actInstance));
                try {
                    FileReader fr = new FileReader(src);
                    BufferedReader br = new BufferedReader(fr);
                    dst.createNewFile();
                    FileWriter fw = new FileWriter(dst);
                    BufferedWriter bw = new BufferedWriter(fw);
                    int i = 0;
                    while ((i = br.read()) != -1) bw.write(i);
                    bw.flush();
                    bw.close();
                    br.close();
                    fr.close();
                } catch (FileNotFoundException e) {
                    log.error("Error while opening wts sourcefile! Saving wasn't possible!!!");
                    e.printStackTrace();
                } catch (IOException e) {
                    log.error("Error while creating wts destfile! Creating wasn't possible!!!");
                    e.printStackTrace();
                }
                this.setProperty(EsomMapper.PROPERTY_WTS_FILE, dst.getName());
                log.debug("done saving wts file");
            }
        }
        if (this.getProperty(EsomMapper.PROPERTY_LRN_RADIO_SELECTED) == EsomMapper.RADIO_SELECT_FROM_DATANAV_SELECTED) {
            this.setProperty(EsomMapper.PROPERTY_LRN_FILE, "EsomMapper" + this.actInstance + ".lrn");
            File dst = new File(folder + File.separator + this.getProperty(EsomMapper.PROPERTY_LRN_FILE));
            try {
                FileWriter fw = new FileWriter(dst);
                BufferedWriter bw = new BufferedWriter(fw);
                bw.write("# EsomMapper LRN save file\n");
                bw.write("% " + this.inputVectors.getNumRows() + "\n");
                bw.write("% " + this.inputVectors.getNumCols() + "\n");
                bw.write("% 9");
                for (IColumn col : this.inputVectors.getColumns()) {
                    if (col.getType() == IClusterNumber.class) bw.write("\t2"); else if (col.getType() == String.class) bw.write("\t8"); else bw.write("\t1");
                }
                bw.write("\n% Key");
                for (IColumn col : this.inputVectors.getColumns()) {
                    bw.write("\t" + col.getLabel());
                }
                bw.write("\n");
                int keyIterator = 0;
                for (Vector<Object> row : this.inputVectors.getGrid()) {
                    bw.write(this.inputVectors.getKey(keyIterator++).toString());
                    for (Object point : row) bw.write("\t" + point.toString());
                    bw.write("\n");
                }
                bw.flush();
                fw.flush();
                bw.close();
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            this.setProperty(EsomMapper.PROPERTY_LRN_RADIO_SELECTED, EsomMapper.RADIO_LOAD_SELECTED);
        }
        if (this.getProperty(EsomMapper.PROPERTY_WTS_RADIO_SELECTED) == EsomMapper.RADIO_SELECT_FROM_DATANAV_SELECTED) {
            this.setProperty(EsomMapper.PROPERTY_WTS_FILE, "EsomMapper" + this.actInstance + ".wts");
            MyRetina tempRetina = new MyRetina(this.outputRetina.getNumRows(), this.outputRetina.getNumCols(), this.outputRetina.getDim(), this.outputRetina.getDistanceFunction(), this.outputRetina.isToroid());
            for (int row = 0; row < this.outputRetina.getNumRows(); row++) {
                for (int col = 0; col < this.outputRetina.getNumCols(); col++) {
                    for (int dim = 0; dim < this.outputRetina.getDim(); dim++) {
                        tempRetina.setNeuron(row, col, dim, this.outputRetina.getPointasDoubleArray(row, col)[dim]);
                    }
                }
            }
            EsomIO.writeWTSFile(folder + File.separator + this.getProperty(EsomMapper.PROPERTY_WTS_FILE), tempRetina);
            this.setProperty(EsomMapper.PROPERTY_WTS_RADIO_SELECTED, EsomMapper.RADIO_LOAD_SELECTED);
        }
        EsomMapper.instance++;
    }


    public boolean copier(String source, String nomFichierSource, java.io.File destination) {
        boolean resultat = false;
        OutputStream tmpOut;
        try {
            tmpOut = new BufferedOutputStream(new FileOutputStream(nomFichierSource + "001.tmp"));
            InputStream is = getClass().getResourceAsStream(source + nomFichierSource);
            int i;
            while ((i = is.read()) != -1) tmpOut.write(i);
            tmpOut.close();
            is.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        FileChannel in = null;
        FileChannel out = null;
        try {
            in = new FileInputStream(new File(nomFichierSource + "001.tmp")).getChannel();
            out = new FileOutputStream(destination).getChannel();
            in.transferTo(0, in.size(), out);
            resultat = true;
        } catch (java.io.FileNotFoundException f) {
        } catch (java.io.IOException e) {
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                }
            }
        }
        new File(nomFichierSource + "001.tmp").delete();
        return (resultat);
    }


private void displayDiffResults() throws IOException {
        File outFile = File.createTempFile("diff", ".htm");
        outFile.deleteOnExit();
        FileOutputStream outStream = new FileOutputStream(outFile);
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(outStream));
        out.write("<title>LOC Differences</title>\n" + SCRIPT + "\n" + "\n" + "
\n");
        if (addedTable.length() > 0) {
            out.write("

Files Added:	" + "Add	Type
");
            out.write(addedTable.toString());
            out.write("

");
        }
        if (modifiedTable.length() > 0) {
            out.write("

Files Modified:	" + "Base	Del	Mod	Add	" + "Total	Type
");
            out.write(modifiedTable.toString());
            out.write("

");
        }
        if (deletedTable.length() > 0) {
            out.write("

Files Deleted:	" + "Del	Type
");
            out.write(deletedTable.toString());
            out.write("

");
        }
        out.write("
\n");
        if (modifiedTable.length() > 0 || deletedTable.length() > 0) {
            out.write("
Base: 	");
            out.write(Long.toString(base));
            out.write("
\n
Deleted: 	");
            out.write(Long.toString(deleted));
            out.write("
\n
Modified: 	");
            out.write(Long.toString(modified));
            out.write("
\n
Added: 	");
            out.write(Long.toString(added));
            out.write("
\n
New & Changed: 	");
            out.write(Long.toString(added + modified));
            out.write("
\n");
        }
        out.write("
Total: 	");
        out.write(Long.toString(total));
        out.write("
\n

");
        redlinesOut.close();
        out.flush();
        InputStream redlines = new FileInputStream(redlinesTempFile);
        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = redlines.read(buffer)) != -1) outStream.write(buffer, 0, bytesRead);
        outStream.write("".getBytes());
        outStream.close();
        Browser.launch(outFile.toURL().toString());
    }


    public static boolean encodeFileToFile(String infile, String outfile) {
        boolean success = false;
        java.io.InputStream in = null;
        java.io.OutputStream out = null;
        try {
            in = new Base64.InputStream(new java.io.BufferedInputStream(new java.io.FileInputStream(infile)), Base64.ENCODE);
            out = new java.io.BufferedOutputStream(new java.io.FileOutputStream(outfile));
            byte[] buffer = new byte[65536];
            int read = -1;
            while ((read = in.read(buffer)) >= 0) {
                out.write(buffer, 0, read);
            }
            success = true;
        } catch (java.io.IOException exc) {
            exc.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (Exception exc) {
            }
            try {
                out.close();
            } catch (Exception exc) {
            }
        }
        return success;
    }


    public static boolean decodeFileToFile(String infile, String outfile) {
        boolean success = false;
        java.io.InputStream in = null;
        java.io.OutputStream out = null;
        try {
            in = new Base64.InputStream(new java.io.BufferedInputStream(new java.io.FileInputStream(infile)), Base64.DECODE);
            out = new java.io.BufferedOutputStream(new java.io.FileOutputStream(outfile));
            byte[] buffer = new byte[65536];
            int read = -1;
            while ((read = in.read(buffer)) >= 0) {
                out.write(buffer, 0, read);
            }
            success = true;
        } catch (java.io.IOException exc) {
            exc.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (Exception exc) {
            }
            try {
                out.close();
            } catch (Exception exc) {
            }
        }
        return success;
    }


    private String calculateMD5(String input) throws NoSuchAlgorithmException {
        MessageDigest digest = MessageDigest.getInstance("MD5");
        digest.reset();
        digest.update(input.getBytes());
        byte[] md5 = digest.digest();
        String tmp = "";
        String res = "";
        for (int i = 0; i < md5.length; i++) {
            tmp = (Integer.toHexString(0xFF & md5[i]));
            if (tmp.length() == 1) {
                res += "0" + tmp;
            } else {
                res += tmp;
            }
        }
        return res;
    }


    private void compress(String outputFile, ArrayList<String> inputFiles, PrintWriter log, boolean compress) throws Exception {
        String absPath = getAppConfig().getPathConfig().getAbsoluteServerPath();
        log.println("Concat files into: " + outputFile);
        OutputStream out = new FileOutputStream(absPath + outputFile);
        byte[] buffer = new byte[4096];
        int readBytes;
        for (String file : inputFiles) {
            log.println(" Read: " + file);
            InputStream in = new FileInputStream(absPath + file);
            while ((readBytes = in.read(buffer)) != -1) {
                out.write(buffer, 0, readBytes);
            }
            in.close();
        }
        out.close();
        if (compress) {
            long normalSize = new File(absPath + outputFile).length();
            ProcessBuilder builder = new ProcessBuilder("java", "-jar", "WEB-INF/yuicompressor.jar", outputFile, "-o", outputFile, "--line-break", "4000");
            builder.directory(new File(absPath));
            Process process = builder.start();
            process.waitFor();
            long minSize = new File(absPath + outputFile).length();
            long diff = normalSize - minSize;
            double percentage = Math.floor((double) diff / normalSize * 1000.0) / 10.0;
            double diffSize = (Math.floor(diff / 1024.0 * 10.0) / 10.0);
            log.println("Result: " + percentage + " % (" + diffSize + " KB)");
        }
    }


    private void handleInclude(Element elem) throws Exception {
        String source = getTextContent(elem);
        URL url = null;
        try {
            url = new URL(source);
        } catch (MalformedURLException e) {
            url = XmlConfig.class.getResource(source);
        }
        Document doc = db.parse(url.openStream());
        handleDocument(doc);
    }


    private byte[] streamToBytes(InputStream in) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            IOUtils.copy(in, out);
        } finally {
            IOUtils.closeQuietly(in);
        }
        return out.toByteArray();
    }


    public void convert(File src, File dest) throws IOException {
        InputStream in = new BufferedInputStream(new FileInputStream(src));
        DcmParser p = pfact.newDcmParser(in);
        Dataset ds = fact.newDataset();
        p.setDcmHandler(ds.getDcmHandler());
        try {
            FileFormat format = p.detectFileFormat();
            if (format != FileFormat.ACRNEMA_STREAM) {
                System.out.println("\n" + src + ": not an ACRNEMA stream!");
                return;
            }
            p.parseDcmFile(format, Tags.PixelData);
            if (ds.contains(Tags.StudyInstanceUID) || ds.contains(Tags.SeriesInstanceUID) || ds.contains(Tags.SOPInstanceUID) || ds.contains(Tags.SOPClassUID)) {
                System.out.println("\n" + src + ": contains UIDs!" + " => probable already DICOM - do not convert");
                return;
            }
            boolean hasPixelData = p.getReadTag() == Tags.PixelData;
            boolean inflate = hasPixelData && ds.getInt(Tags.BitsAllocated, 0) == 12;
            int pxlen = p.getReadLength();
            if (hasPixelData) {
                if (inflate) {
                    ds.putUS(Tags.BitsAllocated, 16);
                    pxlen = pxlen * 4 / 3;
                }
                if (pxlen != (ds.getInt(Tags.BitsAllocated, 0) >>> 3) * ds.getInt(Tags.Rows, 0) * ds.getInt(Tags.Columns, 0) * ds.getInt(Tags.NumberOfFrames, 1) * ds.getInt(Tags.NumberOfSamples, 1)) {
                    System.out.println("\n" + src + ": mismatch pixel data length!" + " => do not convert");
                    return;
                }
            }
            ds.putUI(Tags.StudyInstanceUID, uid(studyUID));
            ds.putUI(Tags.SeriesInstanceUID, uid(seriesUID));
            ds.putUI(Tags.SOPInstanceUID, uid(instUID));
            ds.putUI(Tags.SOPClassUID, classUID);
            if (!ds.contains(Tags.NumberOfSamples)) {
                ds.putUS(Tags.NumberOfSamples, 1);
            }
            if (!ds.contains(Tags.PhotometricInterpretation)) {
                ds.putCS(Tags.PhotometricInterpretation, "MONOCHROME2");
            }
            if (fmi) {
                ds.setFileMetaInfo(fact.newFileMetaInfo(ds, UIDs.ImplicitVRLittleEndian));
            }
            OutputStream out = new BufferedOutputStream(new FileOutputStream(dest));
            try {
            } finally {
                ds.writeFile(out, encodeParam());
                if (hasPixelData) {
                    if (!skipGroupLen) {
                        out.write(PXDATA_GROUPLEN);
                        int grlen = pxlen + 8;
                        out.write((byte) grlen);
                        out.write((byte) (grlen >> 8));
                        out.write((byte) (grlen >> 16));
                        out.write((byte) (grlen >> 24));
                    }
                    out.write(PXDATA_TAG);
                    out.write((byte) pxlen);
                    out.write((byte) (pxlen >> 8));
                    out.write((byte) (pxlen >> 16));
                    out.write((byte) (pxlen >> 24));
                }
                if (inflate) {
                    int b2, b3;
                    for (; pxlen > 0; pxlen -= 3) {
                        out.write(in.read());
                        b2 = in.read();
                        b3 = in.read();
                        out.write(b2 & 0x0f);
                        out.write(b2 >> 4 | ((b3 & 0x0f) << 4));
                        out.write(b3 >> 4);
                    }
                } else {
                    for (; pxlen > 0; --pxlen) {
                        out.write(in.read());
                    }
                }
                out.close();
            }
            System.out.print('.');
        } finally {
            in.close();
        }
    }


    private static void readAndRewrite(File inFile, File outFile) throws IOException {
        ImageInputStream iis = ImageIO.createImageInputStream(new BufferedInputStream(new FileInputStream(inFile)));
        DcmParser dcmParser = DcmParserFactory.getInstance().newDcmParser(iis);
        Dataset ds = DcmObjectFactory.getInstance().newDataset();
        dcmParser.setDcmHandler(ds.getDcmHandler());
        dcmParser.parseDcmFile(null, Tags.PixelData);
        PixelDataReader pdReader = pdFact.newReader(ds, iis, dcmParser.getDcmDecodeParam().byteOrder, dcmParser.getReadVR());
        System.out.println("reading " + inFile + "...");
        pdReader.readPixelData(false);
        ImageOutputStream out = ImageIO.createImageOutputStream(new BufferedOutputStream(new FileOutputStream(outFile)));
        DcmEncodeParam dcmEncParam = DcmEncodeParam.IVR_LE;
        ds.writeDataset(out, dcmEncParam);
        ds.writeHeader(out, dcmEncParam, Tags.PixelData, dcmParser.getReadVR(), dcmParser.getReadLength());
        System.out.println("writing " + outFile + "...");
        PixelDataWriter pdWriter = pdFact.newWriter(pdReader.getPixelDataArray(), false, ds, out, dcmParser.getDcmDecodeParam().byteOrder, dcmParser.getReadVR());
        pdWriter.writePixelData();
        out.flush();
        out.close();
        System.out.println("done!");
    }


    public BufferedWriter createOutputStream(String inFile, String outFile) throws IOException {
        int k_blockSize = 1024;
        int byteCount;
        char[] buf = new char[k_blockSize];
        File ofp = new File(outFile);
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(ofp));
        zos.setMethod(ZipOutputStream.DEFLATED);
        OutputStreamWriter osw = new OutputStreamWriter(zos, "ISO-8859-1");
        BufferedWriter bw = new BufferedWriter(osw);
        ZipEntry zot = null;
        File ifp = new File(inFile);
        ZipInputStream zis = new ZipInputStream(new FileInputStream(ifp));
        InputStreamReader isr = new InputStreamReader(zis, "ISO-8859-1");
        BufferedReader br = new BufferedReader(isr);
        ZipEntry zit = null;
        while ((zit = zis.getNextEntry()) != null) {
            if (zit.getName().equals("content.xml")) {
                continue;
            }
            zot = new ZipEntry(zit.getName());
            zos.putNextEntry(zot);
            while ((byteCount = br.read(buf, 0, k_blockSize)) >= 0) bw.write(buf, 0, byteCount);
            bw.flush();
            zos.closeEntry();
        }
        zos.putNextEntry(new ZipEntry("content.xml"));
        bw.flush();
        osw = new OutputStreamWriter(zos, "UTF8");
        bw = new BufferedWriter(osw);
        return bw;
    }


    public int down(String downLoadUrl, String saveUrl) {
        int status = 1;
        long fileSize = 0;
        int len = 0;
        byte[] bt = new byte[1024];
        RandomAccessFile raFile = null;
        long totalSize = 0;
        URL url = null;
        HttpURLConnection httpConn = null;
        BufferedInputStream bis = null;
        try {
            url = new URL(downLoadUrl);
            httpConn = (HttpURLConnection) url.openConnection();
            if (httpConn.getHeaderField("Content-Length") == null) {
                status = 500;
            } else {
                totalSize = Long.parseLong(httpConn.getHeaderField("Content-Length"));
                System.out.println("文件大小:" + totalSize / 1000000 + " M");
                httpConn.disconnect();
                httpConn = (HttpURLConnection) url.openConnection();
                fileSize = loadFileSize(saveUrl + BACK_SUFFIX);
                System.out.println("已下载:" + fileSize / 1000000 + " M");
                httpConn.setRequestProperty("RANGE", "bytes=" + fileSize + "-");
                httpConn.setRequestProperty("Accept", "image/gif,image/x-xbitmap,application/msword,*/*");
                raFile = new RandomAccessFile(saveUrl + BACK_SUFFIX, "rw");
                raFile.seek(fileSize);
                bis = new BufferedInputStream(httpConn.getInputStream());
                while ((len = bis.read(bt)) > 0) {
                    raFile.write(bt, 0, len);
                    float progress = 0.f;
                    float downSize = raFile.length();
                    progress = downSize / totalSize;
                    System.out.println(progress * 100 + "%" + "\t\t" + downSize / 1000000 + "M");
                }
            }
        } catch (FileNotFoundException e) {
            status = 404;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (bis != null) bis.close();
                if (raFile != null) raFile.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (loadFileSize(saveUrl + BACK_SUFFIX) == totalSize) {
            fileRename(saveUrl + BACK_SUFFIX, saveUrl);
        }
        return status;
    }


    public String encrypt(final char[] password, final String algorithm, final byte[] salt) {
        final StringBuffer buffer = new StringBuffer();
        MessageDigest digest = null;
        int size = 0;
        if ("SHA".equalsIgnoreCase(algorithm) || "SSHA".equalsIgnoreCase(algorithm)) {
            size = 20;
            if ((salt != null) && (salt.length > 0)) {
                buffer.append("{SSHA}");
            } else {
                buffer.append("{SHA}");
            }
            try {
                digest = MessageDigest.getInstance("SHA-1");
            } catch (final NoSuchAlgorithmException e) {
                throw new IllegalStateException("Invalid algorithm");
            }
        } else if ("MD5".equalsIgnoreCase(algorithm) || "SMD5".equalsIgnoreCase(algorithm)) {
            size = 16;
            if ((salt != null) && (salt.length > 0)) {
                buffer.append("{SMD5}");
            } else {
                buffer.append("{MD5}");
            }
            try {
                digest = MessageDigest.getInstance("MD5");
            } catch (final NoSuchAlgorithmException e) {
                throw new IllegalStateException("Invalid algorithm");
            }
        } else {
            throw new UnsupportedOperationException("Not implemented");
        }
        int outSize = size;
        digest.reset();
        try {
            digest.update(new String(password).getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            throw new IllegalStateException("UTF-8 Unsupported");
        }
        if ((salt != null) && (salt.length > 0)) {
            digest.update(salt);
            outSize += salt.length;
        }
        final byte[] out = new byte[outSize];
        System.arraycopy(digest.digest(), 0, out, 0, size);
        if ((salt != null) && (salt.length > 0)) {
            System.arraycopy(salt, 0, out, size, salt.length);
        }
        buffer.append(new String(Base64.encodeBase64(out)));
        return buffer.toString();
    }


    public boolean verify(final char[] password, final String encryptedPassword) {
        MessageDigest digest = null;
        int size = 0;
        String base64 = null;
        if (encryptedPassword.regionMatches(true, 0, "{SHA}", 0, 5)) {
            size = 20;
            base64 = encryptedPassword.substring(5);
            try {
                digest = MessageDigest.getInstance("SHA-1");
            } catch (final NoSuchAlgorithmException e) {
                throw new IllegalStateException("Invalid algorithm");
            }
        } else if (encryptedPassword.regionMatches(true, 0, "{SSHA}", 0, 6)) {
            size = 20;
            base64 = encryptedPassword.substring(6);
            try {
                digest = MessageDigest.getInstance("SHA-1");
            } catch (final NoSuchAlgorithmException e) {
                throw new IllegalStateException("Invalid algorithm");
            }
        } else if (encryptedPassword.regionMatches(true, 0, "{MD5}", 0, 5)) {
            size = 16;
            base64 = encryptedPassword.substring(5);
            try {
                digest = MessageDigest.getInstance("MD5");
            } catch (final NoSuchAlgorithmException e) {
                throw new IllegalStateException("Invalid algorithm");
            }
        } else if (encryptedPassword.regionMatches(true, 0, "{SMD5}", 0, 6)) {
            size = 16;
            base64 = encryptedPassword.substring(6);
            try {
                digest = MessageDigest.getInstance("MD5");
            } catch (final NoSuchAlgorithmException e) {
                throw new IllegalStateException("Invalid algorithm");
            }
        } else {
            return false;
        }
        try {
            final byte[] data = Base64.decodeBase64(base64.getBytes("UTF-8"));
            final byte[] orig = new byte[size];
            System.arraycopy(data, 0, orig, 0, size);
            digest.reset();
            digest.update(new String(password).getBytes("UTF-8"));
            if (data.length > size) {
                digest.update(data, size, data.length - size);
            }
            return MessageDigest.isEqual(digest.digest(), orig);
        } catch (UnsupportedEncodingException e) {
            throw new IllegalStateException("UTF-8 Unsupported");
        }
    }


    public Configuration(URL url) {
        InputStream in = null;
        try {
            load(in = url.openStream());
        } catch (Exception e) {
            throw new RuntimeException("Could not load configuration from " + url, e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException ignore) {
                }
            }
        }
    }


    public static void fixEol(File fin) throws IOException {
        File fout = File.createTempFile(fin.getName(), ".fixEol", fin.getParentFile());
        FileChannel in = new FileInputStream(fin).getChannel();
        if (0 != in.size()) {
            FileChannel out = new FileOutputStream(fout).getChannel();
            byte[] eol = AStringUtilities.systemNewLine.getBytes();
            ByteBuffer bufOut = ByteBuffer.allocateDirect(1024 * eol.length);
            boolean previousIsCr = false;
            ByteBuffer buf = ByteBuffer.allocateDirect(1024);
            while (in.read(buf) > 0) {
                buf.limit(buf.position());
                buf.position(0);
                while (buf.remaining() > 0) {
                    byte b = buf.get();
                    if (b == '\r') {
                        previousIsCr = true;
                        bufOut.put(eol);
                    } else {
                        if (b == '\n') {
                            if (!previousIsCr) bufOut.put(eol);
                        } else bufOut.put(b);
                        previousIsCr = false;
                    }
                }
                bufOut.limit(bufOut.position());
                bufOut.position(0);
                out.write(bufOut);
                bufOut.clear();
                buf.clear();
            }
            out.close();
        }
        in.close();
        fin.delete();
        fout.renameTo(fin);
    }


    public static void copyFile(File dst, File src, boolean append) throws FileNotFoundException, IOException {
        dst.createNewFile();
        FileChannel in = new FileInputStream(src).getChannel();
        FileChannel out = new FileOutputStream(dst).getChannel();
        long startAt = 0;
        if (append) startAt = out.size();
        in.transferTo(startAt, in.size(), out);
        out.close();
        in.close();
    }


    private String getSearchResults(String id) {
        try {
            final URL url = new URL("http://www.jaap.nl/api/jaapAPI.do?clientId=iPhone&limit=5&request=details&id=" + id + "&format=JSON&field=street_nr&field=zip&field=city&field=price&field=thumb&field=since&field=houseType&field=area&field=rooms&field=id");
            final StringBuilder builder = new StringBuilder();
            final BufferedReader rd = new BufferedReader(new InputStreamReader(url.openStream()));
            String s = "";
            while ((s = rd.readLine()) != null) {
                builder.append(s);
            }
            rd.close();
            return builder.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public static void doVersionCheck(View view) {
        view.showWaitCursor();
        try {
            URL url = new URL(jEdit.getProperty("version-check.url"));
            InputStream in = url.openStream();
            BufferedReader bin = new BufferedReader(new InputStreamReader(in));
            String line;
            String develBuild = null;
            String stableBuild = null;
            while ((line = bin.readLine()) != null) {
                if (line.startsWith(".build")) develBuild = line.substring(6).trim(); else if (line.startsWith(".stablebuild")) stableBuild = line.substring(12).trim();
            }
            bin.close();
            if (develBuild != null && stableBuild != null) {
                doVersionCheck(view, stableBuild, develBuild);
            }
        } catch (IOException e) {
            String[] args = { jEdit.getProperty("version-check.url"), e.toString() };
            GUIUtilities.error(view, "read-error", args);
        }
        view.hideWaitCursor();
    }


    public String GetUserPage(String User, int pagetocrawl) {
        int page = pagetocrawl;
        URL url;
        String line, finalstring;
        StringBuffer buffer = new StringBuffer();
        setStatus("Start moling....");
        startTimer();
        try {
            url = new URL(HTMLuserpage + User + "?setcount=100&page=" + page);
            HttpURLConnection connect = (HttpURLConnection) url.openConnection();
            connect.addRequestProperty("User-Agent", userAgent);
            System.out.println("moling: page " + page + " of " + User);
            BufferedReader input = new BufferedReader(new InputStreamReader(connect.getInputStream()));
            while ((line = input.readLine()) != null) {
                buffer.append(line);
                buffer.append("\n");
            }
            input.close();
            connect.disconnect();
            stopTimer();
            setStatus("Dauer : " + dauerMs() + " ms");
            finalstring = buffer.toString();
            return finalstring;
        } catch (MalformedURLException e) {
            System.err.println("Bad URL: " + e);
            return null;
        } catch (IOException io) {
            System.err.println("IOException: " + io);
            return null;
        }
    }


    static String fetchURLComposeExternPackageList(String urlpath, String pkglisturlpath) {
        String link = pkglisturlpath + "package-list";
        try {
            boolean relative = isRelativePath(urlpath);
            readPackageList((new URL(link)).openStream(), urlpath, relative);
        } catch (MalformedURLException exc) {
            return getText("doclet.MalformedURL", link);
        } catch (IOException exc) {
            return getText("doclet.URL_error", link);
        }
        return null;
    }


    private static String getData(String myurl) throws Exception {
        URL url = new URL(myurl);
        uc = (HttpURLConnection) url.openConnection();
        if (login) {
            uc.setRequestProperty("Cookie", usercookie + ";" + pwdcookie);
        }
        br = new BufferedReader(new InputStreamReader(uc.getInputStream()));
        String temp = "", k = "";
        while ((temp = br.readLine()) != null) {
            k += temp;
        }
        br.close();
        return k;
    }


    private static void fileUpload() throws IOException {
        HttpClient httpclient = new DefaultHttpClient();
        if (login) {
            postURL = "http://upload.badongo.com/mpu_upload.php";
        }
        HttpPost httppost = new HttpPost(postURL);
        file = new File("g:/S2SClient.7z");
        MultipartEntity mpEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
        ContentBody cbFile = new FileBody(file);
        mpEntity.addPart("Filename", new StringBody(file.getName()));
        if (login) {
            mpEntity.addPart("PHPSESSID", new StringBody(dataid));
        }
        mpEntity.addPart("Filedata", cbFile);
        httppost.setEntity(mpEntity);
        System.out.println("executing request " + httppost.getRequestLine());
        System.out.println("Now uploading your file into badongo.com");
        HttpResponse response = httpclient.execute(httppost);
        HttpEntity resEntity = response.getEntity();
        System.out.println("Upload response : " + uploadresponse);
        System.out.println(response.getStatusLine());
        if (resEntity != null) {
            uploadresponse = EntityUtils.toString(resEntity);
        }
        System.out.println("res " + uploadresponse);
        httpclient.getConnectionManager().shutdown();
    }


    public static void buildDeb(File debFile, File controlFile, File dataFile) throws IOException {
        long now = new Date().getTime() / 1000;
        OutputStream deb = new FileOutputStream(debFile);
        deb.write("!<arch>\n".getBytes());
        startFileEntry(deb, DEBIAN_BINARY_NAME, now, DEBIAN_BINARY_CONTENT.length());
        deb.write(DEBIAN_BINARY_CONTENT.getBytes());
        endFileEntry(deb, DEBIAN_BINARY_CONTENT.length());
        startFileEntry(deb, CONTROL_NAME, now, controlFile.length());
        FileInputStream control = new FileInputStream(controlFile);
        byte[] buffer = new byte[1024];
        while (true) {
            int read = control.read(buffer);
            if (read == -1) break;
            deb.write(buffer, 0, read);
        }
        control.close();
        endFileEntry(deb, controlFile.length());
        startFileEntry(deb, DATA_NAME, now, dataFile.length());
        FileInputStream data = new FileInputStream(dataFile);
        while (true) {
            int read = data.read(buffer);
            if (read == -1) break;
            deb.write(buffer, 0, read);
        }
        data.close();
        endFileEntry(deb, dataFile.length());
        deb.close();
    }


    public void viewFile(int file_nx) {
        FTPClient ftp = new FTPClient();
        boolean error = false;
        try {
            int reply;
            ftp.connect("tgftp.nws.noaa.gov");
            ftp.login("anonymous", "");
            Log.d("WXDroid", "Connected to tgftp.nws.noaa.gov.");
            Log.d("WXDroid", ftp.getReplyString());
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                System.err.println("FTP server refused connection.");
                System.exit(1);
            }
            ftp.changeWorkingDirectory("fax");
            Log.d("WXDroid", "working directory: " + ftp.printWorkingDirectory());
            ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
            InputStream img_file = ftp.retrieveFileStream("PYAA10.gif");
            String storage_state = Environment.getExternalStorageState();
            if (storage_state.contains("mounted")) {
                String filepath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/NOAAWX/";
                File imageDirectory = new File(filepath);
                File local_file = new File(filepath + "PYAA10.gif");
                OutputStream out = new FileOutputStream(local_file);
                byte[] buffer = new byte[1024];
                int count;
                while ((count = img_file.read(buffer)) != -1) {
                    if (Thread.interrupted() == true) {
                        String functionName = Thread.currentThread().getStackTrace()[2].getMethodName() + "()";
                        throw new InterruptedException("The function " + functionName + " was interrupted.");
                    }
                    out.write(buffer, 0, count);
                }
                wxDroid.showImage();
                out.flush();
                out.close();
                img_file.close();
                Log.d("WXDroid", "file saved: " + filepath + " " + local_file);
            } else {
                Log.d("WXDroid", "The SD card is not mounted");
            }
            ftp.logout();
            ftp.disconnect();
        } catch (IOException e) {
            error = true;
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
    }


    public String insertSmsInf(Sms sms) throws Exception {
        String smsId = null;
        Connection conn = null;
        PreparedStatement pstmt = null;
        StringBuffer buffer = new StringBuffer();
        try {
            buffer.append("INSERT INTO COMTNSMS\n");
            buffer.append("  (SMS_ID, TRNSMIS_TELNO, TRNSMIS_CN,\n");
            buffer.append("   FRST_REGISTER_ID, FRST_REGIST_PNTTM )\n");
            buffer.append("VALUES\n");
            buffer.append("(?, ?, ?, ?, SYSDATE())");
            conn = SmsBasicDBUtil.getConnection();
            conn.setAutoCommit(false);
            smsId = getNextId(conn);
            pstmt = conn.prepareStatement(buffer.toString());
            int index = 0;
            pstmt.setString(++index, smsId);
            pstmt.setString(++index, sms.getTrnsmitTelno());
            pstmt.setString(++index, sms.getTrnsmitCn());
            pstmt.setString(++index, sms.getFrstRegisterId());
            pstmt.executeUpdate();
            conn.commit();
            return smsId;
        } catch (Exception ex) {
            if (conn != null) {
                conn.rollback();
            }
            throw ex;
        } finally {
            SmsBasicDBUtil.close(null, pstmt, conn);
        }
    }


    public void process(String dir) {
        String[] list = new File(dir).list();
        if (list == null) return;
        int n = list.length;
        long[] bubblesort = new long[list.length + 1];
        if (!statustext) {
            IJ.log("Current Directory is: " + dir);
            IJ.log(" ");
            IJ.log("DICOM File Name / " + prefix1 + " / " + prefix2 + " / " + prefix3 + " / " + pick);
            IJ.log(" ");
        }
        for (int i = 0; i < n; i++) {
            IJ.showStatus(i + "/" + n);
            File f = new File(dir + list[i]);
            if (!f.isDirectory()) {
                ImagePlus img = new Opener().openImage(dir, list[i]);
                if (img != null && img.getStackSize() == 1) {
                    if (!scoutengine(img)) return;
                    if (!statustext) {
                        IJ.log(list[i] + "/" + whichprefix1 + "/" + whichprefix2 + "/" + whichprefix3 + "/" + whichcase);
                    }
                    int lastDigit = whichcase.length() - 1;
                    while (lastDigit > 0) {
                        if (!Character.isDigit(whichcase.charAt(lastDigit))) lastDigit -= 1; else break;
                    }
                    if (lastDigit < whichcase.length() - 1) whichcase = whichcase.substring(0, lastDigit + 1);
                    bubblesort[i] = Long.parseLong(whichcase);
                }
            }
        }
        if (statussorta || statussortd || statustext) {
            boolean sorted = false;
            while (!sorted) {
                sorted = true;
                for (int i = 0; i < n - 1; i++) {
                    if (statussorta) {
                        if (bubblesort[i] > bubblesort[i + 1]) {
                            long temp = bubblesort[i];
                            tempp = list[i];
                            bubblesort[i] = bubblesort[i + 1];
                            list[i] = list[i + 1];
                            bubblesort[i + 1] = temp;
                            list[i + 1] = tempp;
                            sorted = false;
                        }
                    } else {
                        if (bubblesort[i] < bubblesort[i + 1]) {
                            long temp = bubblesort[i];
                            tempp = list[i];
                            bubblesort[i] = bubblesort[i + 1];
                            list[i] = list[i + 1];
                            bubblesort[i + 1] = temp;
                            list[i + 1] = tempp;
                            sorted = false;
                        }
                    }
                }
            }
            IJ.log(" ");
            for (int i = 0; i < n; i++) {
                if (!statustext) {
                    IJ.log(list[i] + " / " + bubblesort[i]);
                } else {
                    IJ.log(dir + list[i]);
                }
            }
        }
        if (open_as_stack || only_images) {
            boolean sorted = false;
            while (!sorted) {
                sorted = true;
                for (int i = 0; i < n - 1; i++) {
                    if (bubblesort[i] > bubblesort[i + 1]) {
                        long temp = bubblesort[i];
                        tempp = list[i];
                        bubblesort[i] = bubblesort[i + 1];
                        list[i] = list[i + 1];
                        bubblesort[i + 1] = temp;
                        list[i + 1] = tempp;
                        sorted = false;
                    }
                }
            }
            if (only_images) {
                Opener o = new Opener();
                int counter = 0;
                IJ.log(" ");
                for (int i = 0; i < n; i++) {
                    String path = (dir + list[i]);
                    if (path == null) break; else {
                        ImagePlus imp = o.openImage(path);
                        counter++;
                        if (imp != null) {
                            IJ.log(counter + " + " + path);
                            imp.show();
                        } else IJ.log(counter + " - " + path);
                    }
                }
                return;
            }
            int width = 0, height = 0, type = 0;
            ImageStack stack = null;
            double min = Double.MAX_VALUE;
            double max = -Double.MAX_VALUE;
            int k = 0;
            try {
                for (int i = 0; i < n; i++) {
                    String path = (dir + list[i]);
                    if (path == null) break;
                    if (list[i].endsWith(".txt")) continue;
                    ImagePlus imp = new Opener().openImage(path);
                    if (imp != null && stack == null) {
                        width = imp.getWidth();
                        height = imp.getHeight();
                        type = imp.getType();
                        ColorModel cm = imp.getProcessor().getColorModel();
                        if (halfSize) stack = new ImageStack(width / 2, height / 2, cm); else stack = new ImageStack(width, height, cm);
                    }
                    if (stack != null) k = stack.getSize() + 1;
                    IJ.showStatus(k + "/" + n);
                    IJ.showProgress((double) k / n);
                    if (imp == null) IJ.log(list[i] + ": unable to open"); else if (imp.getWidth() != width || imp.getHeight() != height) IJ.log(list[i] + ": wrong dimensions"); else if (imp.getType() != type) IJ.log(list[i] + ": wrong type"); else {
                        ImageProcessor ip = imp.getProcessor();
                        if (grayscale) ip = ip.convertToByte(true);
                        if (halfSize) ip = ip.resize(width / 2, height / 2);
                        if (ip.getMin() < min) min = ip.getMin();
                        if (ip.getMax() > max) max = ip.getMax();
                        String label = imp.getTitle();
                        String info = (String) imp.getProperty("Info");
                        if (info != null) label += "\n" + info;
                        stack.addSlice(label, ip);
                    }
                    System.gc();
                }
            } catch (OutOfMemoryError e) {
                IJ.outOfMemory("FolderOpener");
                stack.trim();
            }
            if (stack != null && stack.getSize() > 0) {
                ImagePlus imp2 = new ImagePlus("Stack", stack);
                if (imp2.getType() == ImagePlus.GRAY16 || imp2.getType() == ImagePlus.GRAY32) imp2.getProcessor().setMinAndMax(min, max);
                imp2.show();
            }
            IJ.showProgress(1.0);
        }
    }


    private static void main(String[] args) {
        try {
            File f = new File("test.txt");
            if (f.exists()) {
                throw new IOException(f + " already exists.  I don't want to overwrite it.");
            }
            StraightStreamReader in;
            char[] cbuf = new char[0x1000];
            int read;
            int totRead;
            FileOutputStream out = new FileOutputStream(f);
            for (int i = 0x00; i < 0x100; i++) {
                out.write(i);
            }
            out.close();
            in = new StraightStreamReader(new FileInputStream(f));
            for (int i = 0x00; i < 0x100; i++) {
                read = in.read();
                if (read != i) {
                    System.err.println("Error: " + i + " read as " + read);
                }
            }
            in.close();
            in = new StraightStreamReader(new FileInputStream(f));
            totRead = in.read(cbuf);
            if (totRead != 0x100) {
                System.err.println("Simple buffered read did not read the full amount: 0x" + Integer.toHexString(totRead));
            }
            for (int i = 0x00; i < totRead; i++) {
                if (cbuf[i] != i) {
                    System.err.println("Error: 0x" + i + " read as 0x" + cbuf[i]);
                }
            }
            in.close();
            in = new StraightStreamReader(new FileInputStream(f));
            totRead = 0;
            while (totRead <= 0x100 && (read = in.read(cbuf, totRead, 0x100 - totRead)) > 0) {
                totRead += read;
            }
            if (totRead != 0x100) {
                System.err.println("Not enough read. Bytes read: " + Integer.toHexString(totRead));
            }
            for (int i = 0x00; i < totRead; i++) {
                if (cbuf[i] != i) {
                    System.err.println("Error: 0x" + i + " read as 0x" + cbuf[i]);
                }
            }
            in.close();
            in = new StraightStreamReader(new FileInputStream(f));
            totRead = 0;
            while (totRead <= 0x100 && (read = in.read(cbuf, totRead + 0x123, 0x100 - totRead)) > 0) {
                totRead += read;
            }
            if (totRead != 0x100) {
                System.err.println("Not enough read. Bytes read: " + Integer.toHexString(totRead));
            }
            for (int i = 0x00; i < totRead; i++) {
                if (cbuf[i + 0x123] != i) {
                    System.err.println("Error: 0x" + i + " read as 0x" + cbuf[i + 0x123]);
                }
            }
            in.close();
            in = new StraightStreamReader(new FileInputStream(f));
            totRead = 0;
            while (totRead <= 0x100 && (read = in.read(cbuf, totRead + 0x123, 7)) > 0) {
                totRead += read;
            }
            if (totRead != 0x100) {
                System.err.println("Not enough read. Bytes read: " + Integer.toHexString(totRead));
            }
            for (int i = 0x00; i < totRead; i++) {
                if (cbuf[i + 0x123] != i) {
                    System.err.println("Error: 0x" + i + " read as 0x" + cbuf[i + 0x123]);
                }
            }
            in.close();
            f.delete();
        } catch (IOException x) {
            System.err.println(x.getMessage());
        }
    }


private void displayDiffResults() throws IOException {
        File outFile = File.createTempFile("diff", ".htm");
        outFile.deleteOnExit();
        FileOutputStream outStream = new FileOutputStream(outFile);
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(outStream));
        out.write("<title>LOC Differences</title>\n" + SCRIPT + "\n" + "\n" + "
\n");
        if (addedTable.length() > 0) {
            out.write("

Files Added:	" + "Add	Type
");
            out.write(addedTable.toString());
            out.write("

");
        }
        if (modifiedTable.length() > 0) {
            out.write("

Files Modified:	" + "Base	Del	Mod	Add	" + "Total	Type
");
            out.write(modifiedTable.toString());
            out.write("

");
        }
        if (deletedTable.length() > 0) {
            out.write("

Files Deleted:	" + "Del	Type
");
            out.write(deletedTable.toString());
            out.write("

");
        }
        out.write("
\n");
        if (modifiedTable.length() > 0 || deletedTable.length() > 0) {
            out.write("
Base: 	");
            out.write(Long.toString(base));
            out.write("
\n
Deleted: 	");
            out.write(Long.toString(deleted));
            out.write("
\n
Modified: 	");
            out.write(Long.toString(modified));
            out.write("
\n
Added: 	");
            out.write(Long.toString(added));
            out.write("
\n
New & Changed: 	");
            out.write(Long.toString(added + modified));
            out.write("
\n");
        }
        out.write("
Total: 	");
        out.write(Long.toString(total));
        out.write("
\n

");
        redlinesOut.close();
        out.flush();
        InputStream redlines = new FileInputStream(redlinesTempFile);
        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = redlines.read(buffer)) != -1) outStream.write(buffer, 0, bytesRead);
        outStream.write("".getBytes());
        outStream.close();
        Browser.launch(outFile.toURL().toString());
    }


    public BufferedWriter createOutputStream(String inFile, String outFile) throws IOException {
        int k_blockSize = 1024;
        int byteCount;
        char[] buf = new char[k_blockSize];
        File ofp = new File(outFile);
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(ofp));
        zos.setMethod(ZipOutputStream.DEFLATED);
        OutputStreamWriter osw = new OutputStreamWriter(zos, "ISO-8859-1");
        BufferedWriter bw = new BufferedWriter(osw);
        ZipEntry zot = null;
        File ifp = new File(inFile);
        ZipInputStream zis = new ZipInputStream(new FileInputStream(ifp));
        InputStreamReader isr = new InputStreamReader(zis, "ISO-8859-1");
        BufferedReader br = new BufferedReader(isr);
        ZipEntry zit = null;
        while ((zit = zis.getNextEntry()) != null) {
            if (zit.getName().equals("content.xml")) {
                continue;
            }
            zot = new ZipEntry(zit.getName());
            zos.putNextEntry(zot);
            while ((byteCount = br.read(buf, 0, k_blockSize)) >= 0) bw.write(buf, 0, byteCount);
            bw.flush();
            zos.closeEntry();
        }
        zos.putNextEntry(new ZipEntry("content.xml"));
        bw.flush();
        osw = new OutputStreamWriter(zos, "UTF8");
        bw = new BufferedWriter(osw);
        return bw;
    }


    public void copyTo(Bean bean, OutputStream out, int offset, int length) throws Exception {
        BeanInfo beanInfo = getBeanInfo(bean.getClass());
        validate(bean, beanInfo, "copyTo");
        if (blobCache != null && length < MAX_BLOB_CACHE_LENGHT) {
            byte[] bytes = null;
            synchronized (this) {
                String key = makeUniqueKey(bean, beanInfo, offset, length);
                if (blobCache.contains(key)) bytes = (byte[]) blobCache.get(key); else blobCache.put(key, bytes = toByteArray(bean, offset, length, beanInfo));
            }
            InputStream in = new ByteArrayInputStream(bytes);
            IOUtils.copy(in, out);
            in.close();
        } else {
            jdbcManager.queryScript(beanInfo.getBlobInfo(jdbcManager.getDb()).getReadScript(), bean, new JdbcOutputStreamRowMapper(out, offset, length));
        }
    }


    public String stringOfUrl(String addr) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        URL url = new URL(addr);
        IOUtils.copy(url.openStream(), output);
        return output.toString();
    }


    public Image getURLImage(String url) {
        if (!images.containsKey(url)) {
            try {
                URL img = new URL(url);
                images.put(url, new Image(null, img.openStream()));
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage() + ": " + url);
            }
        }
        imageTimes.put(url, System.currentTimeMillis());
        return images.get(url);
    }


    private String executeHttpPreload(HttpResponse response, String xml) throws Exception {
        GadgetSpec spec = new GadgetSpec(GADGET_URL, xml);
        RecordingRequestPipeline pipeline = new RecordingRequestPipeline(response);
        PipelinedDataPreloader preloader = new PipelinedDataPreloader(pipeline, containerConfig);
        view = "profile";
        Gadget gadget = new Gadget().setContext(context).setSpec(spec).setCurrentView(spec.getView("profile"));
        PipelinedData.Batch batch = getBatch(gadget);
        Collection<Callable<PreloadedData>> tasks = preloader.createPreloadTasks(context, batch);
        assertEquals(1, tasks.size());
        assertEquals(0, pipeline.requests.size());
        Collection<Object> result = tasks.iterator().next().call().toJson();
        assertEquals(1, result.size());
        assertEquals(1, pipeline.requests.size());
        HttpRequest request = pipeline.requests.get(0);
        assertEquals(HTTP_REQUEST_URL, request.getUri().toString());
        assertEquals("POST", request.getMethod());
        assertEquals(60, request.getCacheTtl());
        return result.iterator().next().toString();
    }


    @org.junit.Test
    public void testReadWrite() throws Exception {
        final byte[] testBytes = "testString".getBytes();
        final InputStream istream = new ByteArrayInputStream(testBytes);
        final ByteArrayOutputStream destination = new ByteArrayOutputStream();
        final InputStream teeStream = new TeeInputStreamOutputStream(istream, destination);
        IOUtils.copy(teeStream, new NullOutputStream());
        teeStream.close();
        assertArrayEquals("array are equals", testBytes, destination.toByteArray());
    }


    public void convert(File src, File dest) throws IOException {
        InputStream in = new BufferedInputStream(new FileInputStream(src));
        DcmParser p = pfact.newDcmParser(in);
        Dataset ds = fact.newDataset();
        p.setDcmHandler(ds.getDcmHandler());
        try {
            FileFormat format = p.detectFileFormat();
            if (format != FileFormat.ACRNEMA_STREAM) {
                System.out.println("\n" + src + ": not an ACRNEMA stream!");
                return;
            }
            p.parseDcmFile(format, Tags.PixelData);
            if (ds.contains(Tags.StudyInstanceUID) || ds.contains(Tags.SeriesInstanceUID) || ds.contains(Tags.SOPInstanceUID) || ds.contains(Tags.SOPClassUID)) {
                System.out.println("\n" + src + ": contains UIDs!" + " => probable already DICOM - do not convert");
                return;
            }
            boolean hasPixelData = p.getReadTag() == Tags.PixelData;
            boolean inflate = hasPixelData && ds.getInt(Tags.BitsAllocated, 0) == 12;
            int pxlen = p.getReadLength();
            if (hasPixelData) {
                if (inflate) {
                    ds.putUS(Tags.BitsAllocated, 16);
                    pxlen = pxlen * 4 / 3;
                }
                if (pxlen != (ds.getInt(Tags.BitsAllocated, 0) >>> 3) * ds.getInt(Tags.Rows, 0) * ds.getInt(Tags.Columns, 0) * ds.getInt(Tags.NumberOfFrames, 1) * ds.getInt(Tags.NumberOfSamples, 1)) {
                    System.out.println("\n" + src + ": mismatch pixel data length!" + " => do not convert");
                    return;
                }
            }
            ds.putUI(Tags.StudyInstanceUID, uid(studyUID));
            ds.putUI(Tags.SeriesInstanceUID, uid(seriesUID));
            ds.putUI(Tags.SOPInstanceUID, uid(instUID));
            ds.putUI(Tags.SOPClassUID, classUID);
            if (!ds.contains(Tags.NumberOfSamples)) {
                ds.putUS(Tags.NumberOfSamples, 1);
            }
            if (!ds.contains(Tags.PhotometricInterpretation)) {
                ds.putCS(Tags.PhotometricInterpretation, "MONOCHROME2");
            }
            if (fmi) {
                ds.setFileMetaInfo(fact.newFileMetaInfo(ds, UIDs.ImplicitVRLittleEndian));
            }
            OutputStream out = new BufferedOutputStream(new FileOutputStream(dest));
            try {
            } finally {
                ds.writeFile(out, encodeParam());
                if (hasPixelData) {
                    if (!skipGroupLen) {
                        out.write(PXDATA_GROUPLEN);
                        int grlen = pxlen + 8;
                        out.write((byte) grlen);
                        out.write((byte) (grlen >> 8));
                        out.write((byte) (grlen >> 16));
                        out.write((byte) (grlen >> 24));
                    }
                    out.write(PXDATA_TAG);
                    out.write((byte) pxlen);
                    out.write((byte) (pxlen >> 8));
                    out.write((byte) (pxlen >> 16));
                    out.write((byte) (pxlen >> 24));
                }
                if (inflate) {
                    int b2, b3;
                    for (; pxlen > 0; pxlen -= 3) {
                        out.write(in.read());
                        b2 = in.read();
                        b3 = in.read();
                        out.write(b2 & 0x0f);
                        out.write(b2 >> 4 | ((b3 & 0x0f) << 4));
                        out.write(b3 >> 4);
                    }
                } else {
                    for (; pxlen > 0; --pxlen) {
                        out.write(in.read());
                    }
                }
                out.close();
            }
            System.out.print('.');
        } finally {
            in.close();
        }
    }


    private synchronized boolean saveU(URL url, String typeFlag, byte[] arrByte) {
        BufferedReader buffReader = null;
        BufferedOutputStream buffOS = null;
        URLConnection urlconnection = null;
        char flagChar = '0';
        boolean flag = true;
        try {
            urlconnection = url.openConnection();
            urlconnection.setDoOutput(true);
            urlconnection.setDoInput(true);
            urlconnection.setUseCaches(false);
            urlconnection.setRequestProperty("Content-type", "application/octet-stream");
            buffOS = new BufferedOutputStream(urlconnection.getOutputStream());
            buffOS.write((byte[]) typeFlag.getBytes());
            buffOS.write(arrByte);
            buffOS.flush();
            if (Config.DEBUG) System.out.println("Applet output file successfully! ");
            buffReader = new BufferedReader(new InputStreamReader(urlconnection.getInputStream()));
            StringBuffer stringBuff = new StringBuffer();
            String serReturnMess = buffReader.readLine();
            if (Config.DEBUG) System.out.println("Applet check status successfully! " + serReturnMess);
            flagChar = '2';
            if (serReturnMess != null) {
                stringBuff.append(serReturnMess);
                serReturnMess = serReturnMess.substring(serReturnMess.indexOf(32)).trim() + '2';
                flagChar = serReturnMess.charAt(0);
            }
            while ((serReturnMess = buffReader.readLine()) != null) {
                if (serReturnMess.length() <= 0) break;
            }
        } catch (Throwable e) {
            e.printStackTrace();
            return false;
        } finally {
            try {
                if (buffOS != null) buffOS.close();
                if (buffReader != null) buffReader.close();
            } catch (Throwable e) {
                e.printStackTrace();
            }
            if (flagChar == '2' || flagChar == '3') flag = true; else flag = false;
        }
        return flag;
    }


    public static void putNextJarEntry(JarOutputStream modelStream, String name, File file) throws IOException {
        JarEntry entry = new JarEntry(name);
        entry.setSize(file.length());
        modelStream.putNextEntry(entry);
        InputStream fileStream = new BufferedInputStream(new FileInputStream(file));
        IOUtils.copy(fileStream, modelStream);
        fileStream.close();
    }


    public Collection<Module> loadModules() {
        URL url = getClass().getResource("/modules.xml");
        if (url == null) {
            java.util.logging.Logger.getLogger(ModuleLoader.class.getName()).log(java.util.logging.Level.SEVERE, "Cannot find modules.xml file in classpath");
            return Collections.<Module>emptyList();
        }
        DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance();
        Document document = null;
        InputStream input = null;
        try {
            input = url.openStream();
            DocumentBuilder bui = fac.newDocumentBuilder();
            document = bui.parse(url.openStream());
        } catch (SAXException ex) {
            Logger.getLogger(ModuleLoader.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(ModuleLoader.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(ModuleLoader.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException ex) {
                    Logger.getLogger(ModuleLoader.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        if (document == null) {
            return Collections.<Module>emptyList();
        }
        List<Module> modules = new LinkedList<Module>();
        NodeList moduleListNodes = document.getElementsByTagName("module-list");
        for (int i = 0; i < moduleListNodes.getLength(); i++) {
            Element moduleListNode = (Element) moduleListNodes.item(i);
            NodeList moduleNodes = moduleListNode.getElementsByTagName("module");
            for (int j = 0; j < moduleNodes.getLength(); j++) {
                Element moduleNode = (Element) moduleNodes.item(j);
                String moduleClass = moduleNode.getAttribute("class");
                if (moduleClass != null) {
                    instantiateModule(moduleClass, modules);
                }
            }
        }
        return modules;
    }


public static void proxyRequest(IPageContext context, Writer writer, String proxyPath) throws IOException {
        URLConnection connection = new URL(proxyPath).openConnection();
        connection.setDoInput(true);
        connection.setDoOutput(false);
        connection.setUseCaches(false);
        connection.setRequestProperty("Content-Type", "text/html; charset=UTF-8");
        connection.setReadTimeout(30000);
        connection.setConnectTimeout(5000);
        Enumeration<String> e = context.httpRequest().getHeaderNames();
        while (e.hasMoreElements()) {
            String name = e.nextElement();
            if (name.equalsIgnoreCase("HOST") || name.equalsIgnoreCase("Accept-Encoding") || name.equalsIgnoreCase("Authorization")) continue;
            Enumeration<String> headers = context.httpRequest().getHeaders(name);
            while (headers.hasMoreElements()) {
                String header = headers.nextElement();
                connection.setRequestProperty(name, header);
            }
        }
        if (connection instanceof HttpURLConnection) {
            HttpURLConnection httpConnection = (HttpURLConnection) connection;
            httpConnection.setRequestMethod(context.httpRequest().getMethod());
            if ("POST".equalsIgnoreCase(context.httpRequest().getMethod()) || "PUT".equalsIgnoreCase(context.httpRequest().getMethod())) {
                Enumeration<String> names = context.httpRequest().getParameterNames();
                StringBuilder body = new StringBuilder();
                while (names.hasMoreElements()) {
                    String key = names.nextElement();
                    for (String value : context.parameters(key)) {
                        if (body.length() > 0) {
                            body.append('&');
                        }
                        try {
                            body.append(key).append("=").append(URLEncoder.encode(value, "UTF-8"));
                        } catch (UnsupportedEncodingException ex) {
                        }
                    }
                }
                if (body.length() > 0) {
                    connection.setDoOutput(true);
                    OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
                    out.write(body.toString());
                    out.close();
                }
            }
        }
        try {
            IOUtils.copy(connection.getInputStream(), writer);
        } catch (IOException ex) {
            writer.write("SSI Error: " + ex.getMessage() + "");
        }
    }


    public Configuration(URL url) {
        InputStream in = null;
        try {
            load(in = url.openStream());
        } catch (Exception e) {
            throw new RuntimeException("Could not load configuration from " + url, e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException ignore) {
                }
            }
        }
    }


    public VersionInfo getVersionInfo(String url) {
        try {
            XmlContentHandler handler = new XmlContentHandler();
            XMLReader myReader = XMLReaderFactory.createXMLReader();
            myReader.setContentHandler(handler);
            myReader.parse(new InputSource(new URL(url).openStream()));
            return handler.getVersionInfo();
        } catch (SAXException e) {
            if (debug) {
                println("SAXException was thrown!");
                e.printStackTrace();
            }
        } catch (MalformedURLException e) {
            if (debug) {
                println("MalformedURLException was thrown!");
                e.printStackTrace();
            }
        } catch (IOException e) {
            if (debug) {
                println("IOException was thrown!");
                e.printStackTrace();
            }
        }
        return null;
    }


    public String getPasswordMD5() {
        try {
            MessageDigest algorithm = MessageDigest.getInstance("MD5");
            algorithm.reset();
            algorithm.update(password.getBytes());
            byte messageDigest[] = algorithm.digest();
            StringBuffer hexString = new StringBuffer();
            for (int i = 0; i < messageDigest.length; i++) {
                hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException nsae) {
        }
        return null;
    }


    public static String getMD5(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        MessageDigest md;
        md = MessageDigest.getInstance("MD5");
        byte[] md5hash = new byte[32];
        md.update(text.getBytes("iso-8859-1"), 0, text.length());
        md5hash = md.digest();
        return convertToHex(md5hash);
    }


    public static String SHA1(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        MessageDigest md;
        md = MessageDigest.getInstance("SHA-1");
        byte[] sha1hash = new byte[40];
        md.update(text.getBytes("iso-8859-1"), 0, text.length());
        sha1hash = md.digest();
        return convertToHex(sha1hash);
    }


    public static String createHash(String seed) {
        MessageDigest md;
        try {
            md = MessageDigest.getInstance("SHA");
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Can't happen!", e);
        }
        try {
            md.update(seed.getBytes(CHARSET));
            md.update(String.valueOf(System.currentTimeMillis()).getBytes(CHARSET));
            return toHexString(md.digest());
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("Can't happen!", e);
        }
    }


    public static void copyFile(File source, File dest) throws IOException {
        log.debug("Copy from {} to {}", source.getAbsoluteFile(), dest.getAbsoluteFile());
        FileInputStream fi = new FileInputStream(source);
        FileChannel fic = fi.getChannel();
        MappedByteBuffer mbuf = fic.map(FileChannel.MapMode.READ_ONLY, 0, source.length());
        fic.close();
        fi.close();
        fi = null;
        if (!dest.exists()) {
            String destPath = dest.getPath();
            log.debug("Destination path: {}", destPath);
            String destDir = destPath.substring(0, destPath.lastIndexOf(File.separatorChar));
            log.debug("Destination dir: {}", destDir);
            File dir = new File(destDir);
            if (!dir.exists()) {
                if (dir.mkdirs()) {
                    log.debug("Directory created");
                } else {
                    log.warn("Directory not created");
                }
            }
            dir = null;
        }
        FileOutputStream fo = new FileOutputStream(dest);
        FileChannel foc = fo.getChannel();
        foc.write(mbuf);
        foc.close();
        fo.close();
        fo = null;
        mbuf.clear();
        mbuf = null;
    }


    protected static String hashPassword(String password, String salt) throws NoSuchAlgorithmException {
        String s = salt + password;
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(s.getBytes());
        byte bs[] = md.digest();
        String s1 = BASE64Encoder.encode(bs);
        return new StringBuffer(salt).append(':').append(s1).toString();
    }


    private boolean dependencyOutOfDate(ScriptCacheEntry entry) {
        if (entry != null) {
            for (Iterator i = entry.dependencies.keySet().iterator(); i.hasNext(); ) {
                URLConnection urlc = null;
                URL url = (URL) i.next();
                try {
                    urlc = url.openConnection();
                    urlc.setDoInput(false);
                    urlc.setDoOutput(false);
                    long dependentLastModified = urlc.getLastModified();
                    if (dependentLastModified > ((Long) entry.dependencies.get(url)).longValue()) {
                        return true;
                    }
                } catch (IOException ioe) {
                    return true;
                }
            }
        }
        return false;
    }


    public static void cpdir(File src, File dest) throws BrutException {
        dest.mkdirs();
        File[] files = src.listFiles();
        for (int i = 0; i < files.length; i++) {
            File file = files[i];
            File destFile = new File(dest.getPath() + File.separatorChar + file.getName());
            if (file.isDirectory()) {
                cpdir(file, destFile);
                continue;
            }
            try {
                InputStream in = new FileInputStream(file);
                OutputStream out = new FileOutputStream(destFile);
                IOUtils.copy(in, out);
                in.close();
                out.close();
            } catch (IOException ex) {
                throw new BrutException("Could not copy file: " + file, ex);
            }
        }
    }


    private void copyResource(final String resourceName, final File file) throws IOException {
        assertTrue(resourceName.startsWith("/"));
        InputStream in = null;
        boolean suppressExceptionOnClose = true;
        try {
            in = this.getClass().getResourceAsStream(resourceName);
            assertNotNull("Resource '" + resourceName + "' not found.", in);
            OutputStream out = null;
            try {
                out = new FileOutputStream(file);
                IOUtils.copy(in, out);
                suppressExceptionOnClose = false;
            } finally {
                try {
                    if (out != null) {
                        out.close();
                    }
                } catch (final IOException e) {
                    if (!suppressExceptionOnClose) {
                        throw e;
                    }
                }
            }
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (final IOException e) {
                if (!suppressExceptionOnClose) {
                    throw e;
                }
            }
        }
    }


    public InputStream getExportFile() {
        URL url = ExportAction.class.getClassLoader().getResource("sysConfig.xml");
        if (url != null) try {
            return url.openStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    public static String backupFile(File source) {
        File backup = new File(source.getParent() + "/~" + source.getName());
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(source)));
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(backup)));
            return FileUtil.backupFile(reader, writer, source.getAbsolutePath());
        } catch (FileNotFoundException fe) {
            String msg = "Failed to find file for backup [" + source.getAbsolutePath() + "].";
            _log.error(msg, fe);
            throw new InvalidImplementationException(msg, fe);
        }
    }


    private String loadStatusResult() {
        try {
            URL url = new URL(getServerUrl());
            InputStream input = url.openStream();
            InputStreamReader is = new InputStreamReader(input, "utf-8");
            BufferedReader reader = new BufferedReader(is);
            StringBuffer buffer = new StringBuffer();
            String line = "";
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            return buffer.toString();
        } catch (MalformedURLException e1) {
            e1.printStackTrace();
            return null;
        } catch (IOException e2) {
            e2.printStackTrace();
            return null;
        }
    }


    @Override
    protected URLConnection openConnection(URL url) throws IOException {
        if (url.getQuery() == null) throw new IllegalStateException("Missing TemplateAccount number in rest URL " + url);
        MSResource msResource = null;
        try {
            long templateAccountId = Long.parseLong(url.getQuery());
            msResource = menuBean.findMSResource(templateAccountId, url.getPath());
        } catch (Exception e) {
            throw new IllegalStateException("Resource not found in database: " + url, e);
        }
        ByteArrayInputStream bais = new ByteArrayInputStream(msResource.getValue());
        return new RestConnection(url, bais);
    }


    protected static byte[] httpConnection(Context context, long token, String url, byte[] pdu, int method, boolean isProxySet, String proxyHost, int proxyPort) throws IOException {
        if (url == null) {
            throw new IllegalArgumentException("URL must not be null.");
        }
        if (LOCAL_LOGV) {
            Log.v(TAG, "httpConnection: params list");
            Log.v(TAG, "\ttoken\t\t= " + token);
            Log.v(TAG, "\turl\t\t= " + url);
            Log.v(TAG, "\tUser-Agent\t\t=" + mUserAgent);
            Log.v(TAG, "\tmethod\t\t= " + ((method == HTTP_POST_METHOD) ? "POST" : ((method == HTTP_GET_METHOD) ? "GET" : "UNKNOWN")));
            Log.v(TAG, "\tisProxySet\t= " + isProxySet);
            Log.v(TAG, "\tproxyHost\t= " + proxyHost);
            Log.v(TAG, "\tproxyPort\t= " + proxyPort);
        }
        AndroidHttpClient client = null;
        try {
            URI hostUrl = new URI(url);
            HttpHost target = new HttpHost(hostUrl.getHost(), hostUrl.getPort(), HttpHost.DEFAULT_SCHEME_NAME);
            client = createHttpClient(context);
            HttpRequest req = null;
            switch(method) {
                case HTTP_POST_METHOD:
                    ProgressCallbackEntity entity = new ProgressCallbackEntity(context, token, pdu);
                    entity.setContentType("application/vnd.wap.mms-message");
                    HttpPost post = new HttpPost(url);
                    post.setEntity(entity);
                    req = post;
                    break;
                case HTTP_GET_METHOD:
                    req = new HttpGet(url);
                    break;
                default:
                    Log.e(TAG, "Unknown HTTP method: " + method + ". Must be one of POST[" + HTTP_POST_METHOD + "] or GET[" + HTTP_GET_METHOD + "].");
                    return null;
            }
            HttpParams params = client.getParams();
            if (isProxySet) {
                ConnRouteParams.setDefaultProxy(params, new HttpHost(proxyHost, proxyPort));
            }
            req.setParams(params);
            req.addHeader(HDR_KEY_ACCEPT, HDR_VALUE_ACCEPT);
            {
                String xWapProfileTagName = MmsConfig.getUaProfTagName();
                String xWapProfileUrl = MmsConfig.getUaProfUrl();
                if (xWapProfileUrl != null) {
                    if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
                        Log.d(LogTag.TRANSACTION, "[HttpUtils] httpConn: xWapProfUrl=" + xWapProfileUrl);
                    }
                    req.addHeader(xWapProfileTagName, xWapProfileUrl);
                }
            }
            String extraHttpParams = MmsConfig.getHttpParams();
            if (extraHttpParams != null) {
                String line1Number = ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE)).getLine1Number();
                String line1Key = MmsConfig.getHttpParamsLine1Key();
                String paramList[] = extraHttpParams.split("\\|");
                for (String paramPair : paramList) {
                    String splitPair[] = paramPair.split(":", 2);
                    if (splitPair.length == 2) {
                        String name = splitPair[0].trim();
                        String value = splitPair[1].trim();
                        if (line1Key != null) {
                            value = value.replace(line1Key, line1Number);
                        }
                        if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(value)) {
                            req.addHeader(name, value);
                        }
                    }
                }
            }
            req.addHeader(HDR_KEY_ACCEPT_LANGUAGE, HDR_VALUE_ACCEPT_LANGUAGE);
            HttpResponse response = client.execute(target, req);
            StatusLine status = response.getStatusLine();
            if (status.getStatusCode() != 200) {
                throw new IOException("HTTP error: " + status.getReasonPhrase());
            }
            HttpEntity entity = response.getEntity();
            byte[] body = null;
            if (entity != null) {
                try {
                    if (entity.getContentLength() > 0) {
                        body = new byte[(int) entity.getContentLength()];
                        DataInputStream dis = new DataInputStream(entity.getContent());
                        try {
                            dis.readFully(body);
                        } finally {
                            try {
                                dis.close();
                            } catch (IOException e) {
                                Log.e(TAG, "Error closing input stream: " + e.getMessage());
                            }
                        }
                    }
                } finally {
                    if (entity != null) {
                        entity.consumeContent();
                    }
                }
            }
            return body;
        } catch (URISyntaxException e) {
            handleHttpConnectionException(e, url);
        } catch (IllegalStateException e) {
            handleHttpConnectionException(e, url);
        } catch (IllegalArgumentException e) {
            handleHttpConnectionException(e, url);
        } catch (SocketException e) {
            handleHttpConnectionException(e, url);
        } catch (Exception e) {
            handleHttpConnectionException(e, url);
        } finally {
            if (client != null) {
                client.close();
            }
        }
        return null;
    }


    protected List webservice(URL url, List locations, boolean followRedirect) throws GeoServiceException {
        long start = System.currentTimeMillis();
        int rowCount = 0, hitCount = 0;
        try {
            HttpURLConnection con;
            try {
                con = (HttpURLConnection) url.openConnection();
                try {
                    con.getClass().getMethod("setConnectTimeout", new Class[] { Integer.TYPE }).invoke(con, new Object[] { TIMEOUT });
                } catch (Throwable t) {
                    LOG.info("can't set connection timeout");
                }
                con.setRequestMethod("POST");
                con.setDoOutput(true);
                con.setDoInput(true);
                Writer out = new OutputStreamWriter(con.getOutputStream(), UTF8);
                out.write(HEADER + "\n");
                for (int i = 0; i < locations.size(); i++) {
                    if (i > 0) out.write("\n");
                    out.write(encode((GeoLocation) locations.get(i)));
                }
                out.close();
            } catch (IOException e) {
                throw new GeoServiceException("Accessing GEO Webservice failed", e);
            }
            List rows = new ArrayList();
            try {
                BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream(), UTF8));
                for (int l = 0; l < locations.size(); l++) {
                    String line = in.readLine();
                    LOG.finer(line);
                    if (line == null) break;
                    if (l == 0 && followRedirect) {
                        try {
                            return webservice(new URL(line), locations, false);
                        } catch (MalformedURLException e) {
                        }
                    }
                    rowCount++;
                    List row = new ArrayList();
                    if (!line.startsWith("?")) {
                        StringTokenizer hits = new StringTokenizer(line, ";");
                        while (hits.hasMoreTokens()) {
                            GeoLocation hit = decode(hits.nextToken());
                            if (hit != null) {
                                row.add(hit);
                                hitCount++;
                            }
                        }
                    }
                    rows.add(row);
                }
                in.close();
            } catch (IOException e) {
                throw new GeoServiceException("Reading from GEO Webservice failed", e);
            }
            if (rows.size() < locations.size()) throw new GeoServiceException("GEO Webservice returned " + rows.size() + " rows for " + locations.size() + " locations");
            return rows;
        } finally {
            long secs = (System.currentTimeMillis() - start) / 1000;
            LOG.fine("query for " + locations.size() + " locations in " + secs + "s resulted in " + rowCount + " rows and " + hitCount + " total hits");
        }
    }


    public void copyFile(File sourceFile, File destFile) throws IOException {
        if (!destFile.exists()) {
            destFile.createNewFile();
        }
        FileChannel source = null;
        FileChannel destination = null;
        Closer c = new Closer();
        try {
            source = c.register(new FileInputStream(sourceFile).getChannel());
            destination = c.register(new FileOutputStream(destFile).getChannel());
            destination.transferFrom(source, 0, source.size());
        } catch (IOException e) {
            c.doNotThrow();
            throw e;
        } finally {
            c.closeAll();
        }
    }


        @Override
        public boolean exists() {
            if (local_file.exists()) {
                return true;
            } else {
                try {
                    URLConnection c = remote_url.openConnection();
                    try {
                        c.setConnectTimeout(CIO.getLoadingTimeOut());
                        c.connect();
                        return c.getContentLength() > 0;
                    } catch (Exception err) {
                        err.printStackTrace();
                        return false;
                    } finally {
                        if (c instanceof HttpURLConnection) {
                            ((HttpURLConnection) c).disconnect();
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    return false;
                }
            }
        }


    public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException {
        String bundleName = toBundleName(baseName, locale);
        String resourceName = toResourceName(bundleName, "properties");
        ResourceBundle bundle = null;
        InputStream stream = null;
        if (reload) {
            URL url = loader.getResource(resourceName);
            if (url != null) {
                URLConnection connection = url.openConnection();
                if (connection != null) {
                    connection.setUseCaches(false);
                    stream = connection.getInputStream();
                }
            }
        } else {
            stream = loader.getResourceAsStream(resourceName);
        }
        if (stream != null) {
            try {
                bundle = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8"));
            } finally {
                stream.close();
            }
        }
        return bundle;
    }


    private static ArrayList<String> BingSearch(String query) {
        ArrayList<String> bingSearchResults = new ArrayList<String>();
        try {
            String request = "http://api.bing.net/xml.aspx?AppId=731DD1E61BE6DE4601A3008DC7A0EB379149EC29" + "&Version=2.2&Market=en-US&Query=" + URLEncoder.encode("Java example for " + query, "UTF-8") + "&Sources=web+spell&Web.Count=30";
            URL url = new URL(request);
            System.out.println("Host : " + url.getHost());
            url.openConnection();
            BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
            String inputLine;
            String finalContents = "";
            while ((inputLine = reader.readLine()) != null) {
                finalContents += "\n" + inputLine;
            }
            Document doc = Jsoup.parse(finalContents);
            Elements eles = doc.getElementsByTag("web:Url");
            for (Element ele : eles) {
                String urlText = ele.text();
                if (!urlText.endsWith(".pdf") && !urlText.endsWith(".doc") && !urlText.endsWith(".ppt") && !urlText.endsWith(".PDF") && !urlText.endsWith(".DOC") && !urlText.endsWith(".PPT")) bingSearchResults.add(ele.text());
                System.out.println("BingResult: " + ele.text());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bingSearchResults;
    }


    private static ArrayList<String> YahooSearch(String query) {
        ArrayList<String> yahooSearchResults = new ArrayList<String>();
        try {
            String request = "http://boss.yahooapis.com/ysearch/web/v1/" + URLEncoder.encode("Java example for " + query, "UTF-8") + "?appid=zfau5aPV34ETbq9mWU0ui5e04y0rIewg1zwvzHb1tGoBFK2nSCU1SKS2D4zphh2rd3Wf" + "&format=xml&count=30&type=-msoffice,-pdf";
            URL url = new URL(request);
            System.out.println("Host : " + url.getHost());
            url.openConnection();
            BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
            String inputLine;
            String finalContents = "";
            while ((inputLine = reader.readLine()) != null) {
                finalContents += "\n" + inputLine;
            }
            Document doc = Jsoup.parse(finalContents);
            Elements eles = doc.getElementsByTag("url");
            for (Element ele : eles) {
                yahooSearchResults.add(ele.text());
                System.out.println("YahooResult: " + ele.text());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return yahooSearchResults;
    }


    private InputStream getPart() throws IOException {
        HttpGet get = new HttpGet(url);
        get.addHeader("Range", "bytes=" + startAt + "-");
        HttpResponse res = client.execute(get);
        System.out.println("requesting kBs from " + startAt + "     server reply:" + res.getStatusLine());
        if (res.getStatusLine().getStatusCode() == 403 || res.getStatusLine().toString().toLowerCase().contains("forbidden")) {
            get.abort();
            get = new HttpGet(url);
            get.addHeader("Range", "bytes=" + startAt + "-" + (startAt + downLimit));
            res = client.execute(get);
            System.out.println("Again requesting from kBs " + startAt + "     server reply:" + res.getStatusLine());
            startAt += downLimit;
        } else {
            complete = true;
        }
        return res.getEntity() == null ? null : res.getEntity().getContent();
    }


    public static boolean copyFile(final File src, final File dst) throws FileNotFoundException {
        if (src == null || dst == null || src.equals(dst)) {
            return false;
        }
        boolean result = false;
        if (src.exists()) {
            if (dst.exists() && !dst.canWrite()) {
                return false;
            }
            final FileInputStream srcStream = new FileInputStream(src);
            final FileOutputStream dstStream = new FileOutputStream(dst);
            final FileChannel srcChannel = srcStream.getChannel();
            final FileChannel dstChannel = dstStream.getChannel();
            FileLock dstLock = null;
            FileLock srcLock = null;
            try {
                srcLock = srcChannel.tryLock(0, Long.MAX_VALUE, true);
                dstLock = dstChannel.tryLock();
                if (srcLock != null && dstLock != null) {
                    int maxCount = 64 * 1024 * 1024 - 32 * 1024;
                    long size = srcChannel.size();
                    long position = 0;
                    while (position < size) {
                        position += srcChannel.transferTo(position, maxCount, dstChannel);
                    }
                }
            } catch (IOException ex) {
                Logger.getLogger(FileUtils.class.getName()).log(Level.SEVERE, null, ex);
            } finally {
                if (srcChannel != null) {
                    try {
                        if (srcLock != null) {
                            srcLock.release();
                        }
                        srcChannel.close();
                        srcStream.close();
                    } catch (IOException ex) {
                        Logger.getLogger(FileUtils.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
                if (dstChannel != null) {
                    try {
                        if (dstLock != null) {
                            dstLock.release();
                        }
                        dstChannel.close();
                        dstStream.close();
                        result = true;
                    } catch (IOException ex) {
                        Logger.getLogger(FileUtils.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        }
        return result;
    }


    public static int[] sortstring(int[] a1) {
        int temp;
        for (int j = 0; j < (a1.length * a1.length); j++) {
            for (int i = 0; i < a1.length - 1; i++) {
                if (a1[i] > a1[i + 1]) {
                    temp = a1[i];
                    a1[i] = a1[i + 1];
                    a1[i + 1] = temp;
                }
            }
        }
        return a1;
    }


    public BufferedWriter createOutputStream(String inFile, String outFile) throws IOException {
        int k_blockSize = 1024;
        int byteCount;
        char[] buf = new char[k_blockSize];
        File ofp = new File(outFile);
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(ofp));
        zos.setMethod(ZipOutputStream.DEFLATED);
        OutputStreamWriter osw = new OutputStreamWriter(zos, "ISO-8859-1");
        BufferedWriter bw = new BufferedWriter(osw);
        ZipEntry zot = null;
        File ifp = new File(inFile);
        ZipInputStream zis = new ZipInputStream(new FileInputStream(ifp));
        InputStreamReader isr = new InputStreamReader(zis, "ISO-8859-1");
        BufferedReader br = new BufferedReader(isr);
        ZipEntry zit = null;
        while ((zit = zis.getNextEntry()) != null) {
            if (zit.getName().equals("content.xml")) {
                continue;
            }
            zot = new ZipEntry(zit.getName());
            zos.putNextEntry(zot);
            while ((byteCount = br.read(buf, 0, k_blockSize)) >= 0) bw.write(buf, 0, byteCount);
            bw.flush();
            zos.closeEntry();
        }
        zos.putNextEntry(new ZipEntry("content.xml"));
        bw.flush();
        osw = new OutputStreamWriter(zos, "UTF8");
        bw = new BufferedWriter(osw);
        return bw;
    }


    private void loadMap(URI uri) throws IOException {
        BufferedReader reader = null;
        InputStream stream = null;
        try {
            URL url = uri.toURL();
            stream = url.openStream();
            if (url.getFile().endsWith(".gz")) {
                stream = new GZIPInputStream(stream);
            }
            reader = new BufferedReader(new InputStreamReader(stream));
            String line;
            while ((line = reader.readLine()) != null) {
                line = line.trim();
                if (line.length() > 0) {
                    String[] parts = line.split(" ");
                    if (parts.length == 2) {
                        pinyinZhuyinMap.put(parts[0], parts[1]);
                        zhuyinPinyinMap.put(parts[1], parts[0]);
                    }
                }
            }
        } finally {
            if (reader != null) {
                reader.close();
            }
        }
    }