public class AddBookmarkFragment extends Fragment {

	private FragmentBaseActivity base;
	
	private EditText mEditUrl;
	private EditText mEditDescription;
	private ProgressBar mDescriptionProgress;
	private EditText mEditNotes;
	private MultiAutoCompleteTextView mEditTags;
	private TextView mRecommendedTags;
	private ProgressBar mRecommendedProgress;
	private TextView mPopularTags;
	private ProgressBar mPopularProgress;
	private CompoundButton mPrivate;
	private Bookmark bookmark;
	private Bookmark oldBookmark;
	private Boolean update = false;
	
	private long updateTime = 0;
	
	private AsyncTask<String, Integer, String> titleTask;
	private AsyncTask<String, Integer, ArrayList<Tag>> tagTask;
	
	private OnBookmarkSaveListener bookmarkSaveListener;
	
	public interface OnBookmarkSaveListener {
		public void onBookmarkSave(Bookmark b);
		public void onBookmarkCancel(Bookmark b);
	}
	
	@Override
	public void onActivityCreated(Bundle savedInstanceState){
		super.onActivityCreated(savedInstanceState);
		
		base = (FragmentBaseActivity)getActivity();
		
		setHasOptionsMenu(true);
		
		mEditUrl = (EditText) getView().findViewById(R.id.add_edit_url);
		mEditDescription = (EditText) getView().findViewById(R.id.add_edit_description);
		mDescriptionProgress = (ProgressBar) getView().findViewById(R.id.add_description_progress);
		mEditNotes = (EditText) getView().findViewById(R.id.add_edit_notes);
		mEditTags = (MultiAutoCompleteTextView) getView().findViewById(R.id.add_edit_tags);
		mRecommendedTags = (TextView) getView().findViewById(R.id.add_recommended_tags);
		mRecommendedProgress = (ProgressBar) getView().findViewById(R.id.add_recommended_tags_progress);
		mPopularTags = (TextView) getView().findViewById(R.id.add_popular_tags);
		mPopularProgress = (ProgressBar) getView().findViewById(R.id.add_popular_tags_progress);
		mPrivate = (CompoundButton) getView().findViewById(R.id.add_edit_private);
		
		mRecommendedTags.setMovementMethod(LinkMovementMethod.getInstance());
		mPopularTags.setMovementMethod(LinkMovementMethod.getInstance());
		
		if(base.mAccount != null){
			String[] tagArray = new String[5];
			tagArray = TagManager.GetTagsAsArray(base.mAccount.name, Tag.Name + " ASC", base).toArray(tagArray);
			ArrayAdapter<String> autoCompleteAdapter = new ArrayAdapter<String>(base, R.layout.autocomplete_view, tagArray);
			mEditTags.setAdapter(autoCompleteAdapter);
			mEditTags.setTokenizer(new SpaceTokenizer());
		}

		mEditUrl.setOnFocusChangeListener(new OnFocusChangeListener(){
			public void onFocusChange(View v, boolean hasFocus) {
				if(!hasFocus){
					String url = mEditUrl.getText().toString();
					
					if(mEditDescription.getText().toString().equals("")) {
						titleTask = new GetTitleTask().execute(url);
					}
					tagTask = new GetTagSuggestionsTask().execute(url);
				}
			}
		});
	}
	
	@Override
	public void onStart(){
		super.onStart();
		
		refreshView();
	}
	
	public void loadBookmark(Bookmark b, Bookmark oldB){
		if(b != null)
			bookmark = b.copy();
		
		if(oldB != null)
			oldBookmark = oldB.copy();
	}
	
	public void refreshView(){
		if(bookmark != null){
			mEditUrl.setText(bookmark.getUrl());
			
			if(bookmark.getDescription() != null)
				mEditDescription.setText(bookmark.getDescription());
			
			if(bookmark.getNotes() != null)
				mEditNotes.setText(bookmark.getNotes());
			
			if(bookmark.getTagString() != null)
				mEditTags.setText(bookmark.getTagString());
			
			mPrivate.setChecked(!bookmark.getShared());
			
			if(mEditDescription.getText().toString().equals(""))
				titleTask = new GetTitleTask().execute(bookmark.getUrl());

			tagTask = new GetTagSuggestionsTask().execute(bookmark.getUrl());
		} else {
			if(!this.isHidden()){
				mEditUrl.requestFocus();
			}
			setDefaultValues();
		}
	}
	
	public void saveHandler(View v) {
		save();
		bookmarkSaveListener.onBookmarkSave(bookmark);
	}
	
	public void cancelHandler(View v) {    	
    	bookmarkSaveListener.onBookmarkCancel(bookmark);
	}
	
	private void setDefaultValues(){   	
    	mPrivate.setChecked(base.privateDefault);
	}
	
    private void save() {
    	
    	String url = mEditUrl.getText().toString();
    	String description = mEditDescription.getText().toString();
    	
    	if(description.equals(""))
    		description = getResources().getString(R.string.add_bookmark_default_title);
    	
    	if(url.equals("")) {
    		Toast.makeText(base, R.string.add_bookmark_blank_url, Toast.LENGTH_LONG).show();
    		return;
    	}	
    	
    	if(titleTask != null)
    		titleTask.cancel(true);
    	
    	if(tagTask != null)
    		tagTask.cancel(true);

		
		if(!url.startsWith("http")){
			url = "http://" + url;
		}
		
		String tagstring = "";
		String[] tags = mEditTags.getText().toString().trim().split(" ");

		for(String s : tags){
			if(!s.equals("") && !s.equals(" "))
				tagstring += (s + " ");
		}
		
		int oldid = 0;
		if(bookmark != null && bookmark.getId() != 0) {
			oldid = bookmark.getId();
			update = true;
			oldBookmark = bookmark.copy();
		}
		
		if(!update) {
			Date d = new Date();
			updateTime = d.getTime();
		}
			
		bookmark = new Bookmark(url, description, 
				mEditNotes.getText().toString(), tagstring.trim(),
				!mPrivate.isChecked(), updateTime);
		
		bookmark.setId(oldid);
		
		if(update){
			BookmarkManager.UpdateBookmark(bookmark, base.mAccount.name, base);
			
			for(Tag t : oldBookmark.getTags()){
				if(!bookmark.getTags().contains(t)) {
					TagManager.UpleteTag(t, base.mAccount.name, base);
				}
			}
		} else {
			BookmarkManager.AddBookmark(bookmark, base.mAccount.name, base);
		}
		
		for(Tag t : bookmark.getTags()){   				
			TagManager.UpsertTag(t, base.mAccount.name, base);
		}
    }
    
	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		super.onCreateOptionsMenu(menu, inflater);
		if(base.isMyself()) {
			inflater.inflate(R.menu.add_bookmark_menu, menu);
		}
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
	    // Handle item selection
	    switch (item.getItemId()) {
	    case R.id.menu_addbookmark_save:
	    	save();
			bookmarkSaveListener.onBookmarkSave(bookmark);
			return true;
	    case R.id.menu_addbookmark_cancel:
        	bookmarkSaveListener.onBookmarkCancel(bookmark);
	        return true;
	    default:
	        return super.onOptionsItemSelected(item);
	    }
	}
	
    TagSpan.OnTagClickListener tagOnClickListener = new TagSpan.OnTagClickListener() {
        public void onTagClick(String tag) {
        	String currentTagString = mEditTags.getText().toString();
        	
        	ArrayList<String> currentTags = new ArrayList<String>();
        	Collections.addAll(currentTags, currentTagString.split(" "));
        	
        	if(tag != null && tag != "") {
        		if(!currentTags.contains(tag)) {
		        	currentTags.add(tag);
        		} else {
        			currentTags.remove(tag);
        		}
        		mEditTags.setText(TextUtils.join(" ", currentTags.toArray()).trim());
        		mEditTags.setSelection(mEditTags.getText().length());
        	}
        }
    };
    
    public class GetTitleTask extends GetWebpageTitleTask{    	
    	protected void onPreExecute(){
    		mDescriptionProgress.setVisibility(View.VISIBLE);
    	}
    	
        protected void onPostExecute(String result) {
        	mEditDescription.setText(Html.fromHtml(result));
        	mDescriptionProgress.setVisibility(View.GONE);
        }
    }
    
    public class GetTagSuggestionsTask extends AsyncTask<String, Integer, ArrayList<Tag>>{
    	private String url;
    	
    	@Override
    	protected ArrayList<Tag> doInBackground(String... args) {
    		url = args[0];
	
    		try {
				return DeliciousApi.getSuggestedTags(url, base.mAccount, base);
			} catch (AuthenticationException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (TooManyRequestsException e) {
				e.printStackTrace();
			}
			return null;
    	}
    	
    	protected void onPreExecute() {
    		mRecommendedTags.setVisibility(View.GONE);
    		mPopularTags.setVisibility(View.GONE);
    		mRecommendedProgress.setVisibility(View.VISIBLE);
    		mPopularProgress.setVisibility(View.VISIBLE);
    	}
    	
        protected void onPostExecute(ArrayList<Tag> result) {
        	        	
        	if(result != null) {
        		SpannableStringBuilder recommendedBuilder = new SpannableStringBuilder();
        		SpannableStringBuilder popularBuilder = new SpannableStringBuilder();

        		for(Tag t : result) {
        			if(t.getType().equals("recommended")) {
        				addTag(recommendedBuilder, t);
        			} else if(t.getType().equals("popular")) {
        				addTag(popularBuilder, t);
        			}
        		}
        		
        		mRecommendedTags.setText(recommendedBuilder);
        		mPopularTags.setText(popularBuilder);
        		
        		mRecommendedTags.setVisibility(View.VISIBLE);
        		mPopularTags.setVisibility(View.VISIBLE);
        		mRecommendedProgress.setVisibility(View.GONE);
        		mPopularProgress.setVisibility(View.GONE);
        	} 	
        }

		private void addTag(SpannableStringBuilder builder, Tag t) {
			int flags = 0;
			
			if (builder.length() != 0) {
				builder.append("  ");
			}
			
			int start = builder.length();
			builder.append(t.getTagName());
			int end = builder.length();
			
			TagSpan span = new TagSpan(t.getTagName());
			span.setOnTagClickListener(tagOnClickListener);

			builder.setSpan(span, start, end, flags);
		}
    }
	
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.add_bookmark_fragment, container, false);
    }
    
	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		try {
			bookmarkSaveListener = (OnBookmarkSaveListener) activity;
		} catch (ClassCastException e) {
			throw new ClassCastException(activity.toString() + " must implement OnBookmarkSaveListener");
		}
	}
} public class BrowseBookmarkFeedFragment extends ListFragment 
	implements LoaderManager.LoaderCallbacks<Cursor> {
	
	private SimpleCursorAdapter mAdapter;
	private FragmentBaseActivity base;
	
	private String username = null;
	private String tagname = null;
	private Intent intent = null;
	String path = null;
	
	Bookmark lastSelected = null;
	
	ListView lv;
	
	static final String STATE_USERNAME = "username";
	static final String STATE_TAGNAME = "tagname";
	
	private BrowseBookmarksFragment.OnBookmarkSelectedListener bookmarkSelectedListener;
	
	@Override
	public void onActivityCreated(Bundle savedInstanceState){
		super.onActivityCreated(savedInstanceState);
		
	    if (savedInstanceState != null) {
	        username = savedInstanceState.getString(STATE_USERNAME);
	        tagname = savedInstanceState.getString(STATE_TAGNAME);
	    } 

		base = (FragmentBaseActivity)getActivity();
		intent = base.getIntent();
		
		setHasOptionsMenu(true);
		
		mAdapter = new SimpleCursorAdapter(base, R.layout.bookmark_view, null, 
				new String[]{Bookmark.Description, Bookmark.Tags, Bookmark.Shared}, 
				new int[]{R.id.bookmark_description, R.id.bookmark_tags, R.id.bookmark_private}, 0);
		
		setListAdapter(mAdapter);
		mAdapter.setViewBinder(new BookmarkViewBinder());

		if(base.mAccount != null) {
			setListShown(false);
			
	    	getLoaderManager().initLoader(0, null, this);
	    	
			lv = getListView();
			lv.setTextFilterEnabled(true);
			lv.setFastScrollEnabled(true);

			lv.setItemsCanFocus(false);
			lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
		
			lv.setOnItemClickListener(new OnItemClickListener() {
			    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
					final Cursor c = (Cursor)lv.getItemAtPosition(position);
					lastSelected = BookmarkManager.CursorToBookmark(c);
	
			    	if(base.defaultAction.equals("view")) {
			    		viewBookmark(lastSelected);
			    	} else if(base.defaultAction.equals("read")) {
			    		readBookmark(lastSelected);
			    	} else {
			    		openBookmarkInBrowser(lastSelected);
			    	}   	
			    }
			});
			
			/* Add Context-Menu listener to the ListView. */
			lv.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
				public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
					menu.setHeaderTitle("Actions");
					MenuInflater inflater = base.getMenuInflater();
					
					inflater.inflate(R.menu.browse_bookmark_context_menu_other, menu);
				}
			});
		}
	}

	@Override
	public void onSaveInstanceState(Bundle savedInstanceState) {
	    savedInstanceState.putString(STATE_USERNAME, username);
	    savedInstanceState.putString(STATE_TAGNAME, tagname);
	    
	    super.onSaveInstanceState(savedInstanceState);
	}
	
	public void setQuery(String username, String tagname){
		this.username = username;
		this.tagname = tagname;
	}
	
	@Override
	public void onResume(){
		super.onResume();
		
		if(Intent.ACTION_SEARCH.equals(intent.getAction())) {		
			String query = intent.getStringExtra(SearchManager.QUERY);
			base.setTitle(getString(R.string.search_results_global_tag_title, query));
		} else if(username.equals("recent")) {
			base.setTitle(getString(R.string.browse_recent_bookmarks_title));
		} else if(username.equals("network")) {
			base.setTitle(getString(R.string.browse_network_bookmarks_title));
		} else {	
			if(tagname != null && tagname != "") {
				base.setTitle(getString(R.string.browse_user_bookmarks_tagged_title, username, tagname));
			} else {
				base.setTitle(getString(R.string.browse_user_bookmarks_title, username));
			}
		}
		
		Uri data = base.getIntent().getData();
		if(data != null && data.getUserInfo() != null && data.getUserInfo() != "") {
			username = data.getUserInfo();
		} else if(base.getIntent().hasExtra("username")){
			username = base.getIntent().getStringExtra("username");
		} else username = base.mAccount.name;
	}
	
	@Override
	public boolean onContextItemSelected(MenuItem aItem) {
		AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) aItem.getMenuInfo();
		final Cursor c = (Cursor)lv.getItemAtPosition(menuInfo.position);
		Bookmark b = BookmarkManager.CursorToBookmark(c);
		
		switch (aItem.getItemId()) {
			case R.id.menu_bookmark_context_open:
				openBookmarkInBrowser(b);
				return true;
			case R.id.menu_bookmark_context_view:				
				viewBookmark(b);
				return true;
			case R.id.menu_bookmark_context_add:				
				bookmarkSelectedListener.onBookmarkAdd(b);
				return true;
			case R.id.menu_bookmark_context_read:
				readBookmark(b);
				return true;
			case R.id.menu_bookmark_context_share:
				bookmarkSelectedListener.onBookmarkShare(b);
				return true;
		}
		return false;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		boolean result = false;
		
	    switch (item.getItemId()) {
	    case R.id.menu_addbookmark:
			bookmarkSelectedListener.onBookmarkAdd(lastSelected);
			return true;
	    }
	    
	    if(result) {
	    	getLoaderManager().restartLoader(0, null, this);
	    } else result = super.onOptionsItemSelected(item);
	    
	    return result;
	}
		
	private void openBookmarkInBrowser(Bookmark b) {
		bookmarkSelectedListener.onBookmarkOpen(b);
	}
	
	private void viewBookmark(Bookmark b) {
		bookmarkSelectedListener.onBookmarkView(b);
	}
	
	private void readBookmark(Bookmark b){
		bookmarkSelectedListener.onBookmarkRead(b);
	}

	public Loader<Cursor> onCreateLoader(int id, Bundle args) {
		if(Intent.ACTION_SEARCH.equals(intent.getAction())) {		
			String query = intent.getStringExtra(SearchManager.QUERY);
			return new LoaderDrone(base, "global", query);
		} else if(username.equals("recent")) {
			return new LoaderDrone(base, "recent", null);
		} else if(username.equals("network")) {
			return new LoaderDrone(base, "network", null);
		} else {			
			return new LoaderDrone(base, username, tagname);
		}
	}
	
	public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
	    mAdapter.swapCursor(data);
	    
	    // The list should now be shown.
        if (isResumed()) {
            setListShown(true);
        } else {
            setListShownNoAnimation(true);
        }
	}
	
	public void onLoaderReset(Loader<Cursor> loader) {
	    mAdapter.swapCursor(null);
	}
	
	public static class LoaderDrone extends AsyncTaskLoader<Cursor> {
        
		private String user = "";
		private String tag = "";

		private FragmentBaseActivity base = null;
		
        public LoaderDrone(Context context, String u, String t) {
        	super(context);
        	
        	user = u;
            tag = t;
            base = (FragmentBaseActivity)context;
        	
            onForceLoad();
        }

        @Override
        public Cursor loadInBackground() {
            Cursor results = null;
            
 	       if(user.equals("global"))
 	    	   user = "tag";
        
 		   try {
 			   if(user.equals("network")) {
 				   results = DeliciousFeed.fetchNetworkRecent(base.mAccount.name);
 			   } else if(user.equals("recent")) {
 				  results = DeliciousFeed.fetchRecent();
 			   } else {
 				  results = DeliciousFeed.fetchUserRecent(user, tag);
 			   }

 		   }catch (ParseException e) {
 			   e.printStackTrace();
 		   }catch (IOException e) {
 			   e.printStackTrace();
 		   }

           return results;
        }
    }
	
	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		try {
			bookmarkSelectedListener = (OnBookmarkSelectedListener) activity;
		} catch (ClassCastException e) {
			throw new ClassCastException(activity.toString() + " must implement OnBookmarkSelectedListener");
		}
	}
} public class BrowseBookmarksFragment extends ListFragment 
	implements LoaderManager.LoaderCallbacks<Cursor> {
	
	private SimpleCursorAdapter mAdapter;
	private FragmentBaseActivity base;
	
	private String sortfield = Bookmark.Time + " DESC";

	private String username = null;
	private String tagname = null;
	private boolean unread = false;
	private String query = null;
	
	ListView lv;
	
	private static final String STATE_USERNAME = "username";
	
	private OnBookmarkSelectedListener bookmarkSelectedListener;
	
	public interface OnBookmarkSelectedListener {
		public void onBookmarkView(Bookmark b);
		public void onBookmarkRead(Bookmark b);
		public void onBookmarkOpen(Bookmark b);
		public void onBookmarkAdd(Bookmark b);
		public void onBookmarkShare(Bookmark b);
		public void onBookmarkEdit(Bookmark b);
		public void onBookmarkDelete(Bookmark b);
	}
	
	@Override
	public void onActivityCreated(Bundle savedInstanceState){
		super.onActivityCreated(savedInstanceState);
		
	    if (savedInstanceState != null) {
	        username = savedInstanceState.getString(STATE_USERNAME);
	    } 
		
		base = (FragmentBaseActivity)getActivity();
		
		setHasOptionsMenu(true);
		
		mAdapter = new SimpleCursorAdapter(base, R.layout.bookmark_view, null, 
				new String[]{Bookmark.Description, Bookmark.Tags, Bookmark.Shared, Bookmark.Synced}, 
				new int[]{R.id.bookmark_description, R.id.bookmark_tags, R.id.bookmark_private, R.id.bookmark_unsynced}, 0);
		
		setListAdapter(mAdapter);
		mAdapter.setViewBinder(new BookmarkViewBinder());

		if(base.mAccount != null) {				
	
	    	getLoaderManager().initLoader(0, null, this);
	    	
			lv = getListView();
			lv.setTextFilterEnabled(true);
			lv.setFastScrollEnabled(true);
			
			lv.setItemsCanFocus(false);
			lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
		
			lv.setOnItemClickListener(new OnItemClickListener() {
			    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
					final Cursor c = (Cursor)lv.getItemAtPosition(position);
					Bookmark b = BookmarkManager.CursorToBookmark(c);
	
			    	if(base.defaultAction.equals("view")) {
			    		viewBookmark(b);
			    	} else if(base.defaultAction.equals("read")) {
			    		readBookmark(b);
			    	} else {
			    		openBookmarkInBrowser(b);
			    	}   	
			    }
			});
			
			/* Add Context-Menu listener to the ListView. */
			lv.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
				public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
					menu.setHeaderTitle("Actions");
					MenuInflater inflater = base.getMenuInflater();

					inflater.inflate(R.menu.browse_bookmark_context_menu_self, menu);
				}
			});
		}
	}
	
	public void setQuery(String username, String tagname, boolean unread){
		this.username = username;
		this.tagname = tagname;
		this.unread = unread;
	}
	
	public void setSearchQuery(String query, String username, String tagname, boolean unread){
		this.query = query;
		this.username = username;
		this.tagname = tagname;
		this.unread = unread;
	}
	
	@Override
	public void onResume(){
		super.onResume();

		if(query != null) {
			if(unread) {
				base.setTitle(getString(R.string.unread_search_results_title, query));
			} else base.setTitle(getString(R.string.bookmark_search_results_title, query));
		} else {
			if(unread && tagname != null && tagname != "") {
				base.setTitle(getString(R.string.browse_my_unread_bookmarks_tagged_title, tagname));
			} else if(unread && (tagname == null || tagname.equals(""))) {
				base.setTitle(getString(R.string.browse_my_unread_bookmarks_title));
			} else if(tagname != null && tagname != "") {
				base.setTitle(getString(R.string.browse_my_bookmarks_tagged_title, tagname));
			} else {
				base.setTitle(getString(R.string.browse_my_bookmarks_title));
			}
		}

		Uri data = base.getIntent().getData();
		if(data != null && data.getUserInfo() != null && data.getUserInfo() != "") {
			username = data.getUserInfo();
		} else if(base.getIntent().hasExtra("username")){
			username = base.getIntent().getStringExtra("username");
		} else username = base.mAccount.name;
	}
	
	@Override
	public void onSaveInstanceState(Bundle savedInstanceState) {
	    savedInstanceState.putString(STATE_USERNAME, username);
	    
	    super.onSaveInstanceState(savedInstanceState);
	}
	
	@Override
	public boolean onContextItemSelected(MenuItem aItem) {
		AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) aItem.getMenuInfo();
		final Cursor c = (Cursor)lv.getItemAtPosition(menuInfo.position);
		Bookmark b = BookmarkManager.CursorToBookmark(c);
		
		switch (aItem.getItemId()) {
			case R.id.menu_bookmark_context_open:
				openBookmarkInBrowser(b);
				return true;
			case R.id.menu_bookmark_context_view:				
				viewBookmark(b);
				return true;
			case R.id.menu_bookmark_context_edit:
				bookmarkSelectedListener.onBookmarkEdit(b);
				return true;
			case R.id.menu_bookmark_context_delete:
				bookmarkSelectedListener.onBookmarkDelete(b);
				return true;
			case R.id.menu_bookmark_context_share:
				Log.d("share", "browse");
				bookmarkSelectedListener.onBookmarkShare(b);
				return true;
			case R.id.menu_bookmark_context_read:
				readBookmark(b);
				return true;
		}
		return false;
	}
	
	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		super.onCreateOptionsMenu(menu, inflater);
		inflater.inflate(R.menu.browse_bookmark_menu, menu);
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		boolean result = false;
		
	    switch (item.getItemId()) {
		    case R.id.menu_bookmark_sort_date_asc:
		    	sortfield = Bookmark.Time + " ASC";
				result = true;
				break;
		    case R.id.menu_bookmark_sort_date_desc:			
		    	sortfield = Bookmark.Time + " DESC";
		    	result = true;
		    	break;
		    case R.id.menu_bookmark_sort_description_asc:			
		    	sortfield = Bookmark.Description + " ASC";
		    	result = true;
		    	break;
		    case R.id.menu_bookmark_sort_description_desc:			
		    	sortfield = Bookmark.Description + " DESC";
		    	result = true;
		    	break;
		    case R.id.menu_bookmark_sort_url_asc:			
		    	sortfield = Bookmark.Url + " ASC";
		    	result = true;
		    	break;
		    case R.id.menu_bookmark_sort_url_desc:			
		    	sortfield = Bookmark.Url + " DESC";
		    	result = true;
		    	break;
	    }
	    
	    if(result) {
	    	getLoaderManager().restartLoader(0, null, this);
	    } else result = super.onOptionsItemSelected(item);
	    
	    return result;
	}
	
	private void openBookmarkInBrowser(Bookmark b) {
		bookmarkSelectedListener.onBookmarkOpen(b);
	}
	
	private void readBookmark(Bookmark b){
		bookmarkSelectedListener.onBookmarkRead(b);
	}
	
	private void viewBookmark(Bookmark b) {
		bookmarkSelectedListener.onBookmarkView(b);
	}
    
	public Loader<Cursor> onCreateLoader(int id, Bundle args) {

		if(query != null) {    		
			return BookmarkManager.SearchBookmarks(query, tagname, username, base);
		} else {
			return BookmarkManager.GetBookmarks(username, tagname, sortfield, base);
		}
	}
	
	public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
	    mAdapter.swapCursor(data);
	}
	
	public void onLoaderReset(Loader<Cursor> loader) {
	    mAdapter.swapCursor(null);
	}
	
	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		try {
			bookmarkSelectedListener = (OnBookmarkSelectedListener) activity;
		} catch (ClassCastException e) {
			throw new ClassCastException(activity.toString() + " must implement OnBookmarkSelectedListener");
		}
	}
} public class BrowseTagsFragment extends ListFragment
	implements LoaderManager.LoaderCallbacks<Cursor> {

	private String sortfield = Tag.Name + " ASC";
	private SimpleCursorAdapter mAdapter;
	
	private String username = null;
	private String query = null;
	
	private OnTagSelectedListener tagSelectedListener;
	private OnItemClickListener clickListener;
	
	public interface OnTagSelectedListener {
		public void onTagSelected(String tag);
	}
	
	@Override
	public void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		clickListener = viewListener;
	}
	
	@Override
	public void onActivityCreated(Bundle savedInstanceState){
		super.onActivityCreated(savedInstanceState);

		setHasOptionsMenu(true);
		
		mAdapter = new SimpleCursorAdapter(this.getActivity(), 
				R.layout.tag_view, null, 
				new String[] {Tag.Name, Tag.Count}, new int[] {R.id.tag_name, R.id.tag_count}, 0);
		
		setListAdapter(mAdapter);	
		
		getLoaderManager().initLoader(0, null, this);
		
		ListView lv = getListView();
		lv.setTextFilterEnabled(true);
		lv.setFastScrollEnabled(true);
		lv.setOnItemClickListener(clickListener);

		lv.setItemsCanFocus(false);
		lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
	}
	
	public void setAccount(String account) {
		this.username = account;
	}
	
	public void setQuery(String query) {
		this.query = query;
	}
	
	private OnItemClickListener viewListener = new OnItemClickListener() {
	    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
	    	String tagName = ((TextView)view.findViewById(R.id.tag_name)).getText().toString();
	    	
	    	tagSelectedListener.onTagSelected(tagName);
	    }
	};
	
	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		super.onCreateOptionsMenu(menu, inflater);
		inflater.inflate(R.menu.browse_tag_menu, menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
	
		boolean result = false;

	    switch (item.getItemId()) {
		    case R.id.menu_tag_sort_name_asc:
		    	sortfield = Tag.Name + " ASC";
				result = true;
				break;
		    case R.id.menu_tag_sort_name_desc:			
		    	sortfield = Tag.Name + " DESC";
		    	result = true;
		    	break;
		    case R.id.menu_tag_sort_count_asc:			
		    	sortfield = Tag.Count + " ASC";
		    	result = true;
		    	break;
		    case R.id.menu_tag_sort_count_desc:			
		    	sortfield = Tag.Count + " DESC";
		    	result = true;
		    	break;
	    }
	    
	    if(result) {
	    	getLoaderManager().restartLoader(0, null, this);
	    } else result = super.onOptionsItemSelected(item);
	    
	    return result;
	}
	
	public Loader<Cursor> onCreateLoader(int id, Bundle args) {
		if(username != null && !username.equals("")) {
			if(query != null) {
				return TagManager.SearchTags(query, username, this.getActivity());
			} else {
				return TagManager.GetTags(username, sortfield, this.getActivity());
			}
		}
		else return null;
	}
	
	public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
	    mAdapter.swapCursor(data);
	}
	
	public void onLoaderReset(Loader<Cursor> loader) {
	    mAdapter.swapCursor(null);
	}
	
	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		try {
			tagSelectedListener = (OnTagSelectedListener) activity;
		} catch (ClassCastException e) {
			throw new ClassCastException(activity.toString() + " must implement OnTagSelectedListener");
		}
	}
} public class ViewBookmarkFragment extends Fragment {

	private FragmentBaseActivity base;
	
	private View container;
	private ScrollView mBookmarkView;
	private TextView mTitle;
	private TextView mUrl;
	private TextView mNotes;
	private TextView mTags;
	private TextView mTime;
	private TextView mUsername;
	private ImageView mIcon;
	private WebView mWebContent;
	private Bookmark bookmark;
	private BookmarkViewType viewType;
	private View readSection;
	private TextView readTitle;
	private TextView readView;
	
	private OnBookmarkActionListener bookmarkActionListener;
	private OnBookmarkSelectedListener bookmarkSelectedListener;
	
	private static final String STATE_VIEWTYPE = "viewType";
	
	public interface OnBookmarkActionListener {
		public void onViewTagSelected(String tag);
		public void onUserTagSelected(String tag, String user);
		public void onAccountSelected(String account);
	}
	
	@Override
	public void onActivityCreated(Bundle savedInstanceState){
		super.onActivityCreated(savedInstanceState);
		
	    if (savedInstanceState != null) {
	        viewType = (BookmarkViewType)savedInstanceState.getSerializable(STATE_VIEWTYPE);
	    } 
		
		base = (FragmentBaseActivity)getActivity();
		
		container = (View) getView().findViewById(R.id.view_bookmark_container);
		mBookmarkView = (ScrollView) getView().findViewById(R.id.bookmark_scroll_view);
		mTitle = (TextView) getView().findViewById(R.id.view_bookmark_title);
		mUrl = (TextView) getView().findViewById(R.id.view_bookmark_url);
		mNotes = (TextView) getView().findViewById(R.id.view_bookmark_notes);
		mTags = (TextView) getView().findViewById(R.id.view_bookmark_tags);
		mTime = (TextView) getView().findViewById(R.id.view_bookmark_time);
		mUsername = (TextView) getView().findViewById(R.id.view_bookmark_account);
		mIcon = (ImageView) getView().findViewById(R.id.view_bookmark_icon);
		mWebContent = (WebView) getView().findViewById(R.id.web_view);
		readSection = getView().findViewById(R.id.read_bookmark_section);
		readTitle = (TextView) getView().findViewById(R.id.read_bookmark_title);
		readView = (TextView) getView().findViewById(R.id.read_view);
		
		mWebContent.getSettings().setJavaScriptEnabled(true);
		readView.setMovementMethod(LinkMovementMethod.getInstance());
		
		setHasOptionsMenu(true);
		//setRetainInstance(true);
	}
	
    TagSpan.OnTagClickListener tagOnClickListener = new TagSpan.OnTagClickListener() {
        public void onTagClick(String tag) {
    		bookmarkActionListener.onViewTagSelected(tag);
        }
    };
    
    TagSpan.OnTagClickListener userTagOnClickListener = new TagSpan.OnTagClickListener() {
        public void onTagClick(String tag) {
        	bookmarkActionListener.onUserTagSelected(tag, bookmark.getAccount());
        }
    };
    
    AccountSpan.OnAccountClickListener accountOnClickListener = new AccountSpan.OnAccountClickListener() {
        public void onAccountClick(String account) {
        	bookmarkActionListener.onAccountSelected(account);
        }
    };
    
	public void setBookmark(Bookmark b, BookmarkViewType viewType) {
		this.viewType = viewType;
		bookmark = b;
		
		ActivityCompat.invalidateOptionsMenu(this.getActivity());
	}
	
	private void addTag(SpannableStringBuilder builder, Tag t, TagSpan.OnTagClickListener listener) {
		int flags = 0;
		
		if (builder.length() != 0) {
			builder.append("  ");
		}
		
		int start = builder.length();
		builder.append(t.getTagName());
		int end = builder.length();
		
		TagSpan span = new TagSpan(t.getTagName());
		span.setOnTagClickListener(listener);

		builder.setSpan(span, start, end, flags);
	}
	
	@Override
	public void onSaveInstanceState(Bundle savedInstanceState) {
	    savedInstanceState.putSerializable(STATE_VIEWTYPE, viewType);
	    
	    super.onSaveInstanceState(savedInstanceState);
	}
    
	@Override
	@TargetApi(14)
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		super.onCreateOptionsMenu(menu, inflater);
	    inflater.inflate(R.menu.view_menu, menu);
	    
	    if(android.os.Build.VERSION.SDK_INT >= 14) {
	    	Log.d("bookmark", Boolean.toString(bookmark == null));
	    	if(bookmark != null){
	    		if(isMyself() && bookmark.getId() != 0){
					try{		
						int id = bookmark.getId();
						bookmark = BookmarkManager.GetById(id, base);
						
			    		ShareActionProvider shareActionProvider = (ShareActionProvider) menu.findItem(R.id.menu_view_sendbookmark).getActionProvider();
			    		shareActionProvider.setShareIntent(IntentHelper.SendBookmark(bookmark.getUrl(), bookmark.getDescription()));
					}
					catch(ContentNotFoundException e){}
	    		}
	    	}
	    }
	}
	
	@Override
	public void onPrepareOptionsMenu(Menu menu) {
		if(bookmark != null){
			if(!isMyself()){
				menu.removeItem(R.id.menu_view_editbookmark);
				menu.removeItem(R.id.menu_view_deletebookmark);
			} else {
				menu.removeItem(R.id.menu_addbookmark);
			}
		} else {
			menu.removeItem(R.id.menu_view);
			menu.removeItem(R.id.menu_view_sendbookmark);
			menu.removeItem(R.id.menu_view_editbookmark);
			menu.removeItem(R.id.menu_view_deletebookmark);
		}
	}
	
	@Override
	@TargetApi(14)
	public boolean onOptionsItemSelected(MenuItem item) {
	    // Handle item selection
	    switch (item.getItemId()) {
		    case R.id.menu_view_details:
		    	bookmarkSelectedListener.onBookmarkView(bookmark);
				return true;
		    case R.id.menu_view_read:
				bookmarkSelectedListener.onBookmarkRead(bookmark);
				return true;
		    case R.id.menu_view_openbookmark:
		    	bookmarkSelectedListener.onBookmarkOpen(bookmark);
				return true;
		    case R.id.menu_view_editbookmark:
		    	bookmarkSelectedListener.onBookmarkEdit(bookmark);
		    	return true;
		    case R.id.menu_view_deletebookmark:
		    	bookmarkSelectedListener.onBookmarkDelete(bookmark);
				return true;
		    case R.id.menu_view_sendbookmark:
		    	if(android.os.Build.VERSION.SDK_INT < 14 || item.getActionProvider() == null || !(item.getActionProvider() instanceof ShareActionProvider)) {
		    		bookmarkSelectedListener.onBookmarkShare(bookmark);
		    	}
		    	return true;
		    default:
		        return super.onOptionsItemSelected(item);
	    }
	}
	
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.view_bookmark_fragment, container, false);
    }
    
    private boolean isMyself() {
    	return bookmark != null && bookmark.getId() != 0;
    }
    
    @Override
    public void onStart(){
    	super.onStart();
    	
    	loadBookmark();
    }

    public void loadBookmark(){
    	if(bookmark != null){
    		
    		if(isMyself() && bookmark.getId() != 0){
				try{		
					int id = bookmark.getId();
					bookmark = BookmarkManager.GetById(id, base);
				}
				catch(ContentNotFoundException e){}
    		}
    		
    		if(viewType == BookmarkViewType.VIEW){
				mBookmarkView.setVisibility(View.VISIBLE);
				readSection.setVisibility(View.GONE);
				mWebContent.setVisibility(View.GONE);
				if(isMyself()){
					Date d = new Date(bookmark.getTime());
					
					mTitle.setText(bookmark.getDescription());
					mUrl.setText(bookmark.getUrl());
					mNotes.setText(bookmark.getNotes());
					mTime.setText(d.toString());
					mUsername.setText(bookmark.getAccount());
					
					if(mIcon != null){
						if(!bookmark.getShared()) {
							mIcon.setImageResource(R.drawable.padlock);
						}
					}
					
	        		SpannableStringBuilder tagBuilder = new SpannableStringBuilder();
	
	        		for(Tag t : bookmark.getTags()) {
	        			addTag(tagBuilder, t, tagOnClickListener);
	        		}
	        		
	        		mTags.setText(tagBuilder);
	        		mTags.setMovementMethod(LinkMovementMethod.getInstance());
				} else {
					
					Date d = new Date(bookmark.getTime());
					
					if(bookmark.getDescription() != null && !bookmark.getDescription().equals("null"))
						mTitle.setText(bookmark.getDescription());
					
					mUrl.setText(bookmark.getUrl());
					
					if(bookmark.getNotes() != null && !bookmark.getNotes().equals("null"))
						mNotes.setText(bookmark.getNotes());
					
					mTime.setText(d.toString());
					
		    		SpannableStringBuilder tagBuilder = new SpannableStringBuilder();
		
		    		for(Tag t : bookmark.getTags()) {
		    			addTag(tagBuilder, t, userTagOnClickListener);
		    		}
		    		
		    		mTags.setText(tagBuilder);
		    		mTags.setMovementMethod(LinkMovementMethod.getInstance());
		
		    		if(bookmark.getAccount() != null){
						SpannableStringBuilder builder = new SpannableStringBuilder();
						int start = builder.length();
						builder.append(bookmark.getAccount());
						int end = builder.length();
						
						AccountSpan span = new AccountSpan(bookmark.getAccount());
						span.setOnAccountClickListener(accountOnClickListener);
			
						builder.setSpan(span, start, end, 0);
						
						mUsername.setText(builder);
		    		}
					
					
					mUsername.setMovementMethod(LinkMovementMethod.getInstance());
				}
			} else if(viewType == BookmarkViewType.READ){
				new GetArticleTask().execute(bookmark.getUrl());
			} else if(viewType == BookmarkViewType.WEB){
				showInWebView();
			}
    	}
    }
    
    private void showInWebView(){
		mWebContent.clearView();
		mWebContent.clearCache(true);
		mBookmarkView.setVisibility(View.GONE);
		readSection.setVisibility(View.GONE);
		mWebContent.setVisibility(View.VISIBLE);				
		mWebContent.loadUrl(bookmark.getUrl());
    }
    
	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		try {
			bookmarkActionListener = (OnBookmarkActionListener) activity;
			bookmarkSelectedListener = (OnBookmarkSelectedListener) activity;
		} catch (ClassCastException e) {
			throw new ClassCastException(activity.toString() + " must implement OnBookmarkActionListener and OnBookmarkSelectedListener");
		}
	}
	
	@Override
	public void onResume(){
		super.onResume();
		readView.setBackgroundColor(Integer.parseInt(base.readingBackground));
		readTitle.setBackgroundColor(Integer.parseInt(base.readingBackground));
		
		if(Integer.parseInt(base.readingBackground) == Color.BLACK){
			readView.setTextColor(Color.parseColor("#999999"));
			readTitle.setTextColor(Color.parseColor("#999999"));
		}
		else { 
			readView.setTextColor(Color.parseColor("#222222"));
			readTitle.setTextColor(Color.parseColor("#222222"));
		}
		
		readView.setPadding(Integer.parseInt(base.readingMargins), 15, Integer.parseInt(base.readingMargins), 15);

		Typeface tf = Typeface.createFromAsset(base.getAssets(), "fonts/" + base.readingFont + ".ttf");
		readView.setTypeface(tf);
		
		readView.setTextSize(Float.parseFloat(base.readingFontSize));
		readView.setLineSpacing(Float.parseFloat(base.readingLineSpace), 1);
		
	}
	
    public class GetArticleTask extends AsyncTask<String, Integer, Article>{
    	private String url;

    	@Override
    	protected Article doInBackground(String... args) {
    		
    		if(args.length > 0 && args[0] != null && args[0] != "") {
    			url = args[0];
    	
        		Article a = NetworkUtilities.getArticleText(url);

        		if(a != null && a.getContent() != null){
	        		Spanned s = Html.fromHtml(a.getContent(), new Html.ImageGetter() {
	
	        			public Drawable getDrawable(String source) {                  
	        				Drawable d = null;
	        				try {
	        					InputStream src = imageFetch(source);
	        					d = Drawable.createFromStream(src, "src");
	        					if(d != null){
	        						int containerWidth = container.getWidth() - (Integer.parseInt(base.readingMargins) * 2);
	        						int width = Math.min(containerWidth, d.getIntrinsicWidth());
	        						
	        						int height = d.getIntrinsicHeight();
	        						
	        						if(containerWidth < d.getIntrinsicWidth()){
	        							double scale = ((double)containerWidth / (double)d.getIntrinsicWidth());	        							
	        							double newWidth = d.getIntrinsicHeight() * scale;
	        							height = (int)Math.floor(newWidth);
	        							
	        						}
	        						d.setBounds(0, 0, width, height);
	        					}
	        				} catch (MalformedURLException e) {
	        					e.printStackTrace(); 
	        				} catch (IOException e) {
	        					e.printStackTrace();  
	        				}
	        				return d;
	        			}
	        		}, null);
	
	        		a.setSpan(s);
        		}
        		return a;

    		} else return null;
    	}
    	
        protected void onPostExecute(Article result) {
        	if(result != null && result.getSpan() != null && !result.getContent().equals("") && !result.getContent().equals("null")){
	        	readSection.scrollTo(0, 0);
	        	mBookmarkView.setVisibility(View.GONE);
	        	mWebContent.setVisibility(View.GONE);
				readSection.setVisibility(View.VISIBLE);
				readTitle.setText(Html.fromHtml(result.getTitle()));
				readView.setText(result.getSpan());
        	} else {
        		showInWebView();
        	}
        }
        
        private InputStream imageFetch(String source) throws MalformedURLException,IOException {
	    	URL url = new URL(source);
	    	Object o = url.getContent();
	    	InputStream content = (InputStream)o;    
	    	return content;
	    }
    }
} public interface OnBookmarkSaveListener {
	public void onBookmarkSave(Bookmark b);
	public void onBookmarkCancel(Bookmark b);
} public interface OnBookmarkSelectedListener {
	public void onBookmarkView(Bookmark b);
	public void onBookmarkRead(Bookmark b);
	public void onBookmarkOpen(Bookmark b);
	public void onBookmarkAdd(Bookmark b);
	public void onBookmarkShare(Bookmark b);
	public void onBookmarkEdit(Bookmark b);
	public void onBookmarkDelete(Bookmark b);
} public interface OnTagSelectedListener {
	public void onTagSelected(String tag);
} public interface OnBookmarkActionListener {
	public void onViewTagSelected(String tag);
	public void onUserTagSelected(String tag, String user);
	public void onAccountSelected(String account);
} public class Constants {

    /**
     * Account type string.
     */
    public static final String ACCOUNT_TYPE = "com.deliciousdroid";
    
    public static final Uri CONTENT_URI_BASE = Uri.parse("content://com.deliciousdroid");
    
    public static final String CONTENT_SCHEME = "content";
    
    public static final String EXTRA_DESCRIPTION = "com.deliciousdroid.bookmark.description";
    public static final String EXTRA_NOTES = "com.deliciousdroid.bookmark.notes";
    public static final String EXTRA_TAGS = "com.deliciousdroid.bookmark.tags";
    public static final String EXTRA_PRIVATE = "com.deliciousdroid.bookmark.private";
    public static final String EXTRA_ERROR = "com.deliciousdroid.bookmark.error";
    public static final String EXTRA_TIME = "com.deliciousdroid.bookmark.time";
	public static final String EXTRA_UPDATE = "com.deliciousdroid.bookmark.update";
	
	public static final String TEXT_EXTRACTOR_URL = "http://viewtext.org/api/text?url=";
	
	public static final String SYNC_MARKER_KEY = "com.deliciousdroid.BookmarkSyncAdapter.marker";
	
	public static final int BOOKMARK_PAGE_SIZE = 500;
	
	public static final String ACTION_SEARCH_SUGGESTION = "com.deliciousdroid.intent.action.SearchSuggestion";
	
	public static final String SUGGEST_COLUMN_TEXT_2_URL = "suggest_text_2_url";

    /**
     * Authtoken type string.
     */
    public static final String AUTHTOKEN_TYPE = "com.deliciousdroid";
    
    public static final String AUTH_PREFS_NAME = "com.deliciousdroid.auth";
    
    public static final String PREFS_AUTH_TYPE = "authentication_type";
    public static final String AUTH_TYPE_DELICIOUS = "delicious";
    
    public static final String GPL_URL = "http://www.gnu.org/licenses/gpl-3.0.txt";
    public static final String MANUAL_URL = "http://code.google.com/p/deliciousdroid/wiki/Manual";
    public static final String DONATION_URL = "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6ERJRC6SWL9ZC";
    
    public static enum BookmarkViewType {VIEW, READ, WEB};
} public static enum BookmarkViewType {VIEW, READ, WEB}; public class IntentHelper {

	public static Intent OpenInBrowser(String url){
    	Uri link = Uri.parse(url);
		return new Intent(Intent.ACTION_VIEW, link);
	}
	
	public static Intent ReadBookmark(String url){
    	String readUrl = "";
		try {
			readUrl = Constants.TEXT_EXTRACTOR_URL + URLEncoder.encode(url, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
    	Uri readLink = Uri.parse(readUrl);
		return new Intent(Intent.ACTION_VIEW, readLink);
	}
	
	public static Intent SendBookmark(String url, String title) {
    	Intent sendIntent = new Intent(Intent.ACTION_SEND);
    	sendIntent.setType("text/plain");
    	sendIntent.putExtra(Intent.EXTRA_TEXT, url);
    	sendIntent.putExtra(Intent.EXTRA_SUBJECT, title);
    	sendIntent.putExtra(Intent.EXTRA_TITLE, title);
    	
    	return sendIntent;
	}
	
	public static Intent AddBookmark(String url, String account, Context context) {
		Intent addBookmark = new Intent(context, AddBookmark.class);
		addBookmark.setAction(Intent.ACTION_SEND);
		if(url != null)
			addBookmark.putExtra(Intent.EXTRA_TEXT, url);
		
		Uri.Builder data = new Uri.Builder();
		data.scheme(Constants.CONTENT_SCHEME);
		data.encodedAuthority(account + "@" + BookmarkContentProvider.AUTHORITY);
		data.appendEncodedPath("bookmarks");
		addBookmark.setData(data.build());
		
		return addBookmark;
	}
	
	public static Intent ViewBookmark(Bookmark b, BookmarkViewType type, String account, Context context) {
		Intent viewBookmark = new Intent(context, ViewBookmark.class);
		viewBookmark.setAction(Intent.ACTION_VIEW);
		viewBookmark.addCategory(Intent.CATEGORY_DEFAULT);
		viewBookmark.putExtra("com.deliciousdroid.BookmarkViewType", type);
		Uri.Builder data = new Uri.Builder();
		data.scheme(Constants.CONTENT_SCHEME);
		data.encodedAuthority(account + "@" + BookmarkContentProvider.AUTHORITY);
		data.appendEncodedPath("bookmarks");
		
		if(b.getId() != 0) {
			data.appendEncodedPath(Integer.toString(b.getId()));
		} else {
			data.appendEncodedPath(Integer.toString(0));
			data.appendQueryParameter("url", b.getUrl());
			data.appendQueryParameter("title", b.getDescription());
			data.appendQueryParameter("notes", b.getNotes());
			data.appendQueryParameter("tags", b.getTagString());
			data.appendQueryParameter("time", Long.toString(b.getTime()));
			data.appendQueryParameter("account", b.getAccount());
		}
		viewBookmark.setData(data.build());
		
		return viewBookmark;
	}
	
	public static Intent EditBookmark(Bookmark b, String account, Context context) {
		Intent editBookmark = new Intent(context, AddBookmark.class);
		editBookmark.setAction(Intent.ACTION_EDIT);
		Uri.Builder data = new Uri.Builder();
		data.scheme(Constants.CONTENT_SCHEME);
		data.encodedAuthority(account + "@" + BookmarkContentProvider.AUTHORITY);
		data.appendEncodedPath("bookmarks");
		data.appendEncodedPath(Integer.toString(b.getId()));
		editBookmark.setData(data.build());
		
		return editBookmark;
	}
	
	public static Intent ViewBookmarks(String tag, String account, Context context) {
		Intent i = new Intent(context, BrowseBookmarks.class);
		i.setAction(Intent.ACTION_VIEW);
		i.addCategory(Intent.CATEGORY_DEFAULT);
		Uri.Builder data = new Uri.Builder();
		data.scheme(Constants.CONTENT_SCHEME);
		data.encodedAuthority(account + "@" + BookmarkContentProvider.AUTHORITY);
		data.appendEncodedPath("bookmarks");
		
		if(tag != null && !tag.equals(""))
			data.appendQueryParameter("tagname", tag);
		
		i.setData(data.build());
		
		return i;
	}
	
	public static Intent ViewBundles(String account, Context context) {
		Intent i = new Intent(context, BrowseBundles.class);
		i.setAction(Intent.ACTION_VIEW);
		i.addCategory(Intent.CATEGORY_DEFAULT);
		Uri.Builder data = new Uri.Builder();
		data.scheme(Constants.CONTENT_SCHEME);
		data.encodedAuthority(account + "@" + BookmarkContentProvider.AUTHORITY);
		data.appendEncodedPath("bundles");
		i.setData(data.build());
		
		return i;
	}
	
	public static Intent ViewTags(String account, Context context) {
		Intent i = new Intent(context, BrowseTags.class);
		i.setAction(Intent.ACTION_VIEW);
		i.addCategory(Intent.CATEGORY_DEFAULT);
		Uri.Builder data = new Uri.Builder();
		data.scheme(Constants.CONTENT_SCHEME);
		data.encodedAuthority(account + "@" + BookmarkContentProvider.AUTHORITY);
		data.appendEncodedPath("tags");
		i.setData(data.build());
		
		return i;
	}
	
	public static Intent ViewTabletTags(String account, Context context) {
		Intent i = new Intent(context, BrowseBookmarks.class);
		i.setAction(Intent.ACTION_VIEW);
		i.addCategory(Intent.CATEGORY_DEFAULT);
		Uri.Builder data = new Uri.Builder();
		data.scheme(Constants.CONTENT_SCHEME);
		data.encodedAuthority(account + "@" + BookmarkContentProvider.AUTHORITY);
		data.appendEncodedPath("tags");
		i.setData(data.build());
		
		return i;
	}
	
	public static Intent SearchBookmarks(String query, String account, Context context) {
		Intent i = new Intent(context, BrowseBookmarks.class);
		i.setAction(Intent.ACTION_SEARCH);
		i.putExtra(SearchManager.QUERY, query);
		i.putExtra("MainSearchResults", "1");
		return i;
	}
	
	public static Intent SearchTags(String query, String account, Context context) {
		Intent i = new Intent(context, BrowseTags.class);
		i.setAction(Intent.ACTION_SEARCH);
		i.putExtra(SearchManager.QUERY, query);
		i.putExtra("MainSearchResults", "1");
		return i;
	}
	
	public static Intent SearchGlobalTags(String query, String account, Context context) {
		Intent i = new Intent(context, BrowseBookmarks.class);
		i.setAction(Intent.ACTION_SEARCH);
		i.putExtra(SearchManager.QUERY, query);
		i.putExtra("MainSearchResults", "1");
		
		Uri.Builder data = new Uri.Builder();
		data.scheme(Constants.CONTENT_SCHEME);
		data.encodedAuthority("global" + "@" + BookmarkContentProvider.AUTHORITY);
		data.appendEncodedPath("bookmarks");
		i.setData(data.build());
		
		return i;
	}
} public class BookmarkManager {
	
	public static CursorLoader GetBookmarks(String username, String tagname, String sortorder, Context context){
		final String[] projection = new String[] {Bookmark._ID, Bookmark.Url, Bookmark.Description, 
				Bookmark.Meta, Bookmark.Tags, Bookmark.Shared, Bookmark.Synced, Bookmark.Deleted};
		String selection = null;
		ArrayList<String> selectionList = new ArrayList<String>();
		final ArrayList<String> queryList = new ArrayList<String>();


		if(tagname != null && tagname != "") {
			String[] tagList = tagname.split(",");

			for(String s : tagList) {
				queryList.add("(" + Bookmark.Tags + " LIKE ? OR " +
					Bookmark.Tags + " LIKE ? OR " +
					Bookmark.Tags + " LIKE ? OR " +
					Bookmark.Tags + " = ?)");

				selectionList.add("% " + s + " %");
				selectionList.add("% " + s);
				selectionList.add(s + " %");
				selectionList.add(s);
			}
			selection = TextUtils.join(" OR ", queryList) + " AND " +
				Bookmark.Account + "=?";

			selectionList.add(username);
		} else {
			selectionList.add(username);
			selection = Bookmark.Account + "=?";
		}

		selection += " AND " + Bookmark.Deleted + "=0";
		
		return new CursorLoader(context, Bookmark.CONTENT_URI, projection, selection, selectionList.toArray(new String[]{}), sortorder);
	}
	
	public static ArrayList<Bookmark> GetLocalBookmarks(String username, Context context){
		ArrayList<Bookmark> bookmarkList = new ArrayList<Bookmark>();
		final String[] projection = new String[] {Bookmark._ID, Bookmark.Url, Bookmark.Description, Bookmark.Notes, Bookmark.Hash,
				Bookmark.Meta, Bookmark.Tags, Bookmark.Shared, Bookmark.Synced, Bookmark.Deleted};
		String selection = null;
		String[] selectionargs = new String[]{username};
		
		selectionargs = new String[]{username};
		selection = Bookmark.Account + "=? AND " + Bookmark.Synced + "=0 AND " + Bookmark.Deleted + "=0";
		
		Uri bookmarks = Bookmark.CONTENT_URI;

		Cursor c = context.getContentResolver().query(bookmarks, projection, selection, selectionargs, null);				

		if(c.moveToFirst()){
			int idColumn = c.getColumnIndex(Bookmark._ID);
			int urlColumn = c.getColumnIndex(Bookmark.Url);
			int descriptionColumn = c.getColumnIndex(Bookmark.Description);
			int tagsColumn = c.getColumnIndex(Bookmark.Tags);
			int metaColumn = c.getColumnIndex(Bookmark.Meta);
			int shareColumn = c.getColumnIndex(Bookmark.Shared);
			int notesColumn = c.getColumnIndex(Bookmark.Notes);
			int hashColumn = c.getColumnIndex(Bookmark.Hash);

			do {

				Bookmark b = new Bookmark(c.getInt(idColumn), "", c.getString(urlColumn), 
						c.getString(descriptionColumn), c.getString(notesColumn), c.getString(tagsColumn), c.getString(hashColumn), 
						c.getString(metaColumn), 0, c.getInt(shareColumn) == 0 ? false : true, false, false);

				bookmarkList.add(b);

			} while(c.moveToNext());

		}
		c.close();
		return bookmarkList;
	}
	
	public static ArrayList<Bookmark> GetDeletedBookmarks(String username, Context context){
		ArrayList<Bookmark> bookmarkList = new ArrayList<Bookmark>();
		final String[] projection = new String[] {Bookmark._ID, Bookmark.Url, Bookmark.Description, Bookmark.Notes, Bookmark.Hash,
				Bookmark.Meta, Bookmark.Tags, Bookmark.Shared, Bookmark.Synced, Bookmark.Deleted};
		String selection = null;
		String[] selectionargs = new String[]{username};
		
		selectionargs = new String[]{username};
		selection = Bookmark.Account + "=? AND " + Bookmark.Synced + "=0 AND " + Bookmark.Deleted + "=1";
		
		Uri bookmarks = Bookmark.CONTENT_URI;

		Cursor c = context.getContentResolver().query(bookmarks, projection, selection, selectionargs, null);				

		if(c.moveToFirst()){
			int idColumn = c.getColumnIndex(Bookmark._ID);
			int urlColumn = c.getColumnIndex(Bookmark.Url);
			int descriptionColumn = c.getColumnIndex(Bookmark.Description);
			int tagsColumn = c.getColumnIndex(Bookmark.Tags);
			int metaColumn = c.getColumnIndex(Bookmark.Meta);
			int shareColumn = c.getColumnIndex(Bookmark.Shared);
			int notesColumn = c.getColumnIndex(Bookmark.Notes);
			int hashColumn = c.getColumnIndex(Bookmark.Hash);

			do {

				Bookmark b = new Bookmark(c.getInt(idColumn), "", c.getString(urlColumn), 
						c.getString(descriptionColumn), c.getString(notesColumn), c.getString(tagsColumn), c.getString(hashColumn), 
						c.getString(metaColumn), 0, c.getInt(shareColumn) == 0 ? false : true, false, true);

				bookmarkList.add(b);

			} while(c.moveToNext());

		}
		c.close();
		return bookmarkList;
	}
	
	public static Bookmark GetById(int id, Context context) throws ContentNotFoundException {		
		final String[] projection = new String[] {Bookmark.Account, Bookmark.Url, Bookmark.Description, Bookmark.Notes, Bookmark.Time, Bookmark.Tags, Bookmark.Hash, Bookmark.Meta, Bookmark.Shared, Bookmark.Synced, Bookmark.Deleted};
		String selection = BaseColumns._ID + "=?";
		final String[] selectionargs = new String[]{Integer.toString(id)};
		selection += " AND " + Bookmark.Deleted + "=0";
		
		Cursor c = context.getContentResolver().query(Bookmark.CONTENT_URI, projection, selection, selectionargs, null);				
		
		if(c.moveToFirst()){
			final int accountColumn = c.getColumnIndex(Bookmark.Account);
			final int urlColumn = c.getColumnIndex(Bookmark.Url);
			final int descriptionColumn = c.getColumnIndex(Bookmark.Description);
			final int notesColumn = c.getColumnIndex(Bookmark.Notes);
			final int tagsColumn = c.getColumnIndex(Bookmark.Tags);
			final int hashColumn = c.getColumnIndex(Bookmark.Hash);
			final int metaColumn = c.getColumnIndex(Bookmark.Meta);
			final int timeColumn = c.getColumnIndex(Bookmark.Time);
			final int shareColumn = c.getColumnIndex(Bookmark.Shared);
			final int syncedColumn = c.getColumnIndex(Bookmark.Synced);
			final int deletedColumn = c.getColumnIndex(Bookmark.Deleted);
			
			final boolean share = c.getInt(shareColumn) == 0 ? false : true;
			final boolean synced = c.getInt(syncedColumn) == 0 ? false : true;
			final boolean deleted = c.getInt(deletedColumn) == 0 ? false : true;

			Bookmark b = new Bookmark(id, c.getString(accountColumn), c.getString(urlColumn), 
				c.getString(descriptionColumn), c.getString(notesColumn), c.getString(tagsColumn),
				c.getString(hashColumn), c.getString(metaColumn), c.getLong(timeColumn), share, synced, deleted);
			
			c.close();
			
			return b;
		} else {
			c.close();
			throw new ContentNotFoundException();
		}
	}
	
	public static Bookmark GetByUrl(String url, Context context) throws ContentNotFoundException {		
		final String[] projection = new String[] {Bookmark._ID, Bookmark.Account, Bookmark.Url, Bookmark.Description, Bookmark.Notes, Bookmark.Time, Bookmark.Tags, Bookmark.Hash, Bookmark.Meta, Bookmark.Shared, Bookmark.Synced, Bookmark.Deleted};
		String selection = Bookmark.Url + "=?";
		final String[] selectionargs = new String[]{ url };
		selection += " AND " + Bookmark.Deleted + "=0";
		
		Cursor c = context.getContentResolver().query(Bookmark.CONTENT_URI, projection, selection, selectionargs, null);				
		
		if(c.moveToFirst()){
			final int idColumn = c.getColumnIndex(Bookmark._ID);
			final int accountColumn = c.getColumnIndex(Bookmark.Account);
			final int urlColumn = c.getColumnIndex(Bookmark.Url);
			final int descriptionColumn = c.getColumnIndex(Bookmark.Description);
			final int notesColumn = c.getColumnIndex(Bookmark.Notes);
			final int tagsColumn = c.getColumnIndex(Bookmark.Tags);
			final int hashColumn = c.getColumnIndex(Bookmark.Hash);
			final int metaColumn = c.getColumnIndex(Bookmark.Meta);
			final int timeColumn = c.getColumnIndex(Bookmark.Time);
			final int shareColumn = c.getColumnIndex(Bookmark.Shared);
			final int syncedColumn = c.getColumnIndex(Bookmark.Synced);
			final int deletedColumn = c.getColumnIndex(Bookmark.Deleted);
			
			final boolean share = c.getInt(shareColumn) == 0 ? false : true;
			final boolean synced = c.getInt(syncedColumn) == 0 ? false : true;
			final boolean deleted = c.getInt(deletedColumn) == 0 ? false : true;

			Bookmark b = new Bookmark(c.getInt(idColumn), c.getString(accountColumn), c.getString(urlColumn), 
				c.getString(descriptionColumn), c.getString(notesColumn), c.getString(tagsColumn),
				c.getString(hashColumn), c.getString(metaColumn), c.getLong(timeColumn), share, synced, deleted);
			
			c.close();
			
			return b;
		} else {
			c.close();
			throw new ContentNotFoundException();
		}
	}
	
	public static void AddBookmark(Bookmark bookmark, String account, Context context) {
		final String url = bookmark.getUrl();
		
		String hash = "";
		if(bookmark.getHash() == null || bookmark.getHash() == ""){
			hash = Md5Hash.md5(url);
		} else hash = bookmark.getHash();
		
		final ContentValues values = new ContentValues();
		values.put(Bookmark.Description, bookmark.getDescription());
		values.put(Bookmark.Url, url);
		values.put(Bookmark.Notes, bookmark.getNotes());
		values.put(Bookmark.Tags, bookmark.getTagString());
		values.put(Bookmark.Hash, hash);
		values.put(Bookmark.Meta, bookmark.getMeta());
		values.put(Bookmark.Time, bookmark.getTime());
		values.put(Bookmark.Account, account);
		values.put(Bookmark.Shared, bookmark.getShared() ? 1 : 0);
		values.put(Bookmark.Synced, 0);
		values.put(Bookmark.Deleted, 0);
		
		context.getContentResolver().insert(Bookmark.CONTENT_URI, values);
	}
	
	public static void BulkInsert(ArrayList<Bookmark> list, String account, Context context) {
		int bookmarksize = list.size();
		ContentValues[] bcv = new ContentValues[bookmarksize];
		
		for(int i = 0; i < bookmarksize; i++){
			Bookmark b = list.get(i);
			
			ContentValues values = new ContentValues();
			values.put(Bookmark.Description, b.getDescription());
			values.put(Bookmark.Url, b.getUrl());
			values.put(Bookmark.Notes, b.getNotes());
			values.put(Bookmark.Tags, b.getTagString());
			values.put(Bookmark.Hash, b.getHash());
			values.put(Bookmark.Meta, b.getMeta());
			values.put(Bookmark.Time, b.getTime());
			values.put(Bookmark.Account, account);
			values.put(Bookmark.Shared, b.getShared() ? 1 : 0);
			values.put(Bookmark.Synced, true);
			values.put(Bookmark.Deleted, false);
			
			bcv[i] = values;
		}
		
		context.getContentResolver().bulkInsert(Bookmark.CONTENT_URI, bcv);
	}
	
	public static void UpdateBookmark(Bookmark bookmark, String account, Context context){
		final String url = bookmark.getUrl();
		
		String hash = "";
		if(bookmark.getHash() == null || bookmark.getHash() == ""){
			hash = Md5Hash.md5(url);
		} else hash = bookmark.getHash();
		
		final String selection = Bookmark.Hash + "=? AND " + Bookmark.Account + "=?";
		final String[] selectionargs = new String[]{hash, account};
		
		final ContentValues values = new ContentValues();
		values.put(Bookmark.Description, bookmark.getDescription());
		values.put(Bookmark.Url, url);
		values.put(Bookmark.Notes, bookmark.getNotes());
		values.put(Bookmark.Tags, bookmark.getTagString());
		values.put(Bookmark.Meta, bookmark.getMeta());
		
		if(bookmark.getTime() > 0)
			values.put(Bookmark.Time, bookmark.getTime());
		
		values.put(Bookmark.Shared, bookmark.getShared() ? 1 : 0);
		values.put(Bookmark.Synced, false);
		values.put(Bookmark.Deleted, false);
		
		context.getContentResolver().update(Bookmark.CONTENT_URI, values, selection, selectionargs);
	}
	
	public static void SetSynced(Bookmark bookmark, boolean synced, String account, Context context){
		final String url = bookmark.getUrl();
		
		String hash = "";
		if(bookmark.getHash() == null || bookmark.getHash() == ""){
			hash = Md5Hash.md5(url);
		} else hash = bookmark.getHash();
		
		final String selection = Bookmark.Hash + "=? AND " + Bookmark.Account + "=?";
		final String[] selectionargs = new String[]{hash, account};
		
		final ContentValues values = new ContentValues();
		values.put(Bookmark.Synced, synced);
		
		context.getContentResolver().update(Bookmark.CONTENT_URI, values, selection, selectionargs);
	}
	
	public static void LazyDelete(Bookmark bookmark, String account, Context context){
		final String url = bookmark.getUrl();
		
		String hash = "";
		if(bookmark.getHash() == null || bookmark.getHash() == ""){
			hash = Md5Hash.md5(url);
		} else hash = bookmark.getHash();
		
		final String selection = Bookmark.Hash + "=? AND " + Bookmark.Account + "=?";
		final String[] selectionargs = new String[]{hash, account};
		
		final ContentValues values = new ContentValues();
		values.put(Bookmark.Deleted, true);
		values.put(Bookmark.Synced, false);
		
		context.getContentResolver().update(Bookmark.CONTENT_URI, values, selection, selectionargs);
	}

	public static void DeleteBookmark(Bookmark bookmark, Context context){
		final int id = bookmark.getId();
		String selection = "";
		
		if(id > 0) {
			selection = BaseColumns._ID + "=" + id;
		} else {
			selection = Bookmark.Url + "='" + bookmark.getUrl() + "'";
		}
		
		context.getContentResolver().delete(Bookmark.CONTENT_URI, selection, null);
	}
	
	public static void TruncateBookmarks(ArrayList<String> accounts, Context context, boolean inverse){
		
		final ArrayList<String> selectionList = new ArrayList<String>();
		
		final String operator = inverse ? "<>" : "=";
		final String logicalOp = inverse ? " AND " : " OR ";
		
		for(String s : accounts) {
			selectionList.add(Bookmark.Account + " " + operator + " '" + s + "'");
		}
		
		String selection = TextUtils.join(logicalOp, selectionList);
		
		if(accounts.size() > 0)
			selection += " AND " + Bookmark.Synced + "=1";
		else selection += Bookmark.Synced + "=1";
		
		context.getContentResolver().delete(Bookmark.CONTENT_URI, selection, null);
	}
	
	public static CursorLoader SearchBookmarks(String query, String tagname, String username, Context context) {
		final String[] projection = new String[] {Bookmark._ID, Bookmark.Url, Bookmark.Description, 
				Bookmark.Meta, Bookmark.Tags, Bookmark.Shared, Bookmark.Synced, Bookmark.Deleted};
		String selection = null;
		
		final String sortorder = Bookmark.Description + " ASC";
		
		final String[] queryBookmarks = query.split(" ");
		
		final ArrayList<String> queryList = new ArrayList<String>();
		final ArrayList<String> selectionlist = new ArrayList<String>();
		
		if(query != null && query != "" && (tagname == null || tagname == "")) {
			
			
			for(String s : queryBookmarks) {
				queryList.add("(" + Bookmark.Tags + " LIKE ? OR " +
						Bookmark.Description + " LIKE ? OR " +
						Bookmark.Notes + " LIKE ?)");
				selectionlist.add("%" + s + "%");
				selectionlist.add("%" + s + "%");
				selectionlist.add("%" + s + "%");
			}
			selectionlist.add(username);
			
			selection = TextUtils.join(" AND ", queryList) + " AND " +
				Bookmark.Account + "=?";
		} else if(query != null && query != ""){
			for(String s : queryBookmarks) {
				queryList.add("(" + Bookmark.Description + " LIKE ? OR " +
						Bookmark.Notes + " LIKE ?)");
				
				selectionlist.add("%" + s + "%");
				selectionlist.add("%" + s + "%");
			}

			selection = TextUtils.join(" AND ", queryList) +
				" AND " + Bookmark.Account + "=? AND " +
				"(" + Bookmark.Tags + " LIKE ? OR " +
				Bookmark.Tags + " LIKE ? OR " +
				Bookmark.Tags + " LIKE ? OR " +
				Bookmark.Tags + " = ?)";
			
			selectionlist.add(username);
			selectionlist.add("% " + tagname + " %");
			selectionlist.add("% " + tagname);
			selectionlist.add(tagname + " %");
			selectionlist.add(tagname);
		} else {
			selectionlist.add(username);
			selection = Bookmark.Account + "=?";
		}
		
		selection += " AND " + Bookmark.Deleted + "=0";
		
		return new CursorLoader(context, Bookmark.CONTENT_URI, projection, selection, selectionlist.toArray(new String[]{}), sortorder);
	}

	
	public static Bookmark CursorToBookmark(Cursor c) {
		Bookmark b = new Bookmark();
		b.setId(c.getInt(c.getColumnIndex(Bookmark._ID)));
		b.setDescription(c.getString(c.getColumnIndex(Bookmark.Description)));
		b.setUrl(c.getString(c.getColumnIndex(Bookmark.Url)));
		b.setMeta(c.getString(c.getColumnIndex(Bookmark.Meta)));
		b.setTagString(c.getString(c.getColumnIndex(Bookmark.Tags)));
		
		if(c.getColumnIndex(Bookmark.Account) != -1)
			b.setAccount(c.getString(c.getColumnIndex(Bookmark.Account)));
		
		if(c.getColumnIndex(Bookmark.Notes) != -1)
			b.setNotes(c.getString(c.getColumnIndex(Bookmark.Notes)));
		
		if(c.getColumnIndex(Bookmark.Time) != -1)
			b.setTime(c.getLong(c.getColumnIndex(Bookmark.Time)));
		
		if(c.getColumnIndex(Bookmark.Shared) != -1)
			b.setShared(c.getInt(c.getColumnIndex(Bookmark.Shared)) == 1 ? true : false);
		
		if(c.getColumnIndex(Bookmark.Synced) != -1)
			b.setSynced(c.getInt(c.getColumnIndex(Bookmark.Synced)) == 1 ? true : false);
		
		if(c.getColumnIndex(Bookmark.Deleted) != -1)
			b.setDeleted(c.getInt(c.getColumnIndex(Bookmark.Deleted)) == 1 ? true : false);
		
		return b;
	}
} public static class Bookmark implements BaseColumns, Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 8170498291668576792L;

	public static final Uri CONTENT_URI = Uri.parse("content://" + BookmarkContentProvider.AUTHORITY + "/bookmark");
		
	public static final  String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.deliciousdroid.bookmarks";
		
	public static final String Account = "ACCOUNT";
	public static final String Description = "DESCRIPTION";
	public static final String Url = "URL";
	public static final String Notes = "NOTES";
	public static final String Tags = "TAGS";
	public static final String Hash = "HASH";
	public static final String Meta = "META";
	public static final String Time = "TIME";
	public static final String Shared = "SHARED";
	public static final String Synced = "SYNCED";
	public static final String Deleted = "DELETED";
		
	private int mId = 0;
	private String mAccount = null;
       private String mUrl = null;
       private String mDescription = null;
       private String mNotes = null;
       private String mTags = null;
       private String mHash = null;
       private String mMeta = null;
       private boolean mShared = true;
       private long mTime = 0;
       private boolean mSynced = false;
       private boolean mDeleted = false;

       public int getId(){
       	return mId;
       }
        
       public void setId(int id){
       	mId = id;
       }
        
       public String getUrl() {
           return mUrl;
       }
        
       public void setUrl(String url) {
       	mUrl = url;
       }

       public String getDescription() {
           return mDescription;
       }
        
       public void setDescription(String desc) {
       	mDescription = desc;
       }
        
       public String getNotes(){
       	return mNotes == null ? "" : mNotes;
       }
        
       public void setNotes(String notes) {
       	mNotes = notes;
       }
        
       public String getTagString(){
       	return mTags;
       }
        
       public void setTagString(String tags){
       	mTags = tags;
       }
        
       public ArrayList<Tag> getTags(){
		ArrayList<Tag> result = new ArrayList<Tag>();
			
		if(mTags != null){
			for(String s : mTags.split(" ")) {
				result.add(new Tag(s));
			}
		}
			
		return result;
       }
        
       public String getHash(){
       	return mHash;
       }
        
       public void setHash(String hash) {
       	mHash = hash;
       }

       public String getMeta(){
       	return mMeta;
       }
        
       public void setMeta(String meta) {
       	mMeta = meta;
       }
        
       public long getTime(){
       	return mTime;
       }
        
       public void setTime(long time) {
       	mTime = time;
       }
        
       public boolean getShared(){
       	return mShared;
       }
        
       public void setShared(boolean shared) {
       	mShared = shared;
       }
        
       public String getAccount(){
       	return mAccount;
       }
        
       public void setAccount(String account) {
       	mAccount = account;
       }
        
       public boolean getSynced(){
       	return mSynced;
       }
        
       public void setSynced(boolean synced){
       	mSynced = synced;
       }
        
       public boolean getDeleted(){
       	return mDeleted;
       }
        
       public void setDeleted(boolean deleted){
       	mDeleted = deleted;
       }
        
       public Bookmark() {
       }
        
       public Bookmark(int id) {
       	mId = id;
       }
        
       public Bookmark(String url) {
           mUrl = url;
       }
        
       public Bookmark(String url, String description, String notes, String tags, boolean priv, long time) {
           mUrl = url;
           mDescription = description;
           mNotes = notes;
           mTags = tags;
           mShared = priv;
           mTime = time;
       }
        
       public Bookmark(int id, String account, String url, String description, String notes, String tags, String hash, String meta, long time, boolean share, boolean synced, boolean deleted) {
           mId = id;
       	mUrl = url;
           mDescription = description;
           mNotes = notes;
           mTags = tags;
           mHash = hash;
           mMeta = meta;
           mTime = time;
           mAccount = account;
           mShared = share;
           mSynced = synced;
           mDeleted = deleted;
       }
        
       public Bookmark copy() {
       	Bookmark b = new Bookmark();
       	b.mAccount = this.mAccount;
       	b.mDescription = this.mDescription;
       	b.mHash = this.mHash;
       	b.mId = this.mId;
       	b.mMeta = this.mMeta;
       	b.mNotes = this.mNotes;
       	b.mShared = this.mShared;
       	b.mTags = this.mTags;
       	b.mTime = this.mTime;
       	b.mUrl = this.mUrl;
       	b.mSynced = this.mSynced;
       	b.mDeleted = this.mDeleted;
       	return b;
       }
        
       public void clear() {
       	this.mAccount = null;
       	this.mDescription = null;
       	this.mHash = null;
       	this.mId = 0;
       	this.mMeta = null;
       	this.mNotes = null;
       	this.mShared = true;
       	this.mTags = null;
       	this.mTime = 0;
       	this.mUrl = null;
       	this.mSynced = false;
       	this.mDeleted = false;
       }
}
import android.app.SearchManager;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import com.deliciousdroid.fragment.AddBookmarkFragment;
import com.deliciousdroid.fragment.BrowseBookmarkFeedFragment;
import com.deliciousdroid.fragment.BrowseBookmarksFragment;
import com.deliciousdroid.fragment.BrowseTagsFragment;
import com.deliciousdroid.fragment.ViewBookmarkFragment;
import com.deliciousdroid.fragment.AddBookmarkFragment.OnBookmarkSaveListener;
import com.deliciousdroid.fragment.BrowseBookmarksFragment.OnBookmarkSelectedListener;
import com.deliciousdroid.fragment.BrowseTagsFragment.OnTagSelectedListener;
import com.deliciousdroid.fragment.ViewBookmarkFragment.OnBookmarkActionListener;
import com.deliciousdroid.Constants;
import com.deliciousdroid.Constants.BookmarkViewType;
import com.deliciousdroid.R;
import com.deliciousdroid.action.IntentHelper;
import com.deliciousdroid.platform.BookmarkManager;
import com.deliciousdroid.providers.BookmarkContent.Bookmark;
			t.hide(addFrag);
		}

		t.commit();
    }
	
	@Override
	public boolean onSearchRequested() {
		if(isMyself()) {
			Bundle contextData = new Bundle();
			contextData.putString("tagname", tagname);
			contextData.putString("username", username);
			contextData.putBoolean("unread", unread);
			startSearch(null, false, contextData, false);
		} else {
			startSearch(null, false, Bundle.EMPTY, false);
		}
		return true;
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
	    MenuInflater inflater = getMenuInflater();
	    inflater.inflate(R.menu.main_menu, menu);
	    setupSearch(menu);
	    return true;
	}
	
	@Override
	public void onSaveInstanceState(Bundle savedInstanceState) {
		if(lastSelected != null && lastViewType != null){
			savedInstanceState.putSerializable(STATE_LASTBOOKMARK, lastSelected);
	    	savedInstanceState.putSerializable(STATE_LASTVIEWTYPE, lastViewType);
		}
		
		savedInstanceState.putString(STATE_USERNAME, username);
		savedInstanceState.putString(STATE_TAGNAME, tagname);
		savedInstanceState.putBoolean(STATE_UNREAD, unread);
		savedInstanceState.putString(STATE_QUERY, query);

	    super.onSaveInstanceState(savedInstanceState);
	}
	
	public void onRestoreInstanceState(Bundle savedInstanceState) {
	    super.onRestoreInstanceState(savedInstanceState);
	    
	    if(findViewById(R.id.maincontent) != null) {
	    	lastSelected = (Bookmark)savedInstanceState.getSerializable(STATE_LASTBOOKMARK);
	    	lastViewType = (BookmarkViewType)savedInstanceState.getSerializable(STATE_LASTVIEWTYPE);
	    	setBookmarkView(lastSelected, lastViewType);
	    }
	}
	
	@Override
	public void onBackPressed(){
		super.onBackPressed();
		
		Fragment tagFrag = getSupportFragmentManager().findFragmentById(R.id.tagcontent);
		View panelBtn = findViewById(R.id.panel_collapse_button);
		
		if(tagFrag != null && panelBtn != null){
			if(tagFrag.isVisible())
				findViewById(R.id.panel_collapse_button).setVisibility(View.GONE);
			else findViewById(R.id.panel_collapse_button).setVisibility(View.VISIBLE);
		}
	}

	public void onBookmarkView(Bookmark b) {
		if(b != null){
			if(findViewById(R.id.maincontent) != null || findViewById(R.id.tagcontent) != null) {
				lastSelected = b;
				lastViewType = BookmarkViewType.VIEW;
				setBookmarkView(b, BookmarkViewType.VIEW);
			} else {
				startActivity(IntentHelper.ViewBookmark(b, BookmarkViewType.VIEW, username, this));
			}
		}
	}

	public void onBookmarkRead(Bookmark b) {
		if(b != null){
			if(findViewById(R.id.maincontent) != null) {
				lastSelected = b;
				lastViewType = BookmarkViewType.READ;
				setBookmarkView(b, BookmarkViewType.READ);
			} else {
				startActivity(IntentHelper.ViewBookmark(b, BookmarkViewType.READ, username, this));
			}
		}
	}

	public void onBookmarkOpen(Bookmark b) {
		if(b != null){
			if(findViewById(R.id.maincontent) != null) {
				lastSelected = b;
				lastViewType = BookmarkViewType.WEB;
				setBookmarkView(b, BookmarkViewType.WEB);
			} else {
				startActivity(IntentHelper.OpenInBrowser(b.getUrl()));
			}
		}
	}

	public void onBookmarkAdd(Bookmark b) {
		if(b != null){
			startActivity(IntentHelper.AddBookmark(b.getUrl(), mAccount.name, this));
		}
	}

	public void onBookmarkShare(Bookmark b) {
		if(b != null){
			Intent sendIntent = IntentHelper.SendBookmark(b.getUrl(), b.getDescription());
			startActivity(Intent.createChooser(sendIntent, getString(R.string.share_chooser_title)));
		}
	}

	public void onBookmarkEdit(Bookmark b) {		
		if(b != null){
			if(findViewById(R.id.maincontent) != null) {
				AddBookmarkFragment addFrag = (AddBookmarkFragment) getSupportFragmentManager().findFragmentById(R.id.addcontent);