private void _parseBundleTags(ref Bundle toBeBundle)
        {
            List<String> tags = new List<String>();

            foreach (DocType.Field field in toBeBundle.type.tagFields) {
                if (toBeBundle.meta.keyValueData.ContainsKey(field.id)) {
                    string toParse = "";
                    toBeBundle.meta.keyValueData.TryGetValue(field.id, out toParse);
                    String[] strs = Regex.Split(toParse, ";;");
                    foreach (String st in strs) {
                        String[] tagss = Regex.Split(st, "::");
                        tags.Add(tagss.Last<String>().Trim());
                    }
                }
            }
            toBeBundle.weeTags = tags;
        }
        public Bundle getBundleInfo(string bundleId)
        {
            Bundle toBeBundle = new Bundle { meta = GetAllMetaFromBundle(bundleId), weeId = bundleId };
            if (toBeBundle == null || toBeBundle.meta == null) return null;

            if (toBeBundle.meta.keyValueData.ContainsKey("dc.type")) {
                String idDocType = toBeBundle.meta.keyValueData["dc.type"];
                if (!this.docTypes.ContainsKey(idDocType)) {
                    //try to get new docTypes
                    this.docTypes = getDocTypes();
                }

                if (!this.docTypes.ContainsKey(idDocType)) {
                    //still don't know the doc type return null
                    return null;
                }
                toBeBundle.type = this.docTypes[idDocType];
            }
            _parseBundleTags(ref toBeBundle);
            _extracFilesInfo(ref toBeBundle);
            return toBeBundle;
        }
        private void _extracFilesInfo(ref Bundle toBeBundle)
        {
            string bundleId = toBeBundle.weeId;
            List<String> ids = toBeBundle.meta.getFilesMd5s();
            List<Ficheiro> files = new List<Ficheiro>();
            if (ids != null) {
                foreach (String fid in ids) {
                    HttpResponseMessage resp = null;
                    bool bo = true;
                    if (ids != null) {
                        //has files
                        while (bo) {
                            try {
                                resp = _client.Get("core/file/" + bundleId + "/" + fid + "?operation=retrieveFileMetadata");
                                                    _checkAndThrowsExceptions(resp.StatusCode, "extract files info");
                                bo = false;
                            }
                            catch (HttpStageProcessingException e) {
                                continue;
                            }
                        }
                    }

                    //parse file names
                    String s = resp.Content.ReadAsString();
                    string pattern = "(<entry key=\"file.filename\">)([^<]*)(</entry>)";
                    MatchCollection matches = Regex.Matches(s, pattern);
                    foreach (Match matche in matches) {
                        if (matche.Groups.Count >= 1) {
                            Group group = matche.Groups[2];
                            toBeBundle.filesPath.Add(new Ficheiro(group.Value, bundleId, fid));
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Synchronize one bundle
        /// </summary>
        /// <param name="bundle">The bundle to be synchronized</param>
        /// <returns></returns>
        public string syncBundle(Bundle bundle){
            String bundle_lastest_version_id = core.GetLatestVersionIdFromServer(bundle.weeId);
            if (bundle_lastest_version_id == null){
                //bundle foi eliminado do servidor
                //delete bundle from db 
                //delete bundle from FS
                try{
                    fileSystem.DeleteRecursiveFolder(bundle.getPath(path_bundles));
                    dataBase.DeleteBundle(bundle.localId);
                    foreach (String t in bundle.weeTags){
                        Tag tag;
                        if ((tag = Scheme.getTagByWeeIds(t, scheme)) != null){
                            fileSystem.DeleteFile(tag.Path + "\\" + bundle.localId + ".lnk"); //tags exists 
                        }
                        //else .... -> if the tags have been removed we don't care.
                    }
                return null;

                }catch(Exception e){
                    ; 
                }

                }
                if (bundle_lastest_version_id == bundle.weeId){
                    //Bundle doesn't have a new version on server
                    _sync_with_no_new_version(bundle);
                    Bundle bundle2 = core.GetLatestVersionFromServer (bundle_lastest_version_id);
                    if (bundle2 != null)
                        bundle2.localId = bundle.localId;
                        generateBundleWebPage(bundle2);
                return bundle_lastest_version_id;
            }
            else{
                //bundle has a new version on server
                _sync_with_new_version(bundle);
                Bundle b = core.getBundleInfo(bundle_lastest_version_id); 
                generateBundleWebPage(b);
                    bundle2.localId = bundle.localId;
                    generateBundleWebPage (bundle2);
                }
                return bundle_lastest_version_id;
            }
 /**
  * retrieves all the bundles stored in the database
  * ::Checked::
  */
 public List<Bundle> GetAllBundles()
 {
     //todas as tabelas
     Bundle bundle = new Bundle();
     List<Bundle> lista = new List<Bundle>();
     SqlConnection con = new SqlConnection(connectionString);
     con.Open();
     SqlCommand query = new SqlCommand("SELECT * FROM bundle", con);
     SqlDataReader reader = query.ExecuteReader();
     while (reader.Read()) {
         bundle = GetBundle(reader.GetString(0));
         lista.Add(bundle);
     }
     con.Close();
     return lista;
 }
 public void UpdateBundle(Bundle b)
 {
     DeleteBundle(b.localId);
     SaveBundle(b);
 }
        /**
         * stores a bundle into the database.
         * any old info associated with that bundle is cleared.
         * ::Checked::
         */
        public void SaveBundle(Bundle bundle)
        {
            if (bundle == null)
                return;

            SqlConnection con = new SqlConnection(connectionString);

            con.Open();
            SqlCommand query = new SqlCommand(string.Format(
                "INSERT INTO bundle (id, version_ID) VALUES ('{0}', '{1}')",
                bundle.localId, bundle.weeId), con);
            query.ExecuteNonQuery();
            // clear old data from last_updated_versions
            query = new SqlCommand(string.Format(
                "delete from last_updated_versions where bundle_version_ID = '{0}'", bundle.weeId), con);
            query.ExecuteNonQuery();
            foreach (Ficheiro f in bundle.filesPath) {
                // insert last_updated_versions
                query = new SqlCommand(string.Format(
                    "INSERT INTO last_updated_versions (bundle_version_ID, file_ID, nome_ficheiro) VALUES ('{0}', '{1}', '{2}')",
                    bundle.localId, bundle.weeId, f.path), con);
                query.ExecuteNonQuery();
            }
            //clear old files
            query = new SqlCommand(string.Format(
                "delete from ficheiro where bundleID = '{0}'", bundle.weeId), con);
            query.ExecuteNonQuery();
            foreach (Ficheiro f in bundle.filesPath) {
                // insert new files
                query = new SqlCommand(string.Format(
                    "INSERT INTO ficheiro (id, BundleID, nome_ficheiro) VALUES ('{0}', '{1}', '{2}')",
                    f.md5, bundle.localId, f.path), con);
                query.ExecuteNonQuery();
            }
            //clear existing metadata
            query = new SqlCommand(string.Format(
                "delete from metadata where BundleID = '{0}'", bundle.weeId), con);
            query.ExecuteNonQuery();
            /*            foreach (KeyValuePair<String, String> kvp in bundle.meta.keyValueData) {
                // insert metadata
                String v1 = kvp.Key;
                String v2 = kvp.Value;
                query = new SqlCommand(string.Format(
                    "INSERT INTO metadata (BundleID, field_name, field_data) VALUES ('{0}', '{1}', '{2}')",
                    bundle.localId, v1, v2), con);
                query.ExecuteNonQuery();
            }
             */
            //clear existing tags
            query = new SqlCommand(string.Format(
                "delete from tags where BundleID = '{0}'", bundle.weeId), con);
            query.ExecuteNonQuery();
            foreach (String tag in bundle.weeTags) {
                // insert new tags
                query =
                    new SqlCommand(
                        string.Format("INSERT INTO tags (BundleID, tag) VALUES ('{0}', '{1}')", bundle.localId, tag),
                        con);
                query.ExecuteNonQuery();
            }
            con.Close();
        }
        ///<summary>
        /// retrieves one bundle stored in the database
        /// ::Checked::
        ///</summary>
        public Bundle GetBundle(string id)
        {
            if (string.IsNullOrEmpty(id))
                return null;
            Bundle bundle = new Bundle();

            SqlConnection con = new SqlConnection(connectionString);
            con.Open();
            SqlCommand query = new SqlCommand(string.Format("SELECT * FROM bundle WHERE id = '{0}'", id), con);
            SqlDataReader reader = query.ExecuteReader();
            while (reader.Read()) {
                bundle.localId = reader.GetString(0);
                bundle.weeId = reader.GetString(1);
            }
            reader.Close();
            query = new SqlCommand(string.Format("SELECT * FROM ficheiro where bundleID = '{0}'", id), con);
            reader = query.ExecuteReader();
            var list = new List<Ficheiro>();
            while (reader.Read()) {
                Ficheiro f = new Ficheiro(
                    //path                  bundleID                    md5
                    reader.GetString(2), reader.GetString(1), reader.GetString(0));
                list.Add(f);
            }
            bundle.filesPath = list;
            reader.Close();
            query = new SqlCommand(string.Format("SELECT * FROM tags where bundleID = '{0}'", id), con);
            reader = query.ExecuteReader();
            while (reader.Read()) {
                bundle.weeTags.Add(reader.GetString(1));
            }
            reader.Close();
            query = new SqlCommand(string.Format("SELECT * FROM metadata where bundleID = '{0}'", id), con);
            reader = query.ExecuteReader();
            while (reader.Read()) {
                bundle.meta.keyValueData.Add(reader.GetString(1), reader.GetString(2));
            }
            reader.Close();

            con.Close();
            return bundle;
        }