    public static void copy(String inputFile, String outputFile) throws Exception {
        try {
            FileReader in = new FileReader(inputFile);
            FileWriter out = new FileWriter(outputFile);
            int c;
            while ((c = in.read()) != -1) out.write(c);
            in.close();
            out.close();
        } catch (Exception e) {
            throw new Exception("Could not copy " + inputFile + " into " + outputFile + " because:\n" + e.getMessage());
        }
    }


    public static void createModelZip(String filename, String tempdir, boolean overwrite) throws Exception {
        FileTools.checkOutput(filename, overwrite);
        BufferedInputStream origin = null;
        FileOutputStream dest = new FileOutputStream(filename);
        ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
        int BUFFER = 2048;
        byte data[] = new byte[BUFFER];
        File f = new File(tempdir);
        for (File fs : f.listFiles()) {
            FileInputStream fi = new FileInputStream(fs.getAbsolutePath());
            origin = new BufferedInputStream(fi, BUFFER);
            ZipEntry entry = new ZipEntry(fs.getName());
            out.putNextEntry(entry);
            int count;
            while ((count = origin.read(data, 0, BUFFER)) != -1) out.write(data, 0, count);
            out.closeEntry();
            origin.close();
        }
        out.close();
    }


    public static void unzipModel(String filename, String tempdir) throws Exception {
        try {
            BufferedOutputStream dest = null;
            FileInputStream fis = new FileInputStream(filename);
            int BUFFER = 2048;
            ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
            ZipEntry entry;
            while ((entry = zis.getNextEntry()) != null) {
                int count;
                byte data[] = new byte[BUFFER];
                FileOutputStream fos = new FileOutputStream(tempdir + entry.getName());
                dest = new BufferedOutputStream(fos, BUFFER);
                while ((count = zis.read(data, 0, BUFFER)) != -1) dest.write(data, 0, count);
                dest.flush();
                dest.close();
            }
            zis.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("Can not expand model in \"" + tempdir + "\" because:\n" + e.getMessage());
        }
    }


    public void createResource(String resourceUri, boolean publish, User user) throws IOException {
        PermissionAPI perAPI = APILocator.getPermissionAPI();
        Logger.debug(this.getClass(), "createResource");
        resourceUri = stripMapping(resourceUri);
        String hostName = getHostname(resourceUri);
        String path = getPath(resourceUri);
        String folderName = getFolderName(path);
        String fileName = getFileName(path);
        fileName = deleteSpecialCharacter(fileName);
        if (fileName.startsWith(".")) {
            return;
        }
        Host host = HostFactory.getHostByHostName(hostName);
        Folder folder = FolderFactory.getFolderByPath(folderName, host);
        boolean hasPermission = perAPI.doesUserHavePermission(folder, PERMISSION_WRITE, user, false);
        if (hasPermission) {
            if (!checkFolderFilter(folder, fileName)) {
                throw new IOException("The file doesn't comply the folder's filter");
            }
            if (host.getInode() != 0 && folder.getInode() != 0) {
                File file = new File();
                file.setTitle(fileName);
                file.setFileName(fileName);
                file.setShowOnMenu(false);
                file.setLive(publish);
                file.setWorking(true);
                file.setDeleted(false);
                file.setLocked(false);
                file.setModDate(new Date());
                String mimeType = FileFactory.getMimeType(fileName);
                file.setMimeType(mimeType);
                String author = user.getFullName();
                file.setAuthor(author);
                file.setModUser(author);
                file.setSortOrder(0);
                file.setShowOnMenu(false);
                try {
                    Identifier identifier = null;
                    if (!isResource(resourceUri)) {
                        WebAssetFactory.createAsset(file, user.getUserId(), folder, publish);
                        identifier = IdentifierCache.getIdentifierFromIdentifierCache(file);
                    } else {
                        File actualFile = FileFactory.getFileByURI(path, host, false);
                        identifier = IdentifierCache.getIdentifierFromIdentifierCache(actualFile);
                        WebAssetFactory.createAsset(file, user.getUserId(), folder, identifier, false, false);
                        WebAssetFactory.publishAsset(file);
                        String assetsPath = FileFactory.getRealAssetsRootPath();
                        new java.io.File(assetsPath).mkdir();
                        java.io.File workingIOFile = FileFactory.getAssetIOFile(file);
                        DotResourceCache vc = CacheLocator.getVeloctyResourceCache();
                        vc.remove(ResourceManager.RESOURCE_TEMPLATE + workingIOFile.getPath());
                        if (file != null && file.getInode() > 0) {
                            byte[] currentData = new byte[0];
                            FileInputStream is = new FileInputStream(workingIOFile);
                            int size = is.available();
                            currentData = new byte[size];
                            is.read(currentData);
                            java.io.File newVersionFile = FileFactory.getAssetIOFile(file);
                            vc.remove(ResourceManager.RESOURCE_TEMPLATE + newVersionFile.getPath());
                            FileChannel channelTo = new FileOutputStream(newVersionFile).getChannel();
                            ByteBuffer currentDataBuffer = ByteBuffer.allocate(currentData.length);
                            currentDataBuffer.put(currentData);
                            currentDataBuffer.position(0);
                            channelTo.write(currentDataBuffer);
                            channelTo.force(false);
                            channelTo.close();
                        }
                        java.util.List<Tree> parentTrees = TreeFactory.getTreesByChild(file);
                        for (Tree tree : parentTrees) {
                            Tree newTree = TreeFactory.getTree(tree.getParent(), file.getInode());
                            if (newTree.getChild() == 0) {
                                newTree.setParent(tree.getParent());
                                newTree.setChild(file.getInode());
                                newTree.setRelationType(tree.getRelationType());
                                newTree.setTreeOrder(0);
                                TreeFactory.saveTree(newTree);
                            }
                        }
                    }
                    List<Permission> permissions = perAPI.getPermissions(folder);
                    for (Permission permission : permissions) {
                        Permission filePermission = new Permission();
                        filePermission.setPermission(permission.getPermission());
                        filePermission.setRoleId(permission.getRoleId());
                        filePermission.setInode(identifier.getInode());
                        perAPI.save(filePermission);
                    }
                } catch (Exception ex) {
                    Logger.debug(this, ex.toString());
                }
            }
        } else {
            throw new IOException("You don't have access to add that folder/host");
        }
    }


    public static String getUserToken(String userName) {
        if (userName != null && userName.trim().length() > 0) try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update((userName + seed).getBytes("ISO-8859-1"));
            return BaseController.bytesToHex(md.digest());
        } catch (NullPointerException npe) {
        } catch (NoSuchAlgorithmException e) {
        } catch (UnsupportedEncodingException e) {
        }
        return null;
    }


    String connect() throws IOException {
        String reply = null;
        if (ftp == null) {
            FTPClient ftp = new FTPClient();
            ftp.connect(remote);
            if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
                throw new IOException("Connection failed: " + remote);
            }
            reply = ftp.getReplyString();
            if (!ftp.login("anonymous", "")) {
                throw new IOException("Login failed: " + remote);
            }
            if (!ftp.setFileType(FTP.BINARY_FILE_TYPE)) {
                throw new IOException("Setting binary file type failed: " + remote);
            }
            this.ftp = ftp;
        }
        return reply;
    }


    @Test
    public void testProxySsl() throws Throwable {
        URL url = new URL("https://login.yahoo.co.jp/config/login");
        HttpsURLConnection httpsconnection = (HttpsURLConnection) url.openConnection();
        KeyManager[] km = null;
        TrustManager[] tm = { new X509TrustManager() {

            public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
            }

            public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
            }

            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        } };
        SSLContext sslcontext = SSLContext.getInstance("SSL");
        sslcontext.init(km, tm, new SecureRandom());
        httpsconnection.setSSLSocketFactory(sslcontext.getSocketFactory());
        InputStream is = httpsconnection.getInputStream();
        readInputStream(is);
        is.close();
    }


    public Document transform(URL url) throws IOException {
        Document doc = null;
        try {
            InputStream in = url.openStream();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            Tidy tidy = new Tidy();
            tidy.setShowWarnings(false);
            tidy.setXmlOut(true);
            tidy.setXmlPi(false);
            tidy.setDocType("auto");
            tidy.setXHTML(false);
            tidy.setRawOut(true);
            tidy.setNumEntities(true);
            tidy.setQuiet(true);
            tidy.setFixComments(true);
            tidy.setIndentContent(true);
            tidy.setCharEncoding(org.w3c.tidy.Configuration.ASCII);
            DOMBuilder docBuilder = new DOMBuilder();
            doc = docBuilder.build(tidy.parseDOM(in, baos));
            String result = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + baos.toString();
            in.close();
            baos.close();
            doc = XMLHelper.parseXMLFromString(result);
        } catch (IOException ioEx) {
            throw ioEx;
        } catch (XMLHelperException xmlEx) {
            xmlEx.printStackTrace();
        }
        return doc;
    }


    public void format(File source, File target) {
        if (!source.exists()) {
            throw new IllegalArgumentException("Source '" + source + " doesn't exist");
        }
        if (!source.isFile()) {
            throw new IllegalArgumentException("Source '" + source + " is not a file");
        }
        target.mkdirs();
        String fileExtension = source.getName().substring(source.getName().lastIndexOf(".") + 1);
        String _target = source.getName().replace(fileExtension, "html");
        target = new File(target.getPath() + "/" + _target);
        try {
            Reader reader = new FileReader(source);
            Writer writer = new FileWriter(target);
            this.format(reader, writer);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static void unzip(File zipInFile, File outputDir) throws Exception {
        Enumeration<? extends ZipEntry> entries;
        ZipFile zipFile = new ZipFile(zipInFile);
        ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipInFile));
        ZipEntry entry = (ZipEntry) zipInputStream.getNextEntry();
        File curOutDir = outputDir;
        while (entry != null) {
            if (entry.isDirectory()) {
                curOutDir = new File(curOutDir, entry.getName());
                curOutDir.mkdirs();
                continue;
            }
            File outFile = new File(curOutDir, entry.getName());
            File tempDir = outFile.getParentFile();
            if (!tempDir.exists()) tempDir.mkdirs();
            outFile.createNewFile();
            BufferedOutputStream outstream = new BufferedOutputStream(new FileOutputStream(outFile));
            int n;
            byte[] buf = new byte[1024];
            while ((n = zipInputStream.read(buf, 0, 1024)) > -1) outstream.write(buf, 0, n);
            outstream.flush();
            outstream.close();
            zipInputStream.closeEntry();
            entry = zipInputStream.getNextEntry();
        }
        zipInputStream.close();
        zipFile.close();
    }


        @Override
        public Void doInBackground() {
            java.io.FileOutputStream fos = null;
            try {
                String localFile = "JavaPointNew.jar";
                java.io.BufferedInputStream in = null;
                try {
                    HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
                    contentLength = httpConn.getContentLength();
                    if (contentLength == -1) {
                        System.out.println("unknown content length");
                    } else {
                        System.out.println("content length: " + contentLength + " bytes");
                    }
                    in = new java.io.BufferedInputStream(httpConn.getInputStream());
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                fos = new java.io.FileOutputStream(localFile);
                java.io.BufferedOutputStream bout = new BufferedOutputStream(fos, 1024);
                byte[] data = new byte[1024];
                int x = 0;
                int bytes = 0;
                while ((x = in.read(data, 0, 1024)) >= 0) {
                    bout.write(data, 0, x);
                    bytes += x;
                    setProgress((int) ((Math.min(bytes * 100 / contentLength, 100)) + .5));
                }
                bout.close();
                in.close();
                File jarFile = mainFrame.presentationFile;
                if (jarFile.exists()) {
                    final File temporaryJarFile = Utilities.createTemporaryFile("presentation", ".jar", false, null);
                    final JarFile updatedJarFile = new JarFile(localFile);
                    final JarOutputStream output = new JarOutputStream(new FileOutputStream(temporaryJarFile));
                    for (final JarEntry entry : Utilities.toList(updatedJarFile.entries())) {
                        if (!entry.getName().startsWith(Constants.JAR_ENTRY_PRESENTATION_PREFIX)) {
                            final InputStream entryStream = updatedJarFile.getInputStream(entry);
                            output.putNextEntry(entry);
                            Utilities.write(entryStream, output);
                        }
                    }
                    new SlidesWriter().write(mainFrame.getSlides(), output);
                    jarFile.delete();
                    new File(localFile).delete();
                    if (!temporaryJarFile.renameTo(jarFile)) {
                        throw new RuntimeException("Failed to update " + jarFile);
                    }
                } else {
                    new SlidesWriter().write(mainFrame.getSlides(), new JarOutputStream(new FileOutputStream(jarFile)));
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            } finally {
                try {
                    fos.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
            return null;
        }


    private static void extract(final ZipFile zf, final ZipEntry zipEntry, final String desDir, final int... startDirLevel) throws IOException {
        File desf = new File(desDir);
        if (!desf.exists()) {
            desf.mkdirs();
        }
        int start = 1;
        if (null != startDirLevel && startDirLevel.length > 0) {
            start = startDirLevel[0];
            if (start < 1) {
                start = 1;
            }
        }
        String startDir = "";
        String zeName = zipEntry.getName();
        String folder = zeName;
        boolean isDir = zipEntry.isDirectory();
        if (null != folder) {
            String[] folders = folder.split("\\/");
            if (null != folders && folders.length > 0) {
                int len = folders.length;
                if (start == 1) {
                    startDir = zeName;
                } else {
                    if (start > len) {
                    } else {
                        for (int i = start - 1; i < len; i++) {
                            startDir += "/" + folders[i];
                        }
                        if (null != startDir) {
                            startDir = startDir.substring(1);
                        }
                    }
                }
            }
        }
        startDir = StringUtils.trim(startDir);
        if (StringUtils.isNotEmpty(startDir)) {
            StringBuilder desFileName = new StringBuilder(desDir);
            if (!desDir.endsWith("/") && !startDir.startsWith("/")) {
                desFileName.append("/");
            }
            desFileName.append(startDir);
            File destFile = new File(desFileName.toString());
            if (isDir) {
                if (!destFile.exists()) {
                    destFile.mkdirs();
                }
            } else {
                File parentDir = new File(destFile.getParentFile().getPath());
                if (!parentDir.exists()) {
                    parentDir.mkdirs();
                }
                InputStream is = zf.getInputStream(zipEntry);
                OutputStream os = new FileOutputStream(destFile);
                IOUtils.copy(is, os);
                if (null != is) {
                    is.close();
                }
                if (null != os) {
                    os.close();
                }
            }
        }
    }


    public void create(File target) {
        if ("dir".equals(type)) {
            File dir = new File(target, name);
            dir.mkdirs();
            for (Resource c : children) {
                c.create(dir);
            }
        } else if ("package".equals(type)) {
            String[] dirs = name.split("\\.");
            File parent = target;
            for (String d : dirs) {
                parent = new File(parent, d);
            }
            parent.mkdirs();
            for (Resource c : children) {
                c.create(parent);
            }
        } else if ("file".equals(type)) {
            InputStream is = getInputStream();
            File file = new File(target, name);
            try {
                if (is != null) {
                    FileOutputStream fos = new FileOutputStream(file);
                    IOUtils.copy(is, fos);
                    fos.flush();
                    fos.close();
                } else {
                    PrintStream ps = new PrintStream(file);
                    ps.print(content);
                    ps.flush();
                    ps.close();
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else if ("zip".equals(type)) {
            try {
                unzip(target);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            throw new RuntimeException("unknown resource type: " + type);
        }
    }


    private void doLogin(String password) throws LoginFailedException, IncorrectPasswordException {
        final long mgr = Constants.MANAGER;
        Data data, response;
        try {
            response = sendAndWait(new Request(mgr)).get(0);
            MessageDigest md;
            try {
                md = MessageDigest.getInstance("MD5");
            } catch (NoSuchAlgorithmException e) {
                throw new RuntimeException("MD5 hash not supported.");
            }
            byte[] challenge = response.getBytes();
            md.update(challenge);
            md.update(password.getBytes(Data.STRING_ENCODING));
            data = Data.valueOf(md.digest());
            try {
                response = sendAndWait(new Request(mgr).add(0, data)).get(0);
            } catch (ExecutionException ex) {
                throw new IncorrectPasswordException();
            }
            setLoginMessage(response.getString());
            response = sendAndWait(new Request(mgr).add(0, getLoginData())).get(0);
            setID(response.getWord());
        } catch (InterruptedException ex) {
            throw new LoginFailedException(ex);
        } catch (ExecutionException ex) {
            throw new LoginFailedException(ex);
        } catch (IOException ex) {
            throw new LoginFailedException(ex);
        }
    }


    public String readBaseLib() throws Exception {
        if (_BASE_LIB_JS == null) {
            StringBuffer js = new StringBuffer();
            try {
                URL url = AbstractRunner.class.getResource(_BASELIB_FILENAME);
                if (url != null) {
                    InputStream is = url.openStream();
                    InputStreamReader reader = new InputStreamReader(is);
                    BufferedReader bfReader = new BufferedReader(reader);
                    String tmp = null;
                    do {
                        tmp = bfReader.readLine();
                        if (tmp != null) {
                            js.append(tmp).append('\n');
                        }
                    } while (tmp != null);
                    bfReader.close();
                    reader.close();
                    is.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw e;
            }
            _BASE_LIB_JS = js.toString();
        }
        return _BASE_LIB_JS;
    }


    public static InputStream download(String endereco, ProxyConfig proxy) {
        if (proxy != null) {
            System.getProperties().put("proxySet", "true");
            System.getProperties().put("proxyPort", proxy.getPorta());
            System.getProperties().put("proxyHost", proxy.getHost());
            Authenticator.setDefault(new ProxyAuthenticator(proxy.getUsuario(), proxy.getSenha()));
        }
        try {
            URL url = new URL(endereco);
            ;
            URLConnection connection = url.openConnection();
            InputStream bis = new BufferedInputStream(connection.getInputStream());
            return bis;
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    private void validateODFDoc(String url, String ver, ValidationReport commentary) throws IOException, MalformedURLException {
        logger.debug("Beginning document validation ...");
        synchronized (ODFValidationSession.class) {
            PropertyMapBuilder builder = new PropertyMapBuilder();
            String[] segments = url.split("/");
            CommentatingErrorHandler h = new CommentatingErrorHandler(commentary, segments[segments.length - 1]);
            ValidateProperty.ERROR_HANDLER.put(builder, h);
            ValidationDriver driver = new ValidationDriver(builder.toPropertyMap());
            InputStream candidateStream = null;
            try {
                logger.debug("Loading schema version " + ver);
                byte[] schemaBytes = getSchemaForVersion(ver);
                driver.loadSchema(new InputSource(new ByteArrayInputStream(schemaBytes)));
                URLConnection conn = new URL(url).openConnection();
                candidateStream = conn.getInputStream();
                logger.debug("Calling validate()");
                commentary.incIndent();
                boolean isValid = driver.validate(new InputSource(candidateStream));
                logger.debug("Errors in instance:" + h.getInstanceErrCount());
                if (h.getInstanceErrCount() > CommentatingErrorHandler.THRESHOLD) {
                    commentary.addComment("(<i>" + (h.getInstanceErrCount() - CommentatingErrorHandler.THRESHOLD) + " error(s) omitted for the sake of brevity</i>)");
                }
                commentary.decIndent();
                if (isValid) {
                    commentary.addComment("The document is valid");
                } else {
                    commentary.addComment("ERROR", "The document is invalid");
                }
            } catch (SAXException e) {
                commentary.addComment("FATAL", "The resource is not conformant XML: " + e.getMessage());
                logger.error(e.getMessage());
            } finally {
                Utils.streamClose(candidateStream);
            }
        }
    }


    public void testRead() throws ParserConfigurationException, SAXException, ParseException, IOException {
        InputStream in = getConfStream();
        LogDistiller ld = dOMConfigurator.read(in);
        in.close();
        checkLogDistiller(ld);
        File tmp = File.createTempFile("logdistiller", "test");
        tmp.delete();
        tmp.mkdir();
        URL url = WeblogicLogEvent.class.getResource("wldomain7.log");
        in = url.openStream();
        assertNotNull("load resource wldomain7.log", in);
        Reader reader = new InputStreamReader(in);
        ld.getOutput().setDirectory(tmp.getAbsolutePath());
        LogDistillation exec = new LogDistillation(ld);
        LogEvent.Factory factory = exec.getLogTypeDescription().newFactory(reader, url.toString());
        exec.begin();
        LogEvent le;
        while ((le = factory.nextEvent()) != null) {
            exec.processLogEvent(le);
        }
        exec.end();
        in.close();
        assertEquals("number of logevents processed", 21, exec.getEventCount());
        final int[] groupEventCount = { 6, 6, 1, 4, 9, 7 };
        for (int i = 0; i < 6; i++) {
            LogDistillation.Group g = exec.getGroups()[i];
            LogDistiller.Group def = g.getDefinition();
            assertEquals("number of logevents in group[id='" + def.getId() + "']", groupEventCount[i], g.getEventCount());
        }
    }


    public static String read(ClassLoader classLoader, String name, boolean all) throws IOException {
        if (all) {
            StringMaker sm = new StringMaker();
            Enumeration enu = classLoader.getResources(name);
            while (enu.hasMoreElements()) {
                URL url = (URL) enu.nextElement();
                InputStream is = url.openStream();
                String s = read(is);
                if (s != null) {
                    sm.append(s);
                    sm.append(StringPool.NEW_LINE);
                }
                is.close();
            }
            return sm.toString().trim();
        } else {
            InputStream is = classLoader.getResourceAsStream(name);
            String s = read(is);
            is.close();
            return s;
        }
    }


    private String getDocumentAsString(URL url) throws IOException {
        StringBuffer result = new StringBuffer();
        InputStream in = url.openStream();
        int c;
        while ((c = in.read()) != -1) result.append((char) c);
        return result.toString();
    }


    @Override
    public Object getImage(String key) {
        if (key.indexOf("exhibition/") != -1) {
            InputStream inputStream = null;
            try {
                URL url = new URL(getBaseURL() + "icons/" + key + ".png");
                inputStream = url.openStream();
                return url;
            } catch (Exception e) {
            } finally {
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        ExceptionHandlingService.INSTANCE.handleException(e);
                    }
                }
            }
        }
        return super.getImage(key);
    }


    protected void serveStaticContent(HttpServletRequest request, HttpServletResponse response, String pathInfo) throws ServletException {
        InputStream is = servletConfig.getServletContext().getResourceAsStream(pathInfo);
        if (is == null) {
            throw new ServletException("Static resource " + pathInfo + " is not available");
        }
        try {
            int ind = pathInfo.lastIndexOf(".");
            if (ind != -1 && ind < pathInfo.length()) {
                String type = STATIC_CONTENT_TYPES.get(pathInfo.substring(ind + 1));
                if (type != null) {
                    response.setContentType(type);
                }
            }
            ServletOutputStream os = response.getOutputStream();
            IOUtils.copy(is, os);
            os.flush();
        } catch (IOException ex) {
            throw new ServletException("Static resource " + pathInfo + " can not be written to the output stream");
        }
    }


    private long getLastModified(Set resourcePaths, Map jarPaths) throws Exception {
        long lastModified = 0;
        Iterator paths = resourcePaths.iterator();
        while (paths.hasNext()) {
            String path = (String) paths.next();
            URL url = context.getServletContext().getResource(path);
            if (url == null) {
                log.debug("Null url " + path);
                break;
            }
            long lastM = url.openConnection().getLastModified();
            if (lastM > lastModified) lastModified = lastM;
            if (log.isDebugEnabled()) {
                log.debug("Last modified " + path + " " + lastM);
            }
        }
        if (jarPaths != null) {
            paths = jarPaths.values().iterator();
            while (paths.hasNext()) {
                File jarFile = (File) paths.next();
                long lastM = jarFile.lastModified();
                if (lastM > lastModified) lastModified = lastM;
                if (log.isDebugEnabled()) {
                    log.debug("Last modified " + jarFile.getAbsolutePath() + " " + lastM);
                }
            }
        }
        return lastModified;
    }


    public static void copy(String fromFileName, String toFileName) throws IOException {
        File fromFile = new File(fromFileName);
        File toFile = new File(toFileName);
        if (!fromFile.exists()) throw new IOException("FileCopy: " + "no such source file: " + fromFileName);
        if (!fromFile.isFile()) throw new IOException("FileCopy: " + "can't copy directory: " + fromFileName);
        if (!fromFile.canRead()) throw new IOException("FileCopy: " + "source file is unreadable: " + fromFileName);
        if (toFile.isDirectory()) toFile = new File(toFile, fromFile.getName());
        if (toFile.exists()) {
            if (!toFile.canWrite()) throw new IOException("FileCopy: " + "destination file is unwriteable: " + toFileName);
            System.out.print("Overwrite existing file " + toFile.getName() + "? (Y/N): ");
            System.out.flush();
            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
            String response = in.readLine();
            if (!response.equals("Y") && !response.equals("y")) throw new IOException("FileCopy: " + "existing file was not overwritten.");
        } else {
            String parent = toFile.getParent();
            if (parent == null) parent = System.getProperty("user.dir");
            File dir = new File(parent);
            if (!dir.exists()) throw new IOException("FileCopy: " + "destination directory doesn't exist: " + parent);
            if (dir.isFile()) throw new IOException("FileCopy: " + "destination is not a directory: " + parent);
            if (!dir.canWrite()) throw new IOException("FileCopy: " + "destination directory is unwriteable: " + parent);
        }
        FileInputStream from = null;
        FileOutputStream to = null;
        try {
            from = new FileInputStream(fromFile);
            to = new FileOutputStream(toFile);
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = from.read(buffer)) != -1) to.write(buffer, 0, bytesRead);
        } finally {
            if (from != null) try {
                from.close();
            } catch (IOException e) {
                ;
            }
            if (to != null) try {
                to.close();
            } catch (IOException e) {
                ;
            }
        }
    }


    public static boolean check(String urlStr) {
        try {
            URL url = new URL(urlStr);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setConnectTimeout(2000);
            urlConnection.getContent();
        } catch (Exception e) {
            logger.error("There is no internet connection", e);
            return false;
        }
        return true;
    }


    public XMLTreeView(JFrame frame, Web3DService web3DService) {
        frame.getContentPane().setLayout(new BorderLayout());
        DefaultMutableTreeNode top = new DefaultMutableTreeNode(file);
        saxTree = new SAXTreeBuilder(top);
        InputStream urlIn = null;
        try {
            SAXParser saxParser = new SAXParser();
            saxParser.setContentHandler(saxTree);
            String request = web3DService.getServiceEndPoint() + "?" + "SERVICE=" + web3DService.getService() + "&" + "REQUEST=GetCapabilities&" + "ACCEPTFORMATS=text/xml&" + "ACCEPTVERSIONS=";
            for (int i = 0; i < web3DService.getAcceptVersions().length; i++) {
                if (i > 0) request += ",";
                request += web3DService.getAcceptVersions()[i];
            }
            System.out.println(request);
            URL url = new URL(request);
            URLConnection urlc = url.openConnection();
            urlc.setReadTimeout(Navigator.TIME_OUT);
            if (web3DService.getEncoding() != null) {
                urlc.setRequestProperty("Authorization", "Basic " + web3DService.getEncoding());
            }
            urlIn = urlc.getInputStream();
            saxParser.parse(new InputSource(urlIn));
        } catch (Exception ex) {
            top.add(new DefaultMutableTreeNode(ex.getMessage()));
        }
        try {
            urlIn.close();
        } catch (Exception e) {
        }
        JTree tree = new JTree(saxTree.getTree());
        JScrollPane scrollPane = new JScrollPane(tree);
        frame.getContentPane().add("Center", scrollPane);
        frame.setVisible(true);
    }


public GEItem lookup(final int itemID) {
        try {
            URL url = new URL(GrandExchange.HOST + GrandExchange.GET + itemID);
            BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
            String input;
            boolean exists = false;
            int i = 0;
            double[] values = new double[4];
            String name = "", examine = "";
            while ((input = br.readLine()) != null) {
                if (input.contains("<div class=\"brown_box main_ge_page") && !exists) {
                    if (!input.contains("vertically_spaced")) {
                        return null;
                    }
                    exists = true;
                    br.readLine();
                    br.readLine();
                    name = br.readLine();
                } else if (input.contains("<img id=\"item_image\" src=\"")) {
                    examine = br.readLine();
                } else if (input.matches("(?i).+ (price|days): .+")) {
                    values[i] = parse(input);
                    i++;
                } else if (input.matches("
")) break;
            }
            return new GEItem(name, examine, itemID, values);
        } catch (IOException ignore) {
        }
        return null;
    }


public GEItem lookup(final String itemName) {
        try {
            URL url = new URL(GrandExchange.HOST + "/m=itemdb_rs/results.ws?query=" + itemName + "&price=all&members=");
            BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
            String input;
            while ((input = br.readLine()) != null) {
                if (input.contains("
")) {
                    input = br.readLine();
                    if (input.contains("Your search for")) {
                        return null;
                    }
                } else if (input.startsWith("<img src=")) {
                    Matcher matcher = GrandExchange.PATTERN.matcher(input);
                    if (matcher.find()) {
                        if (matcher.group(2).contains(itemName)) {
                            return lookup(Integer.parseInt(matcher.group(1)));
                        }
                    }
                }
            }
        } catch (IOException ignored) {
        }
        return null;
    }


    private String getCoded(String pass) {
        String passSecret = "";
        try {
            MessageDigest m = MessageDigest.getInstance("MD5");
            m.update(pass.getBytes("UTF8"));
            byte s[] = m.digest();
            for (int i = 0; i < s.length; i++) {
                passSecret += Integer.toHexString((0x000000ff & s[i]) | 0xffffff00).substring(6);
            }
        } catch (NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return passSecret;
    }


    public void run() {
        try {
            URL url = new URL("http://pokedev.org/time.php");
            BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
            StringTokenizer s = new StringTokenizer(in.readLine());
            m_day = Integer.parseInt(s.nextToken());
            m_hour = Integer.parseInt(s.nextToken());
            m_minutes = Integer.parseInt(s.nextToken());
            in.close();
        } catch (Exception e) {
            System.out.println("ERROR: Cannot reach time server, reverting to local time");
            Calendar cal = Calendar.getInstance();
            m_hour = cal.get(Calendar.HOUR_OF_DAY);
            m_minutes = 0;
            m_day = 0;
        }
        while (m_isRunning) {
            m_minutes = m_minutes == 59 ? 0 : m_minutes + 1;
            if (m_minutes == 0) {
                if (m_hour == 23) {
                    incrementDay();
                    m_hour = 0;
                } else {
                    m_hour += 1;
                }
            }
            m_hour = m_hour == 23 ? 0 : m_hour + 1;
            if (System.currentTimeMillis() - m_lastWeatherUpdate >= 3600000) {
                generateWeather();
                m_lastWeatherUpdate = System.currentTimeMillis();
            }
            try {
                Thread.sleep(60000);
            } catch (Exception e) {
            }
        }
        System.out.println("INFO: Time Service stopped");
    }


    public static void copyFromFileToFileUsingNIO(File inputFile, File outputFile) throws FileNotFoundException, IOException {
        FileChannel inputChannel = new FileInputStream(inputFile).getChannel();
        FileChannel outputChannel = new FileOutputStream(outputFile).getChannel();
        try {
            inputChannel.transferTo(0, inputChannel.size(), outputChannel);
        } catch (IOException e) {
            throw e;
        } finally {
            if (inputChannel != null) inputChannel.close();
            if (outputChannel != null) outputChannel.close();
        }
    }


    @Override
    public void execute() throws ProcessorExecutionException {
        try {
            if (getSource().getPaths() == null || getSource().getPaths().size() == 0 || getDestination().getPaths() == null || getDestination().getPaths().size() == 0) {
                throw new ProcessorExecutionException("No input and/or output paths specified.");
            }
            String temp_dir_prefix = getDestination().getPath().getParent().toString() + "/bcc_" + getDestination().getPath().getName() + "_";
            SequenceTempDirMgr dirMgr = new SequenceTempDirMgr(temp_dir_prefix, context);
            dirMgr.setSeqNum(0);
            Path tmpDir;
            System.out.println("++++++>" + dirMgr.getSeqNum() + ": Transform input to AdjSetVertex");
            Transformer transformer = new OutAdjVertex2AdjSetVertexTransformer();
            transformer.setConf(context);
            transformer.setSrcPath(getSource().getPath());
            tmpDir = dirMgr.getTempDir();
            transformer.setDestPath(tmpDir);
            transformer.setMapperNum(getMapperNum());
            transformer.setReducerNum(getReducerNum());
            transformer.execute();
            System.out.println("++++++>" + dirMgr.getSeqNum() + ": Transform input to LabeledAdjSetVertex");
            Vertex2LabeledTransformer l_transformer = new Vertex2LabeledTransformer();
            l_transformer.setConf(context);
            l_transformer.setSrcPath(tmpDir);
            tmpDir = dirMgr.getTempDir();
            l_transformer.setDestPath(tmpDir);
            l_transformer.setMapperNum(getMapperNum());
            l_transformer.setReducerNum(getReducerNum());
            l_transformer.setOutputValueClass(LabeledAdjSetVertex.class);
            l_transformer.execute();
            Graph src;
            Graph dest;
            Path path_to_remember = tmpDir;
            System.out.println("++++++>" + dirMgr.getSeqNum() + ": SpanningTreeRootChoose");
            src = new Graph(Graph.defaultGraph());
            src.setPath(tmpDir);
            dest = new Graph(Graph.defaultGraph());
            tmpDir = dirMgr.getTempDir();
            dest.setPath(tmpDir);
            GraphAlgorithm choose_root = new SpanningTreeRootChoose();
            choose_root.setConf(context);
            choose_root.setSource(src);
            choose_root.setDestination(dest);
            choose_root.setMapperNum(getMapperNum());
            choose_root.setReducerNum(getReducerNum());
            choose_root.execute();
            Path the_file = new Path(tmpDir.toString() + "/part-00000");
            FileSystem client = FileSystem.get(context);
            if (!client.exists(the_file)) {
                throw new ProcessorExecutionException("Did not find the chosen vertex in " + the_file.toString());
            }
            FSDataInputStream input_stream = client.open(the_file);
            ByteArrayOutputStream output_stream = new ByteArrayOutputStream();
            IOUtils.copyBytes(input_stream, output_stream, context, false);
            String the_line = output_stream.toString();
            String root_vertex_id = the_line.substring(SpanningTreeRootChoose.SPANNING_TREE_ROOT.length()).trim();
            input_stream.close();
            output_stream.close();
            System.out.println("++++++> Chosen the root of spanning tree = " + root_vertex_id);
            while (true) {
                System.out.println("++++++>" + dirMgr.getSeqNum() + " Generate the spanning tree rooted at : (" + root_vertex_id + ") from " + tmpDir);
                src = new Graph(Graph.defaultGraph());
                src.setPath(path_to_remember);
                tmpDir = dirMgr.getTempDir();
                dest = new Graph(Graph.defaultGraph());
                dest.setPath(tmpDir);
                path_to_remember = tmpDir;
                GraphAlgorithm spanning = new SpanningTreeGenerate();
                spanning.setConf(context);
                spanning.setSource(src);
                spanning.setDestination(dest);
                spanning.setMapperNum(getMapperNum());
                spanning.setReducerNum(getReducerNum());
                spanning.setParameter(ConstantLabels.ROOT_ID, root_vertex_id);
                spanning.execute();
                System.out.println("++++++>" + dirMgr.getSeqNum() + " Test spanning convergence");
                src = new Graph(Graph.defaultGraph());
                src.setPath(tmpDir);
                tmpDir = dirMgr.getTempDir();
                dest = new Graph(Graph.defaultGraph());
                dest.setPath(tmpDir);
                GraphAlgorithm conv_tester = new SpanningConvergenceTest();
                conv_tester.setConf(context);
                conv_tester.setSource(src);
                conv_tester.setDestination(dest);
                conv_tester.setMapperNum(getMapperNum());
                conv_tester.setReducerNum(getReducerNum());
                conv_tester.execute();
                long vertexes_out_of_tree = MRConsoleReader.getMapOutputRecordNum(conv_tester.getFinalStatus());
                System.out.println("++++++> number of vertexes out of the spanning tree = " + vertexes_out_of_tree);
                if (vertexes_out_of_tree == 0) {
                    break;
                }
            }
            System.out.println("++++++> From spanning tree to sets of edges");
            src = new Graph(Graph.defaultGraph());
            src.setPath(path_to_remember);
            tmpDir = dirMgr.getTempDir();
            dest = new Graph(Graph.defaultGraph());
            dest.setPath(tmpDir);
            GraphAlgorithm tree2set = new Tree2EdgeSet();
            tree2set.setConf(context);
            tree2set.setSource(src);
            tree2set.setDestination(dest);
            tree2set.setMapperNum(getMapperNum());
            tree2set.setReducerNum(getReducerNum());
            tree2set.execute();
            long map_input_records_num = -1;
            long map_output_records_num = -2;
            Stack<Path> expanding_stack = new Stack<Path>();
            do {
                System.out.println("++++++>" + dirMgr.getSeqNum() + ": EdgeSetMinorJoin");
                GraphAlgorithm minorjoin = new EdgeSetMinorJoin();
                minorjoin.setConf(context);
                src = new Graph(Graph.defaultGraph());
                src.setPath(tmpDir);
                dest = new Graph(Graph.defaultGraph());
                tmpDir = dirMgr.getTempDir();
                dest.setPath(tmpDir);
                minorjoin.setSource(src);
                minorjoin.setDestination(dest);
                minorjoin.setMapperNum(getMapperNum());
                minorjoin.setReducerNum(getReducerNum());
                minorjoin.execute();
                expanding_stack.push(tmpDir);
                System.out.println("++++++>" + dirMgr.getSeqNum() + ": EdgeSetJoin");
                GraphAlgorithm join = new EdgeSetJoin();
                join.setConf(context);
                src = new Graph(Graph.defaultGraph());
                src.setPath(tmpDir);
                dest = new Graph(Graph.defaultGraph());
                tmpDir = dirMgr.getTempDir();
                dest.setPath(tmpDir);
                join.setSource(src);
                join.setDestination(dest);
                join.setMapperNum(getMapperNum());
                join.setReducerNum(getReducerNum());
                join.execute();
                map_input_records_num = MRConsoleReader.getMapInputRecordNum(join.getFinalStatus());
                map_output_records_num = MRConsoleReader.getMapOutputRecordNum(join.getFinalStatus());
                System.out.println("++++++> map in/out : " + map_input_records_num + "/" + map_output_records_num);
            } while (map_input_records_num != map_output_records_num);
            while (expanding_stack.size() > 0) {
                System.out.println("++++++>" + dirMgr.getSeqNum() + ": EdgeSetExpand");
                GraphAlgorithm expand = new EdgeSetExpand();
                expand.setConf(context);
                src = new Graph(Graph.defaultGraph());
                src.addPath(expanding_stack.pop());
                src.addPath(tmpDir);
                dest = new Graph(Graph.defaultGraph());
                tmpDir = dirMgr.getTempDir();
                dest.setPath(tmpDir);
                expand.setSource(src);
                expand.setDestination(dest);
                expand.setMapperNum(getMapperNum());
                expand.setReducerNum(getReducerNum());
                expand.execute();
                System.out.println("++++++>" + dirMgr.getSeqNum() + ": EdgeSetMinorExpand");
                GraphAlgorithm minorexpand = new EdgeSetMinorExpand();
                minorexpand.setConf(context);
                src = new Graph(Graph.defaultGraph());
                src.setPath(tmpDir);
                dest = new Graph(Graph.defaultGraph());
                tmpDir = dirMgr.getTempDir();
                dest.setPath(tmpDir);
                minorexpand.setSource(src);
                minorexpand.setDestination(dest);
                minorexpand.setMapperNum(getMapperNum());
                minorexpand.setReducerNum(getReducerNum());
                minorexpand.execute();
            }
            System.out.println("++++++>" + dirMgr.getSeqNum() + ": EdgeSetSummarize");
            GraphAlgorithm summarize = new EdgeSetSummarize();
            summarize.setConf(context);
            src = new Graph(Graph.defaultGraph());
            src.setPath(tmpDir);
            dest = new Graph(Graph.defaultGraph());
            dest.setPath(getDestination().getPath());
            summarize.setSource(src);
            summarize.setDestination(dest);
            summarize.setMapperNum(getMapperNum());
            summarize.setReducerNum(getReducerNum());
            summarize.execute();
            dirMgr.deleteAll();
        } catch (IOException e) {
            throw new ProcessorExecutionException(e);
        } catch (IllegalAccessException e) {
            throw new ProcessorExecutionException(e);
        }
    }


    @Override
    public boolean putDescription(String uuid, String description) throws DatabaseException {
        if (uuid == null) throw new NullPointerException("uuid");
        if (description == null) throw new NullPointerException("description");
        try {
            getConnection().setAutoCommit(false);
        } catch (SQLException e) {
            LOGGER.warn("Unable to set autocommit off", e);
        }
        boolean found = true;
        try {
            PreparedStatement findSt = getConnection().prepareStatement(SELECT_COMMON_DESCRIPTION_STATEMENT);
            PreparedStatement updSt = null;
            findSt.setString(1, uuid);
            ResultSet rs = findSt.executeQuery();
            found = rs.next();
            int modified = 0;
            updSt = getConnection().prepareStatement(found ? UPDATE_COMMON_DESCRIPTION_STATEMENT : INSERT_COMMON_DESCRIPTION_STATEMENT);
            updSt.setString(1, description);
            updSt.setString(2, uuid);
            modified = updSt.executeUpdate();
            if (modified == 1) {
                getConnection().commit();
                LOGGER.debug("DB has been updated. Queries: \"" + findSt + "\" and \"" + updSt + "\"");
            } else {
                getConnection().rollback();
                LOGGER.error("DB has not been updated -> rollback! Queries: \"" + findSt + "\" and \"" + updSt + "\"");
                found = false;
            }
        } catch (SQLException e) {
            LOGGER.error(e);
            found = false;
        } finally {
            closeConnection();
        }
        return found;
    }


    @Override
    public boolean putUserDescription(String openID, String uuid, String description) throws DatabaseException {
        if (uuid == null) throw new NullPointerException("uuid");
        if (description == null) throw new NullPointerException("description");
        try {
            getConnection().setAutoCommit(false);
        } catch (SQLException e) {
            LOGGER.warn("Unable to set autocommit off", e);
        }
        boolean found = true;
        try {
            int modified = 0;
            PreparedStatement updSt = getConnection().prepareStatement(UPDATE_USER_DESCRIPTION_STATEMENT);
            updSt.setString(1, description);
            updSt.setString(2, uuid);
            updSt.setString(3, openID);
            modified = updSt.executeUpdate();
            if (modified == 1) {
                getConnection().commit();
                LOGGER.debug("DB has been updated. Query: \"" + updSt + "\"");
            } else {
                getConnection().rollback();
                LOGGER.error("DB has not been updated -> rollback!  Query: \"" + updSt + "\"");
                found = false;
            }
        } catch (SQLException e) {
            LOGGER.error(e);
            found = false;
        } finally {
            closeConnection();
        }
        return found;
    }


    private static void copyFile(File source, File dest) throws IOException {
        FileChannel srcChannel = new FileInputStream(source).getChannel();
        FileChannel dstChannel = new FileOutputStream(dest).getChannel();
        dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
        srcChannel.close();
        dstChannel.close();
    }


    public void copyFile(String source_name, String dest_name) throws IOException {
        File source_file = new File(source_name);
        File destination_file = new File(dest_name);
        FileInputStream source = null;
        FileOutputStream destination = null;
        byte[] buffer;
        int bytes_read;
        try {
            if (!source_file.exists() || !source_file.isFile()) throw new FileCopyException(MM.PHRASES.getPhrase("25") + " " + source_name);
            if (!source_file.canRead()) throw new FileCopyException(MM.PHRASES.getPhrase("26") + " " + MM.PHRASES.getPhrase("27") + ": " + source_name);
            if (destination_file.exists()) {
                if (destination_file.isFile()) {
                    DataInputStream in = new DataInputStream(System.in);
                    String response;
                    if (!destination_file.canWrite()) throw new FileCopyException(MM.PHRASES.getPhrase("28") + " " + MM.PHRASES.getPhrase("29") + ": " + dest_name);
                    System.out.print(MM.PHRASES.getPhrase("19") + dest_name + MM.PHRASES.getPhrase("30") + ": ");
                    System.out.flush();
                    response = in.readLine();
                    if (!response.equals("Y") && !response.equals("y")) throw new FileCopyException(MM.PHRASES.getPhrase("31"));
                } else throw new FileCopyException(MM.PHRASES.getPhrase("28") + " " + MM.PHRASES.getPhrase("32") + ": " + dest_name);
            } else {
                File parentdir = parent(destination_file);
                if (!parentdir.exists()) throw new FileCopyException(MM.PHRASES.getPhrase("28") + " " + MM.PHRASES.getPhrase("33") + ": " + dest_name);
                if (!parentdir.canWrite()) throw new FileCopyException(MM.PHRASES.getPhrase("28") + " " + MM.PHRASES.getPhrase("34") + ": " + dest_name);
            }
            source = new FileInputStream(source_file);
            destination = new FileOutputStream(destination_file);
            buffer = new byte[1024];
            while (true) {
                bytes_read = source.read(buffer);
                if (bytes_read == -1) break;
                destination.write(buffer, 0, bytes_read);
            }
        } finally {
            if (source != null) try {
                source.close();
            } catch (IOException e) {
                ;
            }
            if (destination != null) try {
                destination.close();
            } catch (IOException e) {
                ;
            }
        }
    }


    public void copyFile2(String src, String dest) throws IOException {
        FileWriter fw = null;
        FileReader fr = null;
        BufferedReader br = null;
        BufferedWriter bw = null;
        File source = null;
        try {
            fr = new FileReader(src);
            fw = new FileWriter(dest);
            br = new BufferedReader(fr);
            bw = new BufferedWriter(fw);
            source = new File(src);
            int fileLength = (int) source.length();
            char charBuff[] = new char[fileLength];
            while (br.read(charBuff, 0, fileLength) != -1) bw.write(charBuff, 0, fileLength);
        } catch (FileNotFoundException fnfe) {
            throw new FileCopyException(src + " " + MM.PHRASES.getPhrase("35"));
        } catch (IOException ioe) {
            throw new FileCopyException(MM.PHRASES.getPhrase("36"));
        } finally {
            try {
                if (br != null) br.close();
                if (bw != null) bw.close();
            } catch (IOException ioe) {
            }
        }
    }


    private String getMAC(String password) {
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("SHA");
        } catch (NoSuchAlgorithmException e) {
        }
        try {
            md.update(password.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
        }
        byte raw[] = md.digest();
        String hash = (new BASE64Encoder()).encode(raw);
        return hash;
    }


    public void fillData() {
        try {
            URL urlhome = OpenerIF.class.getResource("Home.html");
            URLConnection uc = urlhome.openConnection();
            InputStreamReader input = new InputStreamReader(uc.getInputStream());
            BufferedReader in = new BufferedReader(input);
            String inputLine;
            String htmlData = "";
            while ((inputLine = in.readLine()) != null) {
                htmlData += inputLine;
            }
            in.close();
            String[] str = new String[9];
            str[0] = getLibName();
            str[1] = getLoginId();
            str[2] = getLoginName();
            str[3] = getVerusSubscriptionIdHTML();
            str[4] = getPendingJobsHTMLCode();
            str[5] = getFrequentlyUsedScreensHTMLCode();
            str[6] = getOpenCatalogHTMLCode();
            str[7] = getNewsHTML();
            str[8] = getOnlineInformationHTML();
            MessageFormat mf = new MessageFormat(htmlData);
            String htmlContent = mf.format(htmlData, str);
            PrintWriter fw = new PrintWriter(System.getProperty("user.home") + "/homeNGL.html");
            fw.println(htmlContent);
            fw.flush();
            fw.close();
            new LocalHtmlRendererContext(panel, new SimpleUserAgentContext(), this).navigate("file:" + System.getProperty("user.home") + "/homeNGL.html");
        } catch (Exception exp) {
            exp.printStackTrace();
        }
    }


    @Override
    public void run() {
        try {
            URL urlhome = new URL("http://www.verussolutions.biz/NGLDashBoard.xml");
            URLConnection uc = urlhome.openConnection();
            InputStreamReader input = new InputStreamReader(uc.getInputStream());
            BufferedReader in = new BufferedReader(input);
            String inputLine;
            String xmlData = "";
            while ((inputLine = in.readLine()) != null) {
                xmlData += inputLine;
            }
            in.close();
            PrintWriter fw = new PrintWriter(new FileWriter(System.getProperty("user.home") + "/NGLDashBoard.xml"));
            fw.println(xmlData);
            fw.flush();
            fw.close();
        } catch (Exception exp) {
            exp.printStackTrace();
        }
        try {
            Document doc = new SAXBuilder().build(new File(System.getProperty("user.home") + "/NGLDashBoard.xml"));
            String onlinsuppcdat = doc.getRootElement().getChild("OnlineSupportInformation").getText();
            CDATA cdata = new CDATA(onlinsuppcdat);
            host.setOnlineInformationHTML(cdata.getText());
            onlinsuppcdat = doc.getRootElement().getChild("News").getText();
            cdata = new CDATA(onlinsuppcdat);
            host.setNewsHTML(cdata.getText());
            host.fillData();
        } catch (Exception exp) {
            exp.printStackTrace();
        }
    }


    public String digestResponse() {
        String digest = null;
        if (null == nonce) return null;
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(username.getBytes());
            md.update(":".getBytes());
            md.update(realm.getBytes());
            md.update(":".getBytes());
            md.update(password.getBytes());
            byte[] d = md.digest();
            if (null != algorithm && -1 != (algorithm.toLowerCase()).indexOf("md5-sess")) {
                md = MessageDigest.getInstance("MD5");
                md.update(d);
                md.update(":".getBytes());
                md.update(nonce.getBytes());
                md.update(":".getBytes());
                md.update(cnonce.getBytes());
                d = md.digest();
            }
            byte[] a1 = bytesToHex(d);
            md = MessageDigest.getInstance("MD5");
            md.update(method.getBytes());
            md.update(":".getBytes());
            md.update(uri.getBytes());
            d = md.digest();
            byte[] a2 = bytesToHex(d);
            md = MessageDigest.getInstance("MD5");
            md.update(a1);
            md.update(":".getBytes());
            md.update(nonce.getBytes());
            md.update(":".getBytes());
            if (null != qop) {
                md.update(nonceCount.getBytes());
                md.update(":".getBytes());
                md.update(cnonce.getBytes());
                md.update(":".getBytes());
                md.update(qop.getBytes());
                md.update(":".getBytes());
            }
            md.update(a2);
            d = md.digest();
            byte[] r = bytesToHex(d);
            digest = new String(r);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return digest;
    }


    private static boolean CopyFile(File srcFile, File tagFile) throws IOException {
        if (srcFile == null || tagFile == null) {
            return false;
        }
        int length = 2097152;
        File dirFile = new File(getFileFolder(tagFile.getAbsolutePath()));
        if (!dirFile.exists()) {
            dirFile.mkdirs();
        }
        FileInputStream in = new FileInputStream(srcFile);
        FileOutputStream out = new FileOutputStream(tagFile.getAbsolutePath());
        FileChannel inC = in.getChannel();
        FileChannel outC = out.getChannel();
        int i = 0;
        while (true) {
            if (inC.position() == inC.size()) {
                inC.close();
                outC.close();
                break;
            }
            if ((inC.size() - inC.position()) < 20971520) length = (int) (inC.size() - inC.position()); else length = 20971520;
            inC.transferTo(inC.position(), length, outC);
            inC.position(inC.position() + length);
            i++;
        }
        return true;
    }


    public void search() throws Exception {
        URL searchurl = new URL("" + "http://www.ncbi.nlm.nih.gov/blast/Blast.cgi" + "?CMD=Put" + "&DATABASE=" + this.database + "&PROGRAM=" + this.program + "&QUERY=" + this.sequence.seqString());
        BufferedReader reader = new BufferedReader(new InputStreamReader(searchurl.openStream(), "UTF-8"));
        String line = "";
        while ((line = reader.readLine()) != null) {
            if (line.contains("Request ID")) this.rid += line.substring(70, 81);
        }
        reader.close();
    }


    public void dispatch(com.sun.star.util.URL aURL, com.sun.star.beans.PropertyValue[] aArguments) {
        if (aURL.Protocol.compareTo("org.openoffice.oosvn.oosvn:") == 0) {
            OoDocProperty docProperty = getProperty();
            settings.setCancelFired(false);
            if (aURL.Path.compareTo("svnUpdate") == 0) {
                try {
                    try {
                        settings = getSerializedSettings(docProperty);
                    } catch (NullPointerException ex) {
                        new DialogSettings(new javax.swing.JFrame(), true, settings).setVisible(true);
                        if (settings.getCancelFired()) return;
                        new DialogFileChooser(new javax.swing.JFrame(), true, settings).setVisible(true);
                        if (settings.getCancelFired()) return;
                    } catch (Exception ex) {
                        error("Error getting settings", ex);
                        return;
                    }
                    Object[][] logs = getLogs(settings);
                    long checkVersion = -1;
                    if (logs.length == 0) {
                        error("Sorry, the specified repository is empty.");
                        return;
                    }
                    new DialogSVNHistory(new javax.swing.JFrame(), true, settings, logs).setVisible(true);
                    if (settings.getCancelFired()) return;
                    File tempDir = new File(settings.getCheckoutPath() + svnWorker.tempDir);
                    if (tempDir.exists()) {
                        if (deleteFileDir(tempDir) == false) {
                            error("Error while deleting temporary checkout dir.");
                        }
                    }
                    svnWorker.checkout(settings);
                    File[] tempFiles = tempDir.listFiles();
                    File anyOdt = null;
                    File thisOdt = null;
                    for (int j = 0; j < tempFiles.length; j++) {
                        if (tempFiles[j].toString().endsWith(".odt")) anyOdt = tempFiles[j];
                        if (tempFiles[j].toString().equals(settings.getCheckoutDoc()) && settings.getCheckoutDoc() != null) thisOdt = tempFiles[j];
                    }
                    if (thisOdt != null) anyOdt = thisOdt;
                    String url;
                    if (settings.getCheckoutDoc() == null || !settings.getCheckoutDoc().equals(anyOdt.getName())) {
                        File newOdt = new File(settings.getCheckoutPath() + "/" + anyOdt.getName());
                        if (newOdt.exists()) newOdt.delete();
                        anyOdt.renameTo(newOdt);
                        File svnInfo = new File(settings.getCheckoutPath() + svnWorker.tempDir + "/.svn");
                        File newSvnInfo = new File(settings.getCheckoutPath() + "/.svn");
                        if (newSvnInfo.exists()) {
                            if (deleteFileDir(newSvnInfo) == false) {
                                error("Error while deleting temporary checkout dir.");
                            }
                        }
                        url = "file:///" + newOdt.getPath().replace("\\", "/");
                        svnInfo.renameTo(newSvnInfo);
                        anyOdt = newOdt;
                        loadDocumentFromUrl(url);
                        settings.setCheckoutDoc(anyOdt.getName());
                        try {
                            settings.serializeOut();
                        } catch (Exception ex) {
                            error("Error occured when re-newing settings.", ex);
                        }
                    } else {
                        try {
                            settings.serializeOut();
                        } catch (Exception ex) {
                            error("Error occured when re-newing settings.", ex);
                        }
                        url = "file:///" + anyOdt.getPath().replace("\\", "/");
                        XDispatchProvider xDispatchProvider = (XDispatchProvider) UnoRuntime.queryInterface(XDispatchProvider.class, m_xFrame);
                        PropertyValue property[] = new PropertyValue[1];
                        property[0] = new PropertyValue();
                        property[0].Name = "URL";
                        property[0].Value = url;
                        XMultiServiceFactory xMSF = createProvider();
                        Object objDispatchHelper = m_xServiceManager.createInstanceWithContext("com.sun.star.frame.DispatchHelper", m_xContext);
                        XDispatchHelper xDispatchHelper = (XDispatchHelper) UnoRuntime.queryInterface(XDispatchHelper.class, objDispatchHelper);
                        xDispatchHelper.executeDispatch(xDispatchProvider, ".uno:CompareDocuments", "", 0, property);
                    }
                } catch (Exception ex) {
                    error(ex);
                }
                return;
            }
            if (aURL.Path.compareTo("svnCommit") == 0) {
                try {
                    try {
                        settings = getSerializedSettings(docProperty);
                    } catch (Exception ex) {
                        error("Error getting settings", ex);
                        return;
                    }
                    Collection logs = svnWorker.getLogs(settings);
                    long headRevision = svnWorker.getHeadRevisionNumber(logs);
                    long committedRevision = -1;
                    new DialogCommitMessage(new javax.swing.JFrame(), true, settings).setVisible(true);
                    if (settings.getCancelFired()) return;
                    try {
                        settings.serializeOut();
                    } catch (Exception ex) {
                        error("Error occured when re-newing settings.", ex);
                    }
                    if (headRevision == 0) {
                        File impDir = new File(settings.getCheckoutPath() + svnWorker.tempDir + "/.import");
                        if (impDir.exists()) if (deleteFileDir(impDir) == false) {
                            error("Error while creating temporary import directory.");
                            return;
                        }
                        if (!impDir.mkdirs()) {
                            error("Error while creating temporary import directory.");
                            return;
                        }
                        File impFile = new File(settings.getCheckoutPath() + svnWorker.tempDir + "/.import/" + settings.getCheckoutDoc());
                        try {
                            FileChannel srcChannel = new FileInputStream(settings.getCheckoutPath() + "/" + settings.getCheckoutDoc()).getChannel();
                            FileChannel dstChannel = new FileOutputStream(impFile).getChannel();
                            dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
                            srcChannel.close();
                            dstChannel.close();
                        } catch (Exception ex) {
                            error("Error while importing file", ex);
                            return;
                        }
                        final String checkoutPath = settings.getCheckoutPath();
                        try {
                            settings.setCheckoutPath(impDir.toString());
                            committedRevision = svnWorker.importDirectory(settings, false).getNewRevision();
                        } catch (Exception ex) {
                            settings.setCheckoutPath(checkoutPath);
                            error("Error while importing file", ex);
                            return;
                        }
                        settings.setCheckoutPath(checkoutPath);
                        if (impDir.exists()) if (deleteFileDir(impDir) == false) error("Error while creating temporary import directory.");
                        try {
                            File newSvnInfo = new File(settings.getCheckoutPath() + "/.svn");
                            if (newSvnInfo.exists()) {
                                if (deleteFileDir(newSvnInfo) == false) {
                                    error("Error while deleting temporary checkout dir.");
                                }
                            }
                            File tempDir = new File(settings.getCheckoutPath() + svnWorker.tempDir);
                            if (tempDir.exists()) {
                                if (deleteFileDir(tempDir) == false) {
                                    error("Error while deleting temporary checkout dir.");
                                }
                            }
                            svnWorker.checkout(settings);
                            File svnInfo = new File(settings.getCheckoutPath() + svnWorker.tempDir + "/.svn");
                            svnInfo.renameTo(newSvnInfo);
                            if (deleteFileDir(tempDir) == false) {
                                error("Error while managing working copy");
                            }
                            try {
                                settings.serializeOut();
                            } catch (Exception ex) {
                                error("Error occured when re-newing settings.", ex);
                            }
                        } catch (Exception ex) {
                            error("Error while checking out a working copy for the location", ex);
                        }
                        showMessageBox("Import succesful", "Succesfully imported as revision no. " + committedRevision);
                        return;
                    } else {
                        try {
                            committedRevision = svnWorker.commit(settings, false).getNewRevision();
                        } catch (Exception ex) {
                            error("Error while committing changes. If the file is not working copy, you must use 'Checkout / Update' first.", ex);
                        }
                        if (committedRevision == -1) {
                            showMessageBox("Update - no changes", "No changes was made. Maybe you must just save the changes.");
                        } else {
                            showMessageBox("Commit succesfull", "Commited as revision no. " + committedRevision);
                        }
                    }
                } catch (Exception ex) {
                    error(ex);
                }
                return;
            }
            if (aURL.Path.compareTo("svnHistory") == 0) {
                try {
                    try {
                        settings = getSerializedSettings(docProperty);
                    } catch (Exception ex) {
                        error("Error getting settings", ex);
                        return;
                    }
                    Object[][] logs = getLogs(settings);
                    long checkVersion = settings.getCheckoutVersion();
                    settings.setCheckoutVersion(-99);
                    new DialogSVNHistory(new javax.swing.JFrame(), true, settings, logs).setVisible(true);
                    settings.setCheckoutVersion(checkVersion);
                } catch (Exception ex) {
                    error(ex);
                }
                return;
            }
            if (aURL.Path.compareTo("settings") == 0) {
                try {
                    settings = getSerializedSettings(docProperty);
                } catch (NoSerializedSettingsException ex) {
                    try {
                        settings.setCheckout(docProperty.getDocURL());
                    } catch (Exception exx) {
                    }
                } catch (Exception ex) {
                    error("Error getting settings; maybe you" + " need to save your document." + " If this is your first" + " checkout of the document, use Checkout" + " function directly.");
                    return;
                }
                new DialogSettings(new javax.swing.JFrame(), true, settings).setVisible(true);
                try {
                    settings.serializeOut();
                } catch (Exception ex) {
                    error("Error occured when saving settings.", ex);
                }
                return;
            }
            if (aURL.Path.compareTo("about") == 0) {
                showMessageBox("OoSvn :: About", "Autor: �t�p�n Cenek (stepan@geek.cz)");
                return;
            }
        }
    }


    public static boolean copyFile(String sourceFileName, String destFileName) {
        FileChannel ic = null;
        FileChannel oc = null;
        try {
            ic = new FileInputStream(sourceFileName).getChannel();
            oc = new FileOutputStream(destFileName).getChannel();
            ic.transferTo(0, ic.size(), oc);
            return true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                ic.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                oc.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }


    public boolean compile(URL url) {
        try {
            final InputStream stream = url.openStream();
            final InputSource input = new InputSource(stream);
            input.setSystemId(url.toString());
            return compile(input, _className);
        } catch (IOException e) {
            _parser.reportError(Constants.FATAL, new ErrorMsg(e));
            return false;
        }
    }


    public boolean compile(URL url, String name) {
        try {
            final InputStream stream = url.openStream();
            final InputSource input = new InputSource(stream);
            input.setSystemId(url.toString());
            return compile(input, name);
        } catch (IOException e) {
            _parser.reportError(Constants.FATAL, new ErrorMsg(e));
            return false;
        }
    }


    public static String post(String actionUrl, Map<String, String> params, FormFile[] files) {
        try {
            String BOUNDARY = "---------7d4a6d158c9";
            String MULTIPART_FORM_DATA = "multipart/form-data";
            URL url = new URL(actionUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(6 * 1000);
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Charset", "UTF-8");
            conn.setRequestProperty("Content-Type", MULTIPART_FORM_DATA + "; boundary=" + BOUNDARY);
            StringBuilder sb = new StringBuilder();
            for (Map.Entry<String, String> entry : params.entrySet()) {
                sb.append("--");
                sb.append(BOUNDARY);
                sb.append("\r\n");
                sb.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"\r\n\r\n");
                sb.append(entry.getValue());
                sb.append("\r\n");
            }
            DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());
            outStream.write(sb.toString().getBytes());
            for (FormFile file : files) {
                StringBuilder split = new StringBuilder();
                split.append("--");
                split.append(BOUNDARY);
                split.append("\r\n");
                split.append("Content-Disposition: form-data;name=\"" + file.getFileName() + "\";filename=\"" + file.getFileName() + "\"\r\n");
                split.append("Content-Type: " + file.getContentType() + "\r\n\r\n");
                outStream.write(split.toString().getBytes());
                outStream.write(file.getFileData(), 0, file.getFileData().length);
                outStream.write("\r\n".getBytes());
            }
            byte[] end_data = ("--" + BOUNDARY + "--\r\n").getBytes();
            outStream.write(end_data);
            outStream.flush();
            int cah = conn.getResponseCode();
            if (cah != 200) throw new RuntimeException("request URL failed");
            InputStream is = conn.getInputStream();
            int ch;
            StringBuilder b = new StringBuilder();
            while ((ch = is.read()) != -1) {
                b.append((char) ch);
            }
            Log.i("ItcastHttpPost", b.toString());
            outStream.close();
            conn.disconnect();
            return b.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    public static String post(String actionUrl, Map<String, String> params) {
        HttpPost httpPost = new HttpPost(actionUrl);
        List<NameValuePair> list = new ArrayList<NameValuePair>();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(list, HTTP.UTF_8));
            HttpResponse httpResponse = new DefaultHttpClient().execute(httpPost);
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                return EntityUtils.toString(httpResponse.getEntity());
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return null;
    }


    private void load() throws SQLException {
        Connection conn = null;
        Statement stmt = null;
        try {
            conn = FidoDataSource.getConnection();
            conn.setAutoCommit(false);
            stmt = conn.createStatement();
            ClearData.clearTables(stmt);
            stmt.executeUpdate("insert into AttributeCategories (CategoryName) values ('color')");
            stmt.executeUpdate("insert into Attributes (AttributeName, Category) values ('blue', 'color')");
            stmt.executeUpdate("insert into Attributes (AttributeName, Category) values ('red', 'color')");
            stmt.executeUpdate("insert into Objects (ObjectId, Description) values (100, 'ball')");
            stmt.executeUpdate("insert into Objects (ObjectId, Description) values (101, 'blue ball')");
            stmt.executeUpdate("insert into Objects (ObjectId, Description) values (102, 'red ball')");
            stmt.executeQuery("select setval('objects_objectid_seq', 1000)");
            stmt.executeUpdate("insert into ObjectLinks (ObjectId, LinkName, LinkToObject) values (100, 'isa', 1)");
            stmt.executeUpdate("insert into ObjectLinks (ObjectId, LinkName, LinkToObject) values (101, 'instance', 100)");
            stmt.executeUpdate("insert into ObjectLinks (ObjectId, LinkName, LinkToObject) values (102, 'instance', 100)");
            stmt.executeUpdate("insert into ObjectAttributes (ObjectId, AttributeName) values (101, 'blue')");
            stmt.executeUpdate("insert into ObjectAttributes (ObjectId, AttributeName) values (102, 'red')");
            stmt.executeUpdate("insert into Dictionary (Word, SenseNumber, GrammarString, ObjectId) values ('LEFT-WALL', '1', 'AV+ | ADJ+', 1)");
            stmt.executeUpdate("insert into Dictionary (Word, SenseNumber, GrammarString, ObjectId) values ('the', '1', 'D+', 1)");
            stmt.executeUpdate("insert into Dictionary (Word, SenseNumber, GrammarString, ObjectId) values ('red', '1', 'ADJ- | ADJ+', 1)");
            stmt.executeUpdate("insert into Dictionary (Word, SenseNumber, GrammarString, ObjectId) values ('blue', '1', 'ADJ- | ADJ+', 1)");
            stmt.executeUpdate("insert into Dictionary (Word, SenseNumber, GrammarString, ObjectId) values ('ball', '1', '[@ADJ-] & [D-] & DO-', 100)");
            stmt.executeUpdate("insert into Dictionary (Word, SenseNumber, GrammarString, ObjectId) values ('throw', '1', 'AV- & DO+', 1)");
            stmt.executeUpdate("insert into GrammarLinks (LinkName, LinkType) values ('DO', 3)");
            stmt.executeUpdate("insert into GrammarLinks (LinkName, LinkType) values ('AV', 7)");
            stmt.executeUpdate("insert into GrammarLinks (LinkName, LinkType) values ('D', 10)");
            stmt.executeUpdate("insert into GrammarLinks (LinkName, LinkType) values ('ADJ', 11)");
            stmt.executeUpdate("insert into Articles (ArticleName, Dereference) values ('the', 1)");
            stmt.executeUpdate("insert into FrameSlots (SlotName) values ('object')");
            stmt.executeUpdate("insert into QuestionWords (QuestionWord, Type) values ('which', 7)");
            stmt.executeUpdate("insert into Verbs (VerbName, Type, SubjectSlot, IndirectObjectSlot, PredicateNounSlot) values ('throw', 1, '', '', 'object')");
            stmt.executeQuery("select setval('instructions_instructionid_seq', 1)");
            stmt.executeUpdate("insert into Instructions (Type, ExecuteString, FrameSlot, Operator, LinkName, ObjectId, AttributeName) " + "values (3, '', null, 0, null, null, null)");
            stmt.executeQuery("select setval('transactions_transactionid_seq', 1)");
            stmt.executeUpdate("insert into Transactions (InstructionId, Description) values (2, 'throw')");
            stmt.executeQuery("select setval('verbtransactions_verbid_seq', 1)");
            stmt.executeUpdate("insert into VerbTransactions (VerbString, MoodType, TransactionId) values ('throw', 1, 2)");
            stmt.executeUpdate("insert into VerbConstraints (VerbId, FrameSlot, ObjectId) values (2, 'object', 1)");
            stmt.executeUpdate("update SystemProperties set value = 'Tutorial 3 Data' where name = 'DB Data Version'");
            conn.commit();
        } catch (SQLException e) {
            if (conn != null) conn.rollback();
            throw e;
        } finally {
            if (stmt != null) stmt.close();
            if (conn != null) conn.close();
        }
    }


    public void sendShape(String s) {
        try {
            URLConnection uc = new URL(url + "&add=" + s).openConnection();
            InputStream in = uc.getInputStream();
            int b;
            while ((b = in.read()) != -1) {
            }
            in.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }


        public void runInternal() {
            connection = null;
            boolean itemsLoadedPartially = false;
            boolean loadNext = false;
            HashSet<String> visited = new HashSet<String>();
            do {
                try {
                    setProgressMessage(url.toString(), -1);
                    visited.add(url.toString());
                    long startTimeStamp = System.currentTimeMillis();
                    delayedProgress = coolReader.getEngine().showProgressDelayed(0, progressMessage, PROGRESS_DELAY_MILLIS);
                    URLConnection conn = url.openConnection();
                    if (conn instanceof HttpsURLConnection) {
                        onError("HTTPs is not supported yet");
                        return;
                    }
                    if (!(conn instanceof HttpURLConnection)) {
                        onError("Only HTTP supported");
                        return;
                    }
                    connection = (HttpURLConnection) conn;
                    connection.setRequestProperty("User-Agent", "CoolReader/3(Android)");
                    if (referer != null) connection.setRequestProperty("Referer", referer);
                    connection.setInstanceFollowRedirects(true);
                    connection.setAllowUserInteraction(false);
                    connection.setConnectTimeout(CONNECT_TIMEOUT);
                    connection.setReadTimeout(READ_TIMEOUT);
                    connection.setDoInput(true);
                    String fileName = null;
                    String disp = connection.getHeaderField("Content-Disposition");
                    if (disp != null) {
                        int p = disp.indexOf("filename=");
                        if (p > 0) {
                            fileName = disp.substring(p + 9);
                        }
                    }
                    int response = -1;
                    response = connection.getResponseCode();
                    L.d("Response: " + response);
                    if (response != 200) {
                        onError("Error " + response);
                        return;
                    }
                    String contentType = connection.getContentType();
                    String contentEncoding = connection.getContentEncoding();
                    int contentLen = connection.getContentLength();
                    L.d("Entity content length: " + contentLen);
                    L.d("Entity content type: " + contentType);
                    L.d("Entity content encoding: " + contentEncoding);
                    setProgressMessage(url.toString(), contentLen);
                    InputStream is = connection.getInputStream();
                    delayedProgress.cancel();
                    is = new ProgressInputStream(is, startTimeStamp, progressMessage, contentLen, 80);
                    final int MAX_CONTENT_LEN_TO_BUFFER = 256 * 1024;
                    boolean isZip = contentType != null && contentType.equals("application/zip");
                    if (expectedType != null) contentType = expectedType; else if (contentLen > 0 && contentLen < MAX_CONTENT_LEN_TO_BUFFER) {
                        byte[] buf = new byte[contentLen];
                        if (is.read(buf) != contentLen) {
                            onError("Wrong content length");
                            return;
                        }
                        is.close();
                        is = null;
                        is = new ByteArrayInputStream(buf);
                        if (findSubstring(buf, "<?xml version=") >= 0 && findSubstring(buf, "<feed") >= 0) contentType = "application/atom+xml";
                    }
                    if (contentType.startsWith("application/atom+xml")) {
                        L.d("Parsing feed");
                        parseFeed(is);
                        itemsLoadedPartially = true;
                        if (handler.docInfo.nextLink != null && handler.docInfo.nextLink.type.startsWith("application/atom+xml;profile=opds-catalog")) {
                            if (handler.entries.size() < MAX_OPDS_ITEMS) {
                                url = new URL(handler.docInfo.nextLink.href);
                                loadNext = !visited.contains(url.toString());
                                L.d("continue with next part: " + url);
                            } else {
                                L.d("max item count reached: " + handler.entries.size());
                                loadNext = false;
                            }
                        } else {
                            loadNext = false;
                        }
                    } else {
                        if (fileName == null) fileName = defaultFileName;
                        L.d("Downloading book: " + contentEncoding);
                        downloadBook(contentType, url.toString(), is, contentLen, fileName, isZip);
                        if (progressShown) coolReader.getEngine().hideProgress();
                        loadNext = false;
                        itemsLoadedPartially = false;
                    }
                } catch (Exception e) {
                    L.e("Exception while trying to open URI " + url.toString(), e);
                    if (progressShown) coolReader.getEngine().hideProgress();
                    onError("Error occured while reading OPDS catalog");
                    break;
                } finally {
                    if (connection != null) try {
                        connection.disconnect();
                    } catch (Exception e) {
                    }
                }
            } while (loadNext);
            if (progressShown) coolReader.getEngine().hideProgress();
            if (itemsLoadedPartially) BackgroundThread.guiExecutor.execute(new Runnable() {

                @Override
                public void run() {
                    L.d("Parsing is finished successfully. " + handler.entries.size() + " entries found");
                    callback.onFinish(handler.docInfo, handler.entries);
                }
            });
        }


    byte[] toByteArray() throws IOException {
        DataElement element = new DataElement(DataElement.DATSEQ);
        final boolean sort = true;
        if (sort) {
            int[] sortIDs = new int[attributes.size()];
            int k = 0;
            for (Enumeration e = attributes.keys(); e.hasMoreElements(); ) {
                Integer key = (Integer) e.nextElement();
                sortIDs[k] = key.intValue();
                k++;
            }
            for (int i = 0; i < sortIDs.length; i++) {
                for (int j = 0; j < sortIDs.length - i - 1; j++) {
                    if (sortIDs[j] > sortIDs[j + 1]) {
                        int temp = sortIDs[j];
                        sortIDs[j] = sortIDs[j + 1];
                        sortIDs[j + 1] = temp;
                    }
                }
            }
            for (int i = 0; i < sortIDs.length; i++) {
                element.addElement(new DataElement(DataElement.U_INT_2, sortIDs[i]));
                element.addElement(getAttributeValue(sortIDs[i]));
            }
        } else {
            for (Enumeration e = attributes.keys(); e.hasMoreElements(); ) {
                Integer key = (Integer) e.nextElement();
                element.addElement(new DataElement(DataElement.U_INT_2, key.intValue()));
                element.addElement((DataElement) attributes.get(key));
            }
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        (new SDPOutputStream(out)).writeElement(element);
        return out.toByteArray();
    }


    public boolean populateRecord(int[] attrIDs) throws IOException {
        if (device == null) {
            throw new RuntimeException("This is local device service record");
        }
        if (attrIDs == null) {
            throw new NullPointerException("attrIDs is null");
        }
        if (attrIDs.length == 0) {
            throw new IllegalArgumentException();
        }
        for (int i = 0; i < attrIDs.length; i++) {
            if (attrIDs[i] < 0x0000 || attrIDs[i] > 0xffff) {
                throw new IllegalArgumentException();
            }
        }
        int[] sortIDs = new int[attrIDs.length];
        System.arraycopy(attrIDs, 0, sortIDs, 0, attrIDs.length);
        for (int i = 0; i < sortIDs.length; i++) {
            for (int j = 0; j < sortIDs.length - i - 1; j++) {
                if (sortIDs[j] > sortIDs[j + 1]) {
                    int temp = sortIDs[j];
                    sortIDs[j] = sortIDs[j + 1];
                    sortIDs[j + 1] = temp;
                }
            }
        }
        for (int i = 0; i < sortIDs.length - 1; i++) {
            if (sortIDs[i] == sortIDs[i + 1]) {
                throw new IllegalArgumentException();
            }
            DebugLog.debug0x("query for ", sortIDs[i]);
        }
        DebugLog.debug0x("query for ", sortIDs[sortIDs.length - 1]);
        return this.bluetoothStack.populateServicesRecordAttributeValues(this, sortIDs);
    }


    public static void copyFile(File in, File out) throws IOException {
        FileChannel inChannel = new FileInputStream(in).getChannel();
        FileChannel outChannel = new FileOutputStream(out).getChannel();
        try {
            int maxCount = (64 * 1024 * 1024) - (32 * 1024);
            long size = inChannel.size();
            long position = 0;
            while (position < size) {
                position += inChannel.transferTo(position, maxCount, outChannel);
            }
            out.setLastModified(in.lastModified());
        } catch (IOException e) {
            throw e;
        } finally {
            if (inChannel != null) inChannel.close();
            if (outChannel != null) outChannel.close();
        }
    }


    private File sendQuery(String query) throws MusicBrainzException {
        File xmlServerResponse = null;
        try {
            xmlServerResponse = new File(SERVER_RESPONSE_FILE);
            long start = Calendar.getInstance().getTimeInMillis();
            System.out.println("\n\n++++++++++++++++++++++++++++++++++++++++++++++++++++");
            System.out.println("    consulta de busqueda -> " + query);
            URL url = new URL(query);
            BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
            String response = "";
            String line = "";
            System.out.println("    Respuesta del servidor: \n");
            while ((line = in.readLine()) != null) {
                response += line;
            }
            xmlServerResponse = new File(SERVER_RESPONSE_FILE);
            System.out.println("    Ruta del archivo XML -> " + xmlServerResponse.getAbsolutePath());
            BufferedWriter out = new BufferedWriter(new FileWriter(xmlServerResponse));
            out.write(response);
            out.close();
            System.out.println("Tamanho del xmlFile -> " + xmlServerResponse.length());
            long ahora = (Calendar.getInstance().getTimeInMillis() - start);
            System.out.println(" Tiempo transcurrido en la consulta (en milesimas) -> " + ahora);
            System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n");
        } catch (IOException e) {
            e.printStackTrace();
            String msg = e.getMessage();
            if (e instanceof FileNotFoundException) {
                msg = "ERROR: MusicBrainz URL used is not found:\n" + msg;
            } else {
            }
            throw new MusicBrainzException(msg);
        }
        return xmlServerResponse;
    }