<|start_filename|>src/main/java/weiboclient4j/utils/StreamUtils.java<|end_filename|>
package weiboclient4j.utils;

import java.io.BufferedInputStream;
import java.io.Closeable;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * @author <NAME>
 */
public final class StreamUtils {
    private StreamUtils() {
    }

    public static void closeQuietly(Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (IOException e) {
                // ignore
            }
        }
    }

    public static StreamWriter newStreamWriter(DataOutputStream stream) {
        return new StreamWriter(stream);
    }

    public static class StreamWriter {
        private static final String CRLF = "\r\n";

        private DataOutputStream stream;

        public StreamWriter(DataOutputStream stream) {
            this.stream = stream;
        }

        public StreamWriter writeLine(String content) throws IOException {
            stream.writeBytes(content + CRLF);

            return this;
        }

        public StreamWriter writeLine(byte[] content) throws IOException {
            if (content != null) {
                stream.write(content);
            }

            stream.writeBytes(CRLF);

            return this;
        }

        public StreamWriter writeLine() throws IOException {
            return writeLine("");
        }

        public StreamWriter writeFile(File file) throws IOException {
            BufferedInputStream in = null;
            FileInputStream fileInputStream = null;

            try {
                fileInputStream = new FileInputStream(file);
                in = new BufferedInputStream(fileInputStream);
                int buff;
                while ((buff = in.read()) != -1) {
                    stream.write(buff);
                }

                stream.writeBytes(CRLF);
            } finally {
                closeQuietly(fileInputStream);
                closeQuietly(in);
            }

            return this;
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/IsPic.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public enum IsPic implements ParameterAction {
    All(0), Pic(1);

    private int value;

    IsPic(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void addParameter(Parameters params) {
        params.add("is_pic", getValue());
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/IdResponse.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class IdResponse {
    private long id;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Names.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.LocationService;
import static weiboclient4j.utils.StringUtils.join;

public class Names extends StringParam implements
        LocationService.GetMapImageParam {

    public Names(String... value) {
        super(join(value, ","));
    }

    protected String paramKey() {
        return "names";
    }
}


<|start_filename|>src/main/java/weiboclient4j/PlaceService.java<|end_filename|>
package weiboclient4j;

import org.scribe.model.OAuthRequest;
import weiboclient4j.model.CreatePoiResponse;
import weiboclient4j.model.Poi;
import weiboclient4j.model.PoiCategory;
import weiboclient4j.model.PoiList;
import weiboclient4j.model.Status;
import weiboclient4j.model.StatusList;
import weiboclient4j.model.Timeline;
import weiboclient4j.model.UserLBS;
import weiboclient4j.model.UserList;
import weiboclient4j.params.BaseApp;
import weiboclient4j.params.Category;
import weiboclient4j.params.City;
import weiboclient4j.params.Id;
import weiboclient4j.params.IsPublic;
import weiboclient4j.params.Keyword;
import weiboclient4j.params.Latitude;
import weiboclient4j.params.Longitude;
import weiboclient4j.params.Paging;
import weiboclient4j.params.ParameterAction;
import weiboclient4j.params.Parameters;
import weiboclient4j.params.PoiId;
import weiboclient4j.params.StatusParam;
import weiboclient4j.params.Title;
import weiboclient4j.params.Uid;

import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * @author <NAME>
 */
@SuppressWarnings("unchecked")
public class PlaceService extends AbstractService {

    private static final String PIC_PARAM_NAME = "pic";

    public PlaceService(WeiboClient client) {
        super(client);
    }

    public static interface GetPublishTimelineParam extends ParameterAction {
    }

    public Timeline getPublishTimeline() throws WeiboClientException {
        return getPublishTimeline(Paging.EMPTY);
    }

    public <T extends GetPublishTimelineParam> Timeline getPublishTimeline(T... optionalParams)
            throws WeiboClientException {
        return doGet("place/public_timeline", Paging.EMPTY, buildParams(optionalParams), Timeline.class);
    }

    public <T extends GetPublishTimelineParam> Timeline getPublishTimeline(
            Paging paging, T... optionalParams) throws WeiboClientException {
        return doGet("place/public_timeline", paging, buildParams(optionalParams), Timeline.class);
    }

    public static interface GetFriendsTimelineParam extends ParameterAction {
    }

    public Timeline getFriendsTimeline() throws WeiboClientException {
        return getFriendsTimeline(Paging.EMPTY);
    }

    public <T extends GetFriendsTimelineParam> Timeline getFriendsTimeline(T... optionalParams)
            throws WeiboClientException {
        return doGet("place/friends_timeline", Paging.EMPTY, buildParams(optionalParams), Timeline.class);
    }

    public <T extends GetFriendsTimelineParam> Timeline getFriendsTimeline(
            Paging paging, T... optionalParams) throws WeiboClientException {
        return doGet("place/friends_timeline", paging, buildParams(optionalParams), Timeline.class);
    }

    public static interface GetUserTimelineParam extends ParameterAction {
    }

    public Timeline getUserTimeline(Uid uid) throws WeiboClientException {
        return getUserTimeline(uid, Paging.EMPTY);
    }

    public <T extends GetUserTimelineParam> Timeline getUserTimeline(Uid uid, T... optionalParams)
            throws WeiboClientException {
        return doGet("place/user_timeline", Paging.EMPTY, buildParams(optionalParams, uid), Timeline.class);
    }

    public <T extends GetUserTimelineParam> Timeline getUserTimeline(
            Uid uid, Paging paging, T... optionalParams) throws WeiboClientException {
        return doGet("place/user_timeline", paging, buildParams(optionalParams, uid), Timeline.class);
    }

    public static interface GetPoiTimelineParam extends ParameterAction {
    }

    public Timeline getPoiTimeline(PoiId poiId) throws WeiboClientException {
        return getPoiTimeline(poiId, Paging.EMPTY);
    }

    public <T extends GetPoiTimelineParam> Timeline getPoiTimeline(PoiId poiId, T... optionalParams)
            throws WeiboClientException {
        return doGet("place/poi_timeline", Paging.EMPTY, buildParams(optionalParams, poiId), Timeline.class);
    }

    public <T extends GetPoiTimelineParam> Timeline getPoiTimeline(
            PoiId poiId, Paging paging, T... optionalParams) throws WeiboClientException {
        return doGet("place/poi_timeline", paging, buildParams(optionalParams, poiId), Timeline.class);
    }

    public static interface GetNearbyTimelineParam extends ParameterAction {
    }

    public Timeline getNearbyTimeline(Latitude latitude, Longitude longitude) throws WeiboClientException {
        return getNearbyTimeline(latitude, longitude, Paging.EMPTY);
    }

    public <T extends GetNearbyTimelineParam> Timeline getNearbyTimeline(
            Latitude latitude, Longitude longitude, T... optionalParams)
            throws WeiboClientException {
        return doGet("place/nearby_timeline", Paging.EMPTY, buildParams(optionalParams, latitude, longitude),
                Timeline.class);
    }

    public <T extends GetNearbyTimelineParam> Timeline getNearbyTimeline(
            Latitude latitude, Longitude longitude, Paging paging, T... optionalParams)
            throws WeiboClientException {
        return doGet("place/nearby_timeline", paging, buildParams(optionalParams, latitude, longitude), Timeline.class);
    }

    public Status showStatus(Id id) throws WeiboClientException {
        return doGet("place/statuses/show", withParams(id), Status.class);
    }

    public UserLBS showUser(Uid uid) throws WeiboClientException {
        return showUser(uid, BaseApp.No);
    }

    public UserLBS showUser(Uid uid, BaseApp baseApp) throws WeiboClientException {
        return doGet("place/users/show", withParams(uid, baseApp), UserLBS.class);
    }

    public static interface GetUserCheckinsParam extends ParameterAction {
    }

    public PoiList getUserCheckins(Uid uid) throws WeiboClientException {
        return getUserCheckins(uid, Paging.EMPTY);
    }

    public <T extends GetUserCheckinsParam> PoiList getUserCheckins(
            Uid uid, T... optionalParams) throws WeiboClientException {
        return doGet("place/users/checkins", Paging.EMPTY, buildParams(optionalParams, uid), PoiList.class);
    }

    public <T extends GetUserCheckinsParam> PoiList getUserCheckins(
            Uid uid, Paging paging, T... optionalParams) throws WeiboClientException {
        return doGet("place/users/checkins", paging, buildParams(optionalParams, uid), PoiList.class);
    }

    public static interface GetUserPhotosParam extends ParameterAction {
    }

    public StatusList getUserPhotos(Uid uid) throws WeiboClientException {
        return getUserPhotos(uid, Paging.EMPTY);
    }

    public <T extends GetUserPhotosParam> StatusList getUserPhotos(
            Uid uid, T... optionalParams) throws WeiboClientException {
        return doGet("place/users/photos", Paging.EMPTY, buildParams(optionalParams, uid), StatusList.class);
    }

    public <T extends GetUserPhotosParam> StatusList getUserPhotos(
            Uid uid, Paging paging, T... optionalParams) throws WeiboClientException {
        return doGet("place/users/photos", paging, buildParams(optionalParams, uid), StatusList.class);
    }

    public static interface GetUserTipsParam extends ParameterAction {
    }

    public StatusList getUserTips(Uid uid) throws WeiboClientException {
        return getUserTips(uid, Paging.EMPTY);
    }

    public <T extends GetUserTipsParam> StatusList getUserTips(
            Uid uid, T... optionalParams) throws WeiboClientException {
        return doGet("place/users/tips", Paging.EMPTY, buildParams(optionalParams, uid), StatusList.class);
    }

    public <T extends GetUserTipsParam> StatusList getUserTips(
            Uid uid, Paging paging, T... optionalParams) throws WeiboClientException {
        return doGet("place/users/tips", paging, buildParams(optionalParams, uid), StatusList.class);
    }

    public static interface GetUserTodosParam extends ParameterAction {
    }

    public StatusList getUserTodos(Uid uid) throws WeiboClientException {
        return getUserTodos(uid, Paging.EMPTY);
    }

    public <T extends GetUserTodosParam> StatusList getUserTodos(
            Uid uid, T... optionalParams) throws WeiboClientException {
        return doGet("place/users/todos", Paging.EMPTY, buildParams(optionalParams, uid), StatusList.class);
    }

    public <T extends GetUserTodosParam> StatusList getUserTodos(
            Uid uid, Paging paging, T... optionalParams) throws WeiboClientException {
        return doGet("place/users/todos", paging, buildParams(optionalParams, uid), StatusList.class);
    }

    public Poi showPoi(PoiId poiId) throws WeiboClientException {
        return showPoi(poiId, BaseApp.No);
    }

    public Poi showPoi(PoiId poiId, BaseApp baseApp) throws WeiboClientException {
        return doGet("place/pois/show", withParams(poiId, baseApp), Poi.class);
    }

    public static interface GetPoiUsersParam extends ParameterAction {
    }

    public UserList getPoiUsers(PoiId poiId) throws WeiboClientException {
        return getPoiUsers(poiId, Paging.EMPTY);
    }

    public <T extends GetPoiUsersParam> UserList getPoiUsers(PoiId poiId, T... optionalParams)
            throws WeiboClientException {
        return doGet("place/pois/users", Paging.EMPTY, buildParams(optionalParams, poiId), UserList.class);
    }

    public <T extends GetPoiUsersParam> UserList getPoiUsers(PoiId poiId, Paging paging, T... optionalParams)
            throws WeiboClientException {
        return doGet("place/pois/users", paging, buildParams(optionalParams, poiId), UserList.class);
    }

    public static interface GetPoiTipsParam extends ParameterAction {
    }

    public StatusList getPoiTips(PoiId poiId) throws WeiboClientException {
        return getPoiTips(poiId, Paging.EMPTY);
    }

    public <T extends GetPoiTipsParam> StatusList getPoiTips(PoiId poiId, T... optionalParams)
            throws WeiboClientException {
        return doGet("place/pois/tips", Paging.EMPTY, buildParams(optionalParams, poiId), StatusList.class);
    }

    public <T extends GetPoiTipsParam> StatusList getPoiTips(PoiId poiId, Paging paging, T... optionalParams)
            throws WeiboClientException {
        return doGet("place/pois/tips", paging, buildParams(optionalParams, poiId), StatusList.class);
    }

    public static interface GetPoiPhotosParam extends ParameterAction {
    }

    public StatusList getPoiPhotos(PoiId poiId) throws WeiboClientException {
        return getPoiPhotos(poiId, Paging.EMPTY);
    }

    public <T extends GetPoiPhotosParam> StatusList getPoiPhotos(PoiId poiId, T... optionalParams)
            throws WeiboClientException {
        return doGet("place/pois/photos", Paging.EMPTY, buildParams(optionalParams, poiId), StatusList.class);
    }

    public <T extends GetPoiPhotosParam> StatusList getPoiPhotos(PoiId poiId, Paging paging, T... optionalParams)
            throws WeiboClientException {
        return doGet("place/pois/photos", paging, buildParams(optionalParams, poiId), StatusList.class);
    }

    public static interface SearchPoisParam extends ParameterAction {
    }

    public PoiList searchPois(Keyword keyword) throws WeiboClientException {
        return searchPois(keyword, Paging.EMPTY);
    }

    public <T extends SearchPoisParam> PoiList searchPois(Keyword keyword, T... optionalParams)
            throws WeiboClientException {
        return doGet("place/pois/search", Paging.EMPTY, buildParams(optionalParams, keyword), PoiList.class);
    }

    public <T extends SearchPoisParam> PoiList searchPois(Keyword keyword, Paging paging, T... optionalParams)
            throws WeiboClientException {
        return doGet("place/pois/search", paging, buildParams(optionalParams, keyword), PoiList.class);
    }

    public static interface GetPoiCategoriesParam extends ParameterAction {
    }

    public <T extends GetPoiCategoriesParam> List<PoiCategory> getPoiCategories(T... optionalParams)
            throws WeiboClientException {
        return doGet("place/pois/category", buildParams(optionalParams), PoiCategory.POI_CATEGORY_LIST);
    }

    public static interface GetNearbyPoisParam extends ParameterAction {
    }

    public PoiList getNearbyPois(Latitude latitude, Longitude longitude) throws WeiboClientException {
        return getNearbyPois(latitude, longitude, Paging.EMPTY);
    }

    public <T extends GetNearbyPoisParam> PoiList getNearbyPois(
            Latitude latitude, Longitude longitude, T... optionalParams)
            throws WeiboClientException {
        return doGet("place/nearby/pois", Paging.EMPTY, buildParams(optionalParams, latitude, longitude),
                PoiList.class);
    }

    public <T extends GetNearbyPoisParam> PoiList getNearbyPois(
            Latitude latitude, Longitude longitude, Paging paging, T... optionalParams)
            throws WeiboClientException {
        return doGet("place/nearby/pois", paging, buildParams(optionalParams, latitude, longitude), PoiList.class);
    }

    public static interface GetNearbyUsersParam extends ParameterAction {
    }

    public UserList getNearbyUsers(Latitude latitude, Longitude longitude) throws WeiboClientException {
        return getNearbyUsers(latitude, longitude, Paging.EMPTY);
    }

    public <T extends GetNearbyUsersParam> UserList getNearbyUsers(
            Latitude latitude, Longitude longitude, T... optionalParams)
            throws WeiboClientException {
        return doGet("place/nearby/users", Paging.EMPTY, buildParams(optionalParams, latitude, longitude),
                UserList.class);
    }

    public <T extends GetNearbyUsersParam> UserList getNearbyUsers(
            Latitude latitude, Longitude longitude, Paging paging, T... optionalParams)
            throws WeiboClientException {
        return doGet("place/nearby/users", paging, buildParams(optionalParams, latitude, longitude), UserList.class);
    }

    public static interface GetNearbyPhotosParam extends ParameterAction {
    }

    public StatusList getNearbyPhotos(Latitude latitude, Longitude longitude) throws WeiboClientException {
        return getNearbyPhotos(latitude, longitude, Paging.EMPTY);
    }

    public <T extends GetNearbyPhotosParam> StatusList getNearbyPhotos(
            Latitude latitude, Longitude longitude, T... optionalParams)
            throws WeiboClientException {
        return doGet("place/nearby/photos", Paging.EMPTY, buildParams(optionalParams, latitude, longitude),
                StatusList.class);
    }

    public <T extends GetNearbyPhotosParam> StatusList getNearbyPhotos(
            Latitude latitude, Longitude longitude, Paging paging, T... optionalParams)
            throws WeiboClientException {
        return doGet("place/nearby/photos", paging, buildParams(optionalParams, latitude, longitude), StatusList.class);
    }

    public static interface GetNearbyUsersListParam extends ParameterAction {
    }

    public UserList getNearbyUsersList(Latitude latitude, Longitude longitude) throws WeiboClientException {
        return getNearbyUsersList(latitude, longitude, Paging.EMPTY);
    }

    public <T extends GetNearbyUsersListParam> UserList getNearbyUsersList(
            Latitude latitude, Longitude longitude, T... optionalParams)
            throws WeiboClientException {
        return doGet("place/nearby_users/list", Paging.EMPTY, buildParams(optionalParams, latitude, longitude),
                UserList.class);
    }

    public <T extends GetNearbyUsersListParam> UserList getNearbyUsersList(
            Latitude latitude, Longitude longitude, Paging paging, T... optionalParams)
            throws WeiboClientException {
        return doGet("place/nearby_users/list", paging, buildParams(optionalParams, latitude, longitude),
                UserList.class);
    }

    public static interface CreatePoiParam extends ParameterAction {
    }

    public <T extends CreatePoiParam> CreatePoiResponse createPoi(
            Title title, Category category, Latitude latitude, Longitude longitude, City city, T... optionalParams)
            throws WeiboClientException {
        return doPost("place/pois/create", buildParams(optionalParams, title, category, latitude, longitude, city),
                CreatePoiResponse.class);
    }

    public Status addCheckin(PoiId poiId, StatusParam status) throws WeiboClientException {
        return addCheckin(poiId, status, null, null);
    }

    public Status addCheckin(PoiId poiId, StatusParam status, IsPublic isPublic) throws WeiboClientException {
        return addCheckin(poiId, status, null, isPublic);
    }

    public Status addCheckin(PoiId poiId, StatusParam status, File image) throws WeiboClientException {
        return addCheckin(poiId, status, image, null);
    }

    public Status addCheckin(PoiId poiId, StatusParam status, File image, IsPublic isPublic)
            throws WeiboClientException {
        OAuthRequest request = createPostRequest("place/pois/add_checkin");
        Parameters params = withParams(poiId, status, isPublic);

        if (image != null) {
            try {
                buildUploadRequest(request, PIC_PARAM_NAME, image, params);
            } catch (IOException e) {
                throw new WeiboClientException(e);
            }
        }

        return sendRequestAndGetResponseObject(request, Status.class);
    }

    public Status addPhoto(PoiId poiId, StatusParam status, File image) throws WeiboClientException {
        return addPhoto(poiId, status, image, null);
    }

    public Status addPhoto(PoiId poiId, StatusParam status, File image, IsPublic isPublic)
            throws WeiboClientException {
        OAuthRequest request = createPostRequest("place/pois/add_photo");
        Parameters params = withParams(poiId, status, isPublic);

        if (image != null) {
            try {
                buildUploadRequest(request, PIC_PARAM_NAME, image, params);
            } catch (IOException e) {
                throw new WeiboClientException(e);
            }
        }

        return sendRequestAndGetResponseObject(request, Status.class);
    }

    public Status addTip(PoiId poiId, StatusParam status) throws WeiboClientException {
        return addTip(poiId, status, null);
    }

    public Status addTip(PoiId poiId, StatusParam status, IsPublic isPublic) throws WeiboClientException {
        return doPost("place/pois/add_tip", withParams(poiId, status, isPublic), Status.class);
    }

    public Status addTodo(PoiId poiId, StatusParam status) throws WeiboClientException {
        return addTodo(poiId, status, null);
    }

    public Status addTodo(PoiId poiId, StatusParam status, IsPublic isPublic) throws WeiboClientException {
        return doPost("place/pois/add_todo", withParams(poiId, status, isPublic), Status.class);
    }

    public int createNearbyUser(Latitude latitude, Longitude longitude) throws WeiboClientException {
        StatusResponse response = doPost("place/nearby_users/create",
                withParams(latitude, longitude), StatusResponse.class);

        return response.getStatus();
    }

    public int destroyNearbyUser() throws WeiboClientException {
        StatusResponse response = doPost("place/nearby_users/destroy", StatusResponse.class);

        return response.getStatus();
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Zoom.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.LocationService;

public class Zoom extends LongParam implements
        LocationService.GetMapImageParam {

    public Zoom(long value) {
        super(value);
    }

    protected String paramKey() {
        return "zoom";
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Pid.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.PlaceService;

/**
 * @author <NAME>
 */
public class Pid extends StringParam implements
        PlaceService.GetPoiCategoriesParam {
    public Pid(String value) {
        super(value);
    }

    protected String paramKey() {
        return "pid";
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/TrendName.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public class TrendName extends StringParam {
    public TrendName(String value) {
        super(value);
    }

    protected String paramKey() {
        return "trend_name";
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Feature.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.StatusService;

import java.util.HashMap;
import java.util.Map;

/**
 * @author <NAME>
 */
public enum Feature implements
        StatusService.GetFriendsTimelineParam,
        StatusService.GetHomeTimelineParam,
        StatusService.GetFriendsTimelineIdsParam,
        StatusService.GetUserTimelineParam,
        StatusService.GetUserTimelineIdsParam,
        StatusService.GetBilateralTimelineParam {

    All(0), Original(1), Picture(2), Video(3), Music(4);

    private static Map<Integer, Feature> map = new HashMap<Integer, Feature>();

    static {
        for (Feature feature : Feature.values()) {
            map.put(feature.getValue(), feature);
        }
    }

    private int value;

    Feature(int value) {
        this.value = value;
    }

    public static Feature fromValue(int value) {
        return map.get(value);
    }

    public int getValue() {
        return value;
    }

    public void addParameter(Parameters params) {
        if (this != All) {
            params.add("feature", getValue());
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/TagService.java<|end_filename|>
package weiboclient4j;

import org.codehaus.jackson.node.ArrayNode;
import weiboclient4j.model.Tag;
import weiboclient4j.model.UserTagList;
import weiboclient4j.params.Paging;
import weiboclient4j.params.TagId;
import weiboclient4j.params.TagName;
import weiboclient4j.params.Uid;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author <NAME>
 */
public class TagService extends AbstractService {
    public TagService(WeiboClient client) {
        super(client);
    }

    public List<Tag> getTags(Uid uid) throws WeiboClientException {
        return getTags(uid, Paging.EMPTY);
    }

    public List<Tag> getTags(Uid uid, Paging paging) throws WeiboClientException {
        ArrayNode arrayNode = doGet("tags", paging, withParams(uid), ArrayNode.class);

        return Tag.parseTags(arrayNode);
    }

    public List<UserTagList> getBatch(Collection<Uid> uids) throws WeiboClientException {
        ArrayNode arrayNode = doGet("tags/tags_batch",
                withParams(Uid.uidsParam(uids)), ArrayNode.class);

        return UserTagList.parse(arrayNode);
    }

    public List<Tag> getSuggestions() throws WeiboClientException {
        return getSuggestions(Paging.EMPTY);
    }

    public List<Tag> getSuggestions(Paging paging) throws WeiboClientException {
        List<LongIdStringValue> list = doGet("tags/suggestions", paging, TYPE_LONG_ID_STRING_VALUE_LIST);

        List<Tag> tags = new ArrayList<Tag>(list.size());
        for (LongIdStringValue value : list) {
            tags.add(new Tag(value.getId(), value.getValue()));
        }

        return tags;
    }

    public List<Long> create(Collection<TagName> tagNames) throws WeiboClientException {
        List<TagActionResponse> responseList = doPost("tags/create",
                withParams(TagName.tagsParam(tagNames)), TYPE_TAG_ACTION_RESPONSE_LIST);

        return TagActionResponse.toLongList(responseList);
    }

    public boolean destroy(TagId tagId) throws WeiboClientException {
        ResultResponse response = doPost("tags/destroy",
                withParams(tagId), ResultResponse.class);

        return response.isResult();
    }

    public List<Long> destroyBatch(Collection<TagId> tagIds) throws WeiboClientException {
        List<TagActionResponse> responseList = doPost("tags/destroy_batch",
                withParams(TagId.idsParam(tagIds)), TYPE_TAG_ACTION_RESPONSE_LIST);

        return TagActionResponse.toLongList(responseList);
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/StartTime.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.PlaceService;

/**
 * @author <NAME>
 */
public class StartTime extends LongParam implements
        PlaceService.GetNearbyUsersParam,
        PlaceService.GetNearbyPhotosParam,
        PlaceService.GetNearbyTimelineParam {

    public StartTime(long value) {
        super(value);
    }

    protected String paramKey() {
        return "starttime";
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/IsBase62.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.StatusService;

/**
 * @author <NAME>
 */
public enum IsBase62 implements
        StatusService.QueryIdParam,
        StatusService.QueryIdListParam {

    Yes(1), No(0);

    private int value;

    IsBase62(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void addParameter(Parameters params) {
        if (this == Yes) {
            params.add("isBase62", getValue());
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/RawSuggestionUser.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.type.TypeReference;

import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class RawSuggestionUser {
    public static final TypeReference<List<RawSuggestionUser>> TYPE_SUGGESTION_USER_LIST =
            new TypeReference<List<RawSuggestionUser>>() {
    };

    private long uid;
    private Reason reason;

    public long getUid() {
        return uid;
    }

    public void setUid(long uid) {
        this.uid = uid;
    }

    public Reason getReason() {
        return reason;
    }

    public void setReason(Reason reason) {
        this.reason = reason;
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class Reason {
        private Item f;
        private Item h;
        private Item c;
        private Item s;
        private Item t;

        public Item getS() {
            return s;
        }

        public void setS(Item s) {
            this.s = s;
        }

        public Item getT() {
            return t;
        }

        public void setT(Item t) {
            this.t = t;
        }

        public Item getF() {
            return f;
        }

        public void setF(Item f) {
            this.f = f;
        }

        public Item getH() {
            return h;
        }

        public void setH(Item h) {
            this.h = h;
        }

        public Item getC() {
            return c;
        }

        public void setC(Item c) {
            this.c = c;
        }

        @JsonIgnoreProperties(ignoreUnknown = true)
        public static class Item {
            private String name;
            private List<Long> uid;
            private int n;

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }

            public List<Long> getUid() {
                return uid;
            }

            public void setUid(List<Long> uid) {
                this.uid = uid;
            }

            public int getN() {
                return n;
            }

            public void setN(int n) {
                this.n = n;
            }
        }
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParseWeiboErrorTest.java<|end_filename|>
package weiboclient4j.model;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
import org.junit.Test;
import weiboclient4j.WeiboError;
import weiboclient4j.utils.JsonUtils;

/**
 * @author <NAME>
 */
public class ParseWeiboErrorTest extends AbstractParseJsonTest {
    @Test
    public void testParseWeiboError() throws Exception {
        String content = readResource("/weiboclient4j/model/error.json");

        WeiboError error = JsonUtils.readValue(content, WeiboError.class);
        assertThat(error, is(notNullValue()));
        assertThat(error.getErrorCodeAsInt(), is(20502));
    }
}


<|start_filename|>src/main/java/weiboclient4j/StatusService.java<|end_filename|>
package weiboclient4j;

import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.node.ArrayNode;
import org.scribe.model.OAuthRequest;
import weiboclient4j.model.Count;
import weiboclient4j.model.Emotion;
import weiboclient4j.model.IdResponse;
import weiboclient4j.model.MidResponse;
import weiboclient4j.model.RepostTimeline;
import weiboclient4j.model.Status;
import weiboclient4j.model.Timeline;
import weiboclient4j.model.TimelineIds;
import weiboclient4j.model.UploadedPic;
import weiboclient4j.params.Id;
import weiboclient4j.params.IsBatch;
import weiboclient4j.params.IsComment;
import weiboclient4j.params.Latitude;
import weiboclient4j.params.ListId;
import weiboclient4j.params.Longitude;
import weiboclient4j.params.Mid;
import weiboclient4j.params.MidType;
import weiboclient4j.params.Paging;
import weiboclient4j.params.ParameterAction;
import weiboclient4j.params.Parameters;
import weiboclient4j.params.PicId;
import weiboclient4j.params.ScreenName;
import weiboclient4j.params.StatusParam;
import weiboclient4j.params.Uid;
import weiboclient4j.params.Visible;
import static weiboclient4j.utils.StringUtils.isNotBlank;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Status API
 *
 * @author <NAME>
 */
@SuppressWarnings("unchecked")
public class StatusService extends AbstractService {

    private static final String PIC_PARAM_NAME = "pic";

    public StatusService(WeiboClient client) {
        super(client);
    }

    public static interface GetPublicTimelineParam extends ParameterAction {
    }

    public Timeline getPublicTimeline() throws WeiboClientException {
        return getPublicTimeline(Paging.EMPTY);
    }

    public <T extends GetPublicTimelineParam> Timeline getPublicTimeline(T... optionalParams)
            throws WeiboClientException {
        return doGet("statuses/public_timeline", Paging.EMPTY, buildParams(optionalParams), Timeline.class);
    }

    public <T extends GetPublicTimelineParam> Timeline getPublicTimeline(
            Paging paging, T... optionalParams) throws WeiboClientException {
        return doGet("statuses/public_timeline", paging, buildParams(optionalParams), Timeline.class);
    }

    public static interface GetFriendsTimelineParam extends ParameterAction {
    }

    public Timeline getFriendsTimeline() throws WeiboClientException {
        return getFriendsTimeline(Paging.EMPTY);
    }

    public <T extends GetFriendsTimelineParam> Timeline getFriendsTimeline(T... optionalParams)
            throws WeiboClientException {
        return doGet("statuses/friends_timeline", Paging.EMPTY, buildParams(optionalParams), Timeline.class);
    }

    public <T extends GetFriendsTimelineParam> Timeline getFriendsTimeline(
            Paging paging, T... optionalParams) throws WeiboClientException {
        return doGet("statuses/friends_timeline", paging, buildParams(optionalParams), Timeline.class);
    }

    public static interface GetHomeTimelineParam extends ParameterAction {
    }

    public Timeline getHomeTimeline() throws WeiboClientException {
        return getHomeTimeline(Paging.EMPTY);
    }

    public <T extends GetHomeTimelineParam> Timeline getHomeTimeline(T... optionalParams)
            throws WeiboClientException {
        return doGet("statuses/home_timeline", Paging.EMPTY, buildParams(optionalParams), Timeline.class);
    }

    public <T extends GetHomeTimelineParam> Timeline getHomeTimeline(
            Paging paging, T... optionalParams) throws WeiboClientException {
        return doGet("statuses/home_timeline", paging, buildParams(optionalParams), Timeline.class);
    }

    public static interface GetFriendsTimelineIdsParam extends ParameterAction {
    }

    public TimelineIds getFriendsTimelineIds() throws WeiboClientException {
        return getFriendsTimelineIds(Paging.EMPTY);
    }

    public <T extends GetFriendsTimelineIdsParam> TimelineIds getFriendsTimelineIds(T... optionalParams)
            throws WeiboClientException {
        return doGet("statuses/friends_timeline/ids", Paging.EMPTY, buildParams(optionalParams), TimelineIds.class);
    }

    public <T extends GetFriendsTimelineIdsParam> TimelineIds getFriendsTimelineIds(
            Paging paging, T... optionalParams) throws WeiboClientException {
        return doGet("statuses/friends_timeline/ids", paging, buildParams(optionalParams), TimelineIds.class);
    }

    public static interface GetUserTimelineParam extends ParameterAction {
    }

    public <T extends GetUserTimelineParam> Timeline getUserTimeline(T... optionalParams)
            throws WeiboClientException {
        return getUserTimeline(Uid.EMPTY, ScreenName.EMPTY, Paging.EMPTY, optionalParams);
    }

    public <T extends GetUserTimelineParam> Timeline getUserTimeline(Paging paging, T... optionalParams)
            throws WeiboClientException {
        return getUserTimeline(Uid.EMPTY, ScreenName.EMPTY, paging, optionalParams);
    }

    public Timeline getUserTimeline(Uid uid) throws WeiboClientException {
        return getUserTimeline(uid, Paging.EMPTY);
    }

    public <T extends GetUserTimelineParam> Timeline getUserTimeline(
            Uid uid, T... optionalParams) throws WeiboClientException {
        return getUserTimeline(uid, ScreenName.EMPTY, Paging.EMPTY, optionalParams);
    }

    public <T extends GetUserTimelineParam> Timeline getUserTimeline(
            Uid uid, Paging paging, T... optionalParams) throws WeiboClientException {
        return getUserTimeline(uid, ScreenName.EMPTY, paging, optionalParams);
    }

    public Timeline getUserTimeline(ScreenName screenName) throws WeiboClientException {
        return getUserTimeline(screenName, Paging.EMPTY);
    }

    public <T extends GetUserTimelineParam> Timeline getUserTimeline(
            ScreenName screenName, Paging paging, T... optionalParams) throws WeiboClientException {
        return getUserTimeline(Uid.EMPTY, screenName, paging, optionalParams);
    }

    private <T extends GetUserTimelineParam> Timeline getUserTimeline(
            Uid uid, ScreenName screenName, Paging paging, T... optionalParams) throws WeiboClientException {
        return doGet("statuses/user_timeline", paging,
                buildParams(optionalParams, uid, screenName), Timeline.class);
    }

    public static interface GetUserTimelineIdsParam extends ParameterAction {
    }

    public <T extends GetUserTimelineIdsParam> TimelineIds getUserTimelineIds(
            T... optionalParams) throws WeiboClientException {
        return getUserTimelineIds(Uid.EMPTY, ScreenName.EMPTY, Paging.EMPTY, optionalParams);
    }

    public <T extends GetUserTimelineIdsParam> TimelineIds getUserTimelineIds(
            Paging paging, T... optionalParams) throws WeiboClientException {
        return getUserTimelineIds(Uid.EMPTY, ScreenName.EMPTY, paging, optionalParams);
    }

    public TimelineIds getUserTimelineIds(ScreenName screenName) throws WeiboClientException {
        return getUserTimelineIds(screenName, Paging.EMPTY);
    }

    public <T extends GetUserTimelineIdsParam> TimelineIds getUserTimelineIds(
            ScreenName screenName, T... optionalParams) throws WeiboClientException {
        return getUserTimelineIds(screenName, Paging.EMPTY, optionalParams);
    }

    public <T extends GetUserTimelineIdsParam> TimelineIds getUserTimelineIds(
            ScreenName screenName, Paging paging, T... optionalParams) throws WeiboClientException {
        return getUserTimelineIds(Uid.EMPTY, screenName, paging, optionalParams);
    }

    public TimelineIds getUserTimelineIds(Uid uid) throws WeiboClientException {
        return getUserTimelineIds(uid, Paging.EMPTY);
    }

    public <T extends GetUserTimelineIdsParam> TimelineIds getUserTimelineIds(
            Uid uid, T... optionalParams) throws WeiboClientException {
        return getUserTimelineIds(uid, Paging.EMPTY, optionalParams);
    }

    public <T extends GetUserTimelineIdsParam> TimelineIds getUserTimelineIds(
            Uid uid, Paging paging, T... optionalParams) throws WeiboClientException {
        return getUserTimelineIds(uid, ScreenName.EMPTY, paging, optionalParams);
    }

    private <T extends GetUserTimelineIdsParam> TimelineIds getUserTimelineIds(
            Uid uid, ScreenName screenName, Paging paging, T... optionalParams) throws WeiboClientException {
        return doGet("statuses/user_timeline/ids", paging, buildParams(optionalParams, uid, screenName),
                TimelineIds.class);
    }

    public static interface GetRepostTimelineParam extends ParameterAction {
    }

    public RepostTimeline getRepostTimeline(Id id) throws WeiboClientException {
        return getRepostTimeline(id, Paging.EMPTY);
    }

    public <T extends GetRepostTimelineParam> RepostTimeline getRepostTimeline(
            Id id, T... optionalParams) throws WeiboClientException {
        return doGet("statuses/repost_timeline", Paging.EMPTY, buildParams(optionalParams, id), RepostTimeline.class);
    }

    public <T extends GetRepostTimelineParam> RepostTimeline getRepostTimeline(
            Id id, Paging paging, T... optionalParams) throws WeiboClientException {
        try {
            return doGet("statuses/repost_timeline", paging, buildParams(optionalParams, id), RepostTimeline.class);
        } catch (WeiboClientException e) {
            if (e.getWeiboError() == null && isNotBlank(e.getResponseBody())) {
                if ("[]".equals(e.getResponseBody())) {
                    return RepostTimeline.EMPTY;
                }
            }

            throw e;
        }
    }

    public static interface GetRepostTimelineIdsParam extends ParameterAction {
    }

    public TimelineIds getRepostTimelineIds(Id id) throws WeiboClientException {
        return getRepostTimelineIds(id, Paging.EMPTY);
    }

    public <T extends GetRepostTimelineIdsParam> TimelineIds getRepostTimelineIds(
            Id id, T... optionalParams) throws WeiboClientException {
        return doGet("statuses/repost_timeline/ids", Paging.EMPTY, buildParams(optionalParams, id), TimelineIds.class);
    }

    public <T extends GetRepostTimelineIdsParam> TimelineIds getRepostTimelineIds(
            Id id, Paging paging, T... optionalParams) throws WeiboClientException {
        return doGet("statuses/repost_timeline/ids", paging, buildParams(optionalParams, id), TimelineIds.class);
    }

    public RepostTimeline getRepostByMe() throws WeiboClientException {
        return getRepostByMe(Paging.EMPTY);
    }

    public RepostTimeline getRepostByMe(Paging paging) throws WeiboClientException {
        return doGet("statuses/repost_by_me", paging, RepostTimeline.class);
    }

    public static interface GetMentionsParam extends ParameterAction {
    }

    public <T extends GetMentionsParam> Timeline getMentions(T... optionalParams) throws WeiboClientException {
        return getMentions(Paging.EMPTY, optionalParams);
    }

    public <T extends GetMentionsParam> Timeline getMentions(Paging paging, T... optionalParams)
            throws WeiboClientException {
        return doGet("statuses/mentions", paging, buildParams(optionalParams), Timeline.class);
    }

    public static interface GetMentionsIdsParam extends ParameterAction {
    }

    public <T extends GetMentionsIdsParam> TimelineIds getMentionsIds(T... optionalParams)
            throws WeiboClientException {
        return doGet("statuses/mentions/ids", Paging.EMPTY, buildParams(optionalParams), TimelineIds.class);
    }

    public <T extends GetMentionsIdsParam> TimelineIds getMentionsIds(
            Paging paging, T... optionalParams) throws WeiboClientException {
        return doGet("statuses/mentions/ids", paging, buildParams(optionalParams), TimelineIds.class);
    }

    public static interface GetBilateralTimelineParam extends ParameterAction {
    }

    public <T extends GetBilateralTimelineParam> Timeline getBilateralTimeline(T... optionalParams)
            throws WeiboClientException {
        return doGet("statuses/bilateral_timeline", Paging.EMPTY, buildParams(optionalParams), Timeline.class);
    }

    public <T extends GetBilateralTimelineParam> Timeline getBilateralTimeline(
            Paging paging, T... optionalParams) throws WeiboClientException {
        return doGet("statuses/bilateral_timeline", paging, buildParams(optionalParams), Timeline.class);
    }

    public Status show(Id id) throws WeiboClientException {
        return doGet("statuses/show", withParams(id), Status.class);
    }

    public String queryMid(Id id, MidType midType) throws WeiboClientException {
        MidResponse midResponse = doGet("statuses/querymid",
                withParams(id, midType), MidResponse.class);

        return midResponse != null ? midResponse.getMid() : null;
    }

    public Map<Long, String> queryMidList(Collection<Id> idList, MidType midType) throws WeiboClientException {
        // [{"3436240135184587":"yfcLPlKKn"},{"3436255091659029":"yfd9X6XAx"}]
        ArrayNode arrayNode = doGet("statuses/querymid",
                withParams(Id.idParam(idList), midType, IsBatch.Yes), ArrayNode.class);

        Map<Long, String> map = new HashMap<Long, String>();
        for (int i = 0; i < arrayNode.size(); i++) {
            JsonNode node = arrayNode.get(i);
            Iterator<String> fieldNames = node.getFieldNames();
            while (fieldNames.hasNext()) {
                String idString = fieldNames.next();
                map.put(new Long(idString), node.get(idString).asText());
            }
        }

        return map;
    }

    public static interface QueryIdParam extends ParameterAction {
    }

    public <T extends QueryIdParam> long queryId(
            Mid mid, MidType type, T... optionalParams) throws WeiboClientException {
        IdResponse idResponse = doGet("statuses/queryid", buildParams(optionalParams, mid, type), IdResponse.class);

        return idResponse.getId();
    }

    public static interface QueryIdListParam extends ParameterAction {
    }

    public <T extends QueryIdListParam> Map<String, Long> queryIdList(
            Collection<Mid> midList, MidType type, T... optionalParams)
            throws WeiboClientException {
        // [{"yfcLPlKKn":"3436240135184587"},{"yfd9X6XAx":"3436255091659029"}]
        ArrayNode arrayNode = doGet("statuses/queryid", buildParams(optionalParams, Mid.midParam(midList), type,
                IsBatch.Yes), ArrayNode.class);

        Map<String, Long> map = new HashMap<String, Long>();
        for (int i = 0; i < arrayNode.size(); i++) {
            JsonNode node = arrayNode.get(i);
            Iterator<String> fieldNames = node.getFieldNames();
            while (fieldNames.hasNext()) {
                String mid = fieldNames.next();
                map.put(mid, node.get(mid).asLong());
            }
        }

        return map;
    }

    public List<Count> getStatusesCounts(Collection<Id> ids) throws WeiboClientException {
        return doGet("statuses/count",
                withParams(Id.idsParam(ids)), Count.TYPE_COUNT_LIST);
    }

    public Status repost(Id id, String status) throws WeiboClientException {
        return repost(id, status, IsComment.No);
    }

    public Status repost(Id id, String status, IsComment isComment) throws WeiboClientException {
        return repost(id, new StatusParam(status), isComment);
    }

    public Status repost(Id id, StatusParam status, IsComment isComment) throws WeiboClientException {
        return doPost("statuses/repost", withParams(id, status, isComment), Status.class);
    }

    public Status update(String status) throws WeiboClientException {
        return update(status, null, null);
    }

    public Status update(String status, Latitude latitude, Longitude longitude) throws WeiboClientException {
        return update(new StatusParam(status), latitude, longitude);
    }

    public Status update(StatusParam status, Latitude latitude, Longitude longitude) throws WeiboClientException {
        return doPost("statuses/update", withParams(status, latitude, longitude), Status.class);
    }

    public Status destroy(Id id) throws WeiboClientException {
        return doPost("statuses/destroy", withParams(id), Status.class);
    }

    public static interface UploadImageUrlParam extends ParameterAction {
    }

    public Status uploadImageUrl(String status, URL url, UploadImageUrlParam... optionalParams)
        throws WeiboClientException {
        return uploadImageUrl(new StatusParam(status), url, optionalParams);
    }

    public Status uploadImageUrl(StatusParam status, URL url, UploadImageUrlParam... optionalParams)
            throws WeiboClientException {
        return uploadImageUrl(status, url, null, optionalParams);
    }

    public Status uploadImageUrl(String status, PicId picId, UploadImageUrlParam... optionalParams)
            throws WeiboClientException {
        return uploadImageUrl(new StatusParam(status), picId, optionalParams);
    }

    public Status uploadImageUrl(StatusParam status, PicId picId, UploadImageUrlParam... optionalParams)
            throws WeiboClientException {
        return uploadImageUrl(status, null, picId, optionalParams);
    }

    public Status uploadImageUrl(String status, URL url, PicId picId, UploadImageUrlParam... optionalParams)
            throws WeiboClientException {
        return uploadImageUrl(new StatusParam(status), url, picId, optionalParams);
    }

    public Status uploadImageUrl(StatusParam status, URL url, PicId picId, UploadImageUrlParam... optionalParams)
            throws WeiboClientException {
        return doPost("statuses/upload_url_text", buildParams(optionalParams, status, urlParam(url), picId),
                Status.class);
    }

    public Status uploadImageBinary(StatusParam status, File image) throws WeiboClientException {
        return uploadImageBinary(status, Visible.All, null, image, null, null);
    }

    public Status uploadImageBinary(StatusParam status, Visible visible, ListId listId, File image)
            throws WeiboClientException {
        return uploadImageBinary(status, visible, listId, image, null, null);
    }

    public Status uploadImageBinary(StatusParam status, File image, Latitude latitude, Longitude longitude)
            throws WeiboClientException {
        return uploadImageBinary(status, null, null, image, latitude, longitude);
    }

    public Status uploadImageBinary(StatusParam status, Visible visible, ListId listId, File image, Latitude latitude,
                                    Longitude longitude) throws WeiboClientException {
        OAuthRequest request = createPostRequest("statuses/upload");
        Parameters params = withParams(status, visible, listId, latitude, longitude);

        try {
            buildUploadRequest(request, PIC_PARAM_NAME, image, params);
        } catch (IOException e) {
            throw new WeiboClientException(e);
        }

        return sendRequestAndGetResponseObject(request, Status.class);
    }

    public List<Emotion> getEmotions() throws WeiboClientException {
        return doGet("emotions", Emotion.TYPE_EMOTION_LIST);
    }

    public UploadedPic uploadImage(File image) throws WeiboClientException {
        OAuthRequest request = createPostRequest("statuses/upload_pic");

        try {
            buildUploadRequest(request, PIC_PARAM_NAME, image, Parameters.create());
        } catch (IOException e) {
            throw new WeiboClientException(e);
        }

        return sendRequestAndGetResponseObject(request, UploadedPic.class);
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/ParameterAction.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public interface ParameterAction {
    void addParameter(Parameters params);
}


<|start_filename|>src/main/java/weiboclient4j/params/Font.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.LocationService;

public class Font extends StringParam implements
        LocationService.GetMapImageParam {

    public Font(String value) {
        super(value);
    }

    protected String paramKey() {
        return "font";
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/GlobalTrendList.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.node.ArrayNode;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class GlobalTrendList {
    private String time;
    private List<GlobalTrend> trends;
    private long asOf;

    public GlobalTrendList() {
    }

    public GlobalTrendList(JsonNode json) {
        asOf = json.get("as_of").getLongValue();
        JsonNode trendsNode = json.get("trends");
        Iterator<String> fieldNames = trendsNode.getFieldNames();
        if (fieldNames.hasNext()) {
            time = fieldNames.next();
            ArrayNode trendArray = (ArrayNode) trendsNode.get(time);
            trends = new ArrayList<GlobalTrend>();
            for (JsonNode trendNode : trendArray) {
                trends.add(new GlobalTrend(trendNode));
            }
        }
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public List<GlobalTrend> getTrends() {
        return trends;
    }

    public void setTrends(List<GlobalTrend> trends) {
        this.trends = trends;
    }

    public long getAsOf() {
        return asOf;
    }

    public void setAsOf(long asOf) {
        this.asOf = asOf;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/FloatParam.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public abstract class FloatParam implements ParameterAction {
    private float value;

    public FloatParam(float value) {
        this.value = value;
    }

    public float getValue() {
        return value;
    }

    @Override
    public String toString() {
        return String.valueOf(value);
    }

    protected abstract String paramKey();

    public void addParameter(Parameters params) {
        params.add(paramKey(), getValue());
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/UserCount.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.type.TypeReference;

import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserCount {
    public static final TypeReference<List<UserCount>> LIST_TYPE = new TypeReference<List<UserCount>>() {
    };

    private long id;
    private long followersCount;
    private int friendsCount;
    private int statusesCount;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public long getFollowersCount() {
        return followersCount;
    }

    public void setFollowersCount(long followersCount) {
        this.followersCount = followersCount;
    }

    public int getFriendsCount() {
        return friendsCount;
    }

    public void setFriendsCount(int friendsCount) {
        this.friendsCount = friendsCount;
    }

    public int getStatusesCount() {
        return statusesCount;
    }

    public void setStatusesCount(int statusesCount) {
        this.statusesCount = statusesCount;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/SearchSuggestionAtUserResult.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.type.TypeReference;

import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class SearchSuggestionAtUserResult {
    public static final TypeReference<List<SearchSuggestionAtUserResult>> TYPE_SEARCH_SUGGESTION_AT_USER_RESULT_LIST =
            new TypeReference<List<SearchSuggestionAtUserResult>>() {
            };

    private long uid;
    private String nickname;
    private String remark;

    public long getUid() {
        return uid;
    }

    public void setUid(long uid) {
        this.uid = uid;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }
}


<|start_filename|>src/test/java/weiboclient4j/params/ParametersTest.java<|end_filename|>
package weiboclient4j.params;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;

/**
 * @author <NAME>
 */
public class ParametersTest {
    @Test
    public void testBuildParameters() throws Exception {
        Parameters parameters = Parameters.create();

        assertEquals(0, parameters.size());

        parameters.add("key", "value");
        assertEquals("value", parameters.get("key"));
    }

    @Test
    public void testIsEmpty() throws Exception {
        Parameters parameters = Parameters.create();
        assertTrue(parameters.isEmpty());
        assertFalse(parameters.isNotEmpty());

        parameters.add("key", "value");
        assertFalse(parameters.isEmpty());
        assertTrue(parameters.isNotEmpty());
    }

    @Test
    public void testAddLongArrayOneItem() throws Exception {
        Parameters parameters = Parameters.create();
        long[] ids = new long[]{1};
        parameters.add("key", ids);

        assertEquals("1", parameters.get("key"));
    }

    @Test
    public void testAddLongArrayTwoItem() throws Exception {
        Parameters parameters = Parameters.create();
        long[] ids = new long[]{1, 2};
        parameters.add("key", ids);

        assertEquals("1,2", parameters.get("key"));
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/UnreadCount.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class UnreadCount {

    // V2 fields
    private int dm;
    private int status;
    private int follower;
    private int cmt;
    private int mentionStatus;
    private int mentionCmt;
    private int group;
    private int privateGroup;
    private int notice;
    private int invite;
    private int badge;
    private int photo;
    private int msgbox;

    public int getDm() {
        return dm;
    }

    public void setDm(int dm) {
        this.dm = dm;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public int getFollower() {
        return follower;
    }

    public void setFollower(int follower) {
        this.follower = follower;
    }

    public int getCmt() {
        return cmt;
    }

    public void setCmt(int cmt) {
        this.cmt = cmt;
    }

    public int getMentionStatus() {
        return mentionStatus;
    }

    public void setMentionStatus(int mentionStatus) {
        this.mentionStatus = mentionStatus;
    }

    public int getMentionCmt() {
        return mentionCmt;
    }

    public void setMentionCmt(int mentionCmt) {
        this.mentionCmt = mentionCmt;
    }

    public int getGroup() {
        return group;
    }

    public void setGroup(int group) {
        this.group = group;
    }

    public int getPrivateGroup() {
        return privateGroup;
    }

    public void setPrivateGroup(int privateGroup) {
        this.privateGroup = privateGroup;
    }

    public int getNotice() {
        return notice;
    }

    public void setNotice(int notice) {
        this.notice = notice;
    }

    public int getInvite() {
        return invite;
    }

    public void setInvite(int invite) {
        this.invite = invite;
    }

    public int getBadge() {
        return badge;
    }

    public void setBadge(int badge) {
        this.badge = badge;
    }

    public int getPhoto() {
        return photo;
    }

    public void setPhoto(int photo) {
        this.photo = photo;
    }

    public int getMsgbox() {
        return msgbox;
    }

    public void setMsgbox(int msgbox) {
        this.msgbox = msgbox;
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParsePrivacyTest.java<|end_filename|>
package weiboclient4j.model;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import weiboclient4j.utils.JsonUtils;

/**
 * @author <NAME>
 */
public class ParsePrivacyTest extends AbstractParseJsonTest {
    @Test
    public void testParsePrivacy() throws Exception {
        String content = readResource("/weiboclient4j/model/privacy.json");

        Privacy privacy = JsonUtils.readValue(content, Privacy.class);
        assertTrue(privacy.isBadge());
        assertFalse(privacy.isComment());
        assertTrue(privacy.isGeo());
        assertTrue(privacy.isMessage());
        assertTrue(privacy.isMobile());
        assertFalse(privacy.isRealname());
    }
}


<|start_filename|>src/main/java/weiboclient4j/SuggestionService.java<|end_filename|>
package weiboclient4j;

import weiboclient4j.model.RawSuggestionUser;
import weiboclient4j.model.Status;
import weiboclient4j.model.StatusIdList;
import weiboclient4j.model.StatusList;
import weiboclient4j.model.SuggestionUser;
import static weiboclient4j.model.SuggestionUser.convertFromRawSuggestionUserList;
import weiboclient4j.model.User;
import weiboclient4j.model.UserList;
import weiboclient4j.params.Content;
import weiboclient4j.params.IsPic;
import weiboclient4j.params.Num;
import weiboclient4j.params.Paging;
import weiboclient4j.params.Section;
import weiboclient4j.params.SuggestionStatusType;
import weiboclient4j.params.SuggestionUserCategory;
import weiboclient4j.params.Uid;

import java.util.List;

/**
 * @author <NAME>
 */
public class SuggestionService extends AbstractService {
    public SuggestionService(WeiboClient client) {
        super(client);
    }

    public List<User> getUsersHot() throws WeiboClientException {
        return getUsersHot(SuggestionUserCategory.Default);
    }

    public List<User> getUsersHot(SuggestionUserCategory category) throws WeiboClientException {
        return doGet("suggestions/users/hot",
                withParams(category), User.TYPE_USER_LIST);
    }

    public List<SuggestionUser> getUsersMayInterested() throws WeiboClientException {
        return getUsersMayInterested(Paging.EMPTY);
    }

    public List<SuggestionUser> getUsersMayInterested(Paging paging) throws WeiboClientException {
        List<RawSuggestionUser> rawSuggestionUsers =
                doGet("suggestions/users/may_interested", paging,
                        RawSuggestionUser.TYPE_SUGGESTION_USER_LIST);

        return convertFromRawSuggestionUserList(rawSuggestionUsers);
    }

    public UserList getUsersByStatus(Content content) throws WeiboClientException {
        return getUsersByStatus(content, Num.EMPTY);
    }

    public UserList getUsersByStatus(Content content, Num num) throws WeiboClientException {
        return doGet("suggestions/users/by_status",
                withParams(content, num), UserList.class);
    }

    public StatusList getStatusesHot(SuggestionStatusType type, IsPic isPic) throws WeiboClientException {
        return getStatusesHot(type, isPic, Paging.EMPTY);
    }

    public StatusList getStatusesHot(SuggestionStatusType type, IsPic isPic, Paging paging)
            throws WeiboClientException {
        return doGet("suggestions/statuses/hot",
                paging, withParams(type, isPic), StatusList.class);
    }

    public StatusList getStatusesReorder(Section section) throws WeiboClientException {
        return getStatusesReorder(section, Paging.EMPTY);
    }

    public StatusList getStatusesReorder(Section section, Paging paging) throws WeiboClientException {
        return doGet("suggestions/statuses/reorder",
                paging, withParams(section), StatusList.class);
    }

    public StatusIdList getStatusIdsReorder(Section section) throws WeiboClientException {
        return getStatusIdsReorder(section, Paging.EMPTY);
    }

    public StatusIdList getStatusIdsReorder(Section section, Paging paging) throws WeiboClientException {
        return doGet("suggestions/statuses/reorder/ids",
                paging, withParams(section), StatusIdList.class);
    }

    public List<Status> getFavoritesHot() throws WeiboClientException {
        return getFavoritesHot(Paging.EMPTY);
    }

    public List<Status> getFavoritesHot(Paging paging) throws WeiboClientException {
        return doGet("suggestions/favorites/hot", paging, Status.TYPE_STATUS_LIST);
    }

    public User setUserNotInterested(Uid uid) throws WeiboClientException {
        return doPost("suggestions/users/not_interested",
                withParams(uid), User.class);
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/NotificationResult.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class NotificationResult {
    private Notification notification;
    private List<Long> failedUid;

    public Notification getNotification() {
        return notification;
    }

    public void setNotification(Notification notification) {
        this.notification = notification;
    }

    public List<Long> getFailedUid() {
        return failedUid;
    }

    public void setFailedUid(List<Long> failedUid) {
        this.failedUid = failedUid;
    }
}


<|start_filename|>src/main/java/weiboclient4j/WeiboClientException.java<|end_filename|>
package weiboclient4j;

import weiboclient4j.utils.StringUtils;

/**
 * @author <NAME>
 */
public class WeiboClientException extends Exception {
    private int responseCode;
    private String responseBody;
    private WeiboError error;

    public WeiboClientException() {
    }

    public WeiboClientException(String message) {
        super(message);
    }

    public WeiboClientException(String message, Throwable cause) {
        super(message, cause);
    }

    public WeiboClientException(Throwable cause) {
        super(cause);
    }

    public WeiboClientException(WeiboError error) {
        this(error.toString());

        this.error = error;
    }

    @Override
    public String getMessage() {
        String sourceMessage = super.getMessage();

        if (StringUtils.isNotBlank(responseBody)) {
            return String.format("<%d: %s> %s", responseCode, responseBody, sourceMessage);
        } else if (responseCode != 0) {
            return String.format("<%d> %s", responseCode, sourceMessage);
        } else {
            return sourceMessage;
        }
    }

    public WeiboClientException(int code) {
        responseCode = code;
    }

    public WeiboClientException(int code, String body, WeiboError error) {
        this(error);

        responseCode = code;
        responseBody = body;
    }

    public WeiboClientException(int code, String body, Throwable cause) {
        this(cause);

        responseCode = code;
        responseBody = body;
    }

    public boolean isWeiboError() {
        return error != null;
    }

    public WeiboError getWeiboError() {
        return error;
    }

    public int getResponseCode() {
        return responseCode;
    }

    public String getResponseBody() {
        return responseBody;
    }

    public void setResponseBody(String responseBody) {
        this.responseBody = responseBody;
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParseStatusTest.java<|end_filename|>
package weiboclient4j.model;

import org.junit.Test;
import weiboclient4j.utils.JsonUtils;
import static weiboclient4j.utils.JsonUtils.parseJsonObject;

/**
 * @author <NAME>
 */
public class ParseStatusTest extends AbstractParseJsonTest {
    @Test
    public void testParseStatusList() throws Exception {
        String content = readResource("/weiboclient4j/model/statuses.json");
        JsonUtils.parseJsonObject(content, Status.TYPE_STATUS_LIST);
    }

    @Test
    public void testParseStatusesIncludingDeleted() throws Exception {
        String content = readResource("/weiboclient4j/model/statuses_including_deleted.json");
        parseJsonObject(content, Status.TYPE_STATUS_LIST);
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Num.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public class Num extends LongParam {
    public static final Num EMPTY = new Num(0);

    public Num(long value) {
        super(value);
    }

    protected String paramKey() {
        return "num";
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/GlobalTrend.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class GlobalTrend {
    private String name;
    private String query;

    public GlobalTrend() {

    }

    GlobalTrend(JsonNode json) {
        name = json.get("name").asText();
        query = json.get("query").asText();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getQuery() {
        return query;
    }

    public void setQuery(String query) {
        this.query = query;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/GenderType.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.PlaceService;

/**
 * @author <NAME>
 */
public enum GenderType implements
        PlaceService.GetNearbyUsersListParam {
    All(0), Male(1), Female(2);
    private int value;

    GenderType(int value) {
        this.value = value;
    }

    public void addParameter(Parameters params) {
        params.add("gender", value);
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Phone.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.PlaceService;

/**
 * @author <NAME>
 */
public class Phone extends StringParam implements
        PlaceService.CreatePoiParam {

    public Phone(String value) {
        super(value);
    }

    protected String paramKey() {
        return "phone";
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Pic.java<|end_filename|>
package weiboclient4j.params;

public class Pic extends StringParam {
    public Pic(String value) {
        super(value);
    }

    protected String paramKey() {
        return "pic";
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParseFriendshipTest.java<|end_filename|>
package weiboclient4j.model;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import weiboclient4j.utils.JsonUtils;

/**
 * @author <NAME>
 */
public class ParseFriendshipTest extends AbstractParseJsonTest {
    @Test
    public void testParseFriendship() throws Exception {
        String content = readResource("/weiboclient4j/model/friendship.json");
        Friendship friendship = JsonUtils.readValue(content, Friendship.class);
        assertNotNull(friendship);
        assertTrue(friendship.getTarget().isFollowing());
    }
}


<|start_filename|>src/main/java/weiboclient4j/TrendService.java<|end_filename|>
package weiboclient4j;

import org.codehaus.jackson.JsonNode;
import weiboclient4j.model.GlobalTrendList;
import weiboclient4j.model.Trend;
import weiboclient4j.model.TrendStatus;
import weiboclient4j.params.BaseApp;
import weiboclient4j.params.Paging;
import weiboclient4j.params.TrendId;
import weiboclient4j.params.TrendName;
import weiboclient4j.params.Uid;

import java.util.List;

/**
 * @author <NAME>
 */
public class TrendService extends AbstractService {
    public TrendService(WeiboClient client) {
        super(client);
    }

    public List<Trend> getTrends(Uid uid, Paging paging) throws WeiboClientException {
        return doGet("trends",
                paging, withParams(uid), Trend.TYPE_TREND_LIST);
    }

    public TrendStatus getStatus(TrendName trendName) throws WeiboClientException {
        return doGet("trends/is_follow",
                withParams(trendName), TrendStatus.class);
    }

    public GlobalTrendList getHourly() throws WeiboClientException {
        return getHourly(BaseApp.No);
    }

    public GlobalTrendList getHourly(BaseApp baseApp) throws WeiboClientException {
        JsonNode json = doGet("trends/hourly",
                withParams(baseApp), JsonNode.class);

        return new GlobalTrendList(json);
    }

    public GlobalTrendList getDaily() throws WeiboClientException {
        return getDaily(BaseApp.No);
    }

    public GlobalTrendList getDaily(BaseApp baseApp) throws WeiboClientException {
        JsonNode json = doGet("trends/daily", withParams(baseApp), JsonNode.class);

        return new GlobalTrendList(json);
    }

    public GlobalTrendList getWeekly() throws WeiboClientException {
        return getWeekly(BaseApp.No);
    }

    public GlobalTrendList getWeekly(BaseApp baseApp) throws WeiboClientException {
        JsonNode json = doGet("trends/weekly", withParams(baseApp), JsonNode.class);

        return new GlobalTrendList(json);
    }

    public long follow(TrendName trendName) throws WeiboClientException {
        FollowTrendResponse response = doPost("trends/follow",
                withParams(trendName), FollowTrendResponse.class);

        return response.getTopicid();
    }

    public boolean destroy(TrendId trendId) throws WeiboClientException {
        ResultResponse response = doPost("trends/destroy",
                withParams(trendId), ResultResponse.class);

        return response.isResult();
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Domain.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public class Domain extends StringParam {
    public Domain(String value) {
        super(value);
    }

    protected String paramKey() {
        return "domain";
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/PoiCategory.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.type.TypeReference;

import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class PoiCategory {
    public static final TypeReference<List<PoiCategory>> POI_CATEGORY_LIST = new TypeReference<List<PoiCategory>>() {
    };

    private String id;
    private String name;
    private String pid;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPid() {
        return pid;
    }

    public void setPid(String pid) {
        this.pid = pid;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/Tag.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.type.TypeReference;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class Tag {
    public static final TypeReference<List<Tag>> TYPE_TAG_LIST = new TypeReference<List<Tag>>() {
    };

    private long id;
    private String tag;
    private int count;
    private int weight;

    public Tag() {
    }

    public Tag(long id, String tag) {
        this.id = id;
        this.tag = tag;
    }

    public static List<Tag> parseTags(JsonNode json) {
        assert json != null;
        assert json.isArray();

        List<Tag> tags = new ArrayList<Tag>();

        for (JsonNode tagNode : (ArrayNode) json) {
            tags.add(parseTag(tagNode));
        }

        return tags;
    }

    public static Tag parseTag(JsonNode tagNode) {
        Tag tag = new Tag();

        Iterator<String> fieldNames = tagNode.getFieldNames();
        while (fieldNames.hasNext()) {
            String fieldName = fieldNames.next();
            JsonNode fieldValue = tagNode.get(fieldName);
            if ("weight".equals(fieldName)) {
                tag.setWeight(fieldValue.asInt());
            } else {
                tag.setId(Long.parseLong(fieldName));
                tag.setTag(fieldValue.asText());
            }
        }

        return tag;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getValue() {
        return tag;
    }

    public String getTag() {
        return tag;
    }

    public void setTag(String tag) {
        this.tag = tag;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/UrlShort.java<|end_filename|>
package weiboclient4j.params;

import java.util.Collection;

/**
 * @author <NAME>
 */
public class UrlShort extends StringParam {

    public static final String URL_SHORT = "url_short";

    public UrlShort(String value) {
        super(value);
    }

    protected String paramKey() {
        return URL_SHORT;
    }

    public static ParameterAction urlShortParam(final Collection<UrlShort> urlList) {
        return new ParameterAction() {
            public void addParameter(Parameters params) {
                if (urlList != null && urlList.size() > 0) {
                    for (UrlShort urlShort : urlList) {
                        if (urlShort.isValid()) {
                            params.add(URL_SHORT, urlShort.getValue());
                        }
                    }
                }
            }
        };
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Scale.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.LocationService;

public class Scale extends BooleanParam implements
        LocationService.GetMapImageParam {

    public Scale(boolean value) {
        super(value);
    }

    protected String paramKey() {
        return "scale";
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Coordinate.java<|end_filename|>
package weiboclient4j.params;

public class Coordinate extends StringParam {
    private Longitude longitude;

    private Latitude latitude;

    public Coordinate(Longitude longitude, Latitude latitude) {
        super(formatCoordinate(longitude, latitude));

        this.longitude = longitude;
        this.latitude = latitude;
    }

    public Longitude getLongitude() {
        return longitude;
    }

    public Latitude getLatitude() {
        return latitude;
    }

    @Override
    public String toString() {
        return formatCoordinate(longitude, latitude);
    }

    @Override
    protected String paramKey() {
        return "coordinate";
    }

    private static String formatCoordinate(Longitude longitudeParam, Latitude latitudeParam) {
        return String.format("%f,%f", longitudeParam.getValue(), latitudeParam.getValue());
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Coordinates.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.LocationService;
import static weiboclient4j.utils.StringUtils.join;

public class Coordinates extends StringParam implements
        LocationService.GetMapImageParam,
        LocationService.SearchByAreaParam {

    public Coordinates(String value) {
        super(value);
    }

    public Coordinates(Coordinate... coordinates) {
        this(join(coordinates, "|"));
    }

    protected String paramKey() {
        return "coordinates";
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Mid.java<|end_filename|>
package weiboclient4j.params;

import static weiboclient4j.utils.StringUtils.join;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author <NAME>
 */
public class Mid extends StringParam {

    public static final String MID = "mid";

    public Mid(String value) {
        super(value);
    }

    protected String paramKey() {
        return MID;
    }

    public static ParameterAction midParam(final Collection<Mid> midList) {
        return new ParameterAction() {
            public void addParameter(Parameters params) {
                if (midList != null && midList.size() > 0) {
                    List<String> midStringList = new ArrayList<String>(midList.size());
                    for (Mid mid : midList) {
                        midStringList.add(mid.getValue());
                    }
                    params.add(MID, join(midStringList, ","));
                }
            }
        };
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/CommentParam.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public class CommentParam extends StringParam {
    public CommentParam(String value) {
        super(value);
    }

    protected String paramKey() {
        return "comment";
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/PoiCategoryFlag.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.PlaceService;

/**
 * @author <NAME>
 */
public enum PoiCategoryFlag implements
        PlaceService.GetPoiCategoriesParam {

    CurrentLevel(0), All(1);

    private int value;

    PoiCategoryFlag(int value) {
        this.value = value;
    }

    public void addParameter(Parameters params) {
        if (this != CurrentLevel) {
            params.add("flag", value);
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/ListId.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.StatusService;

/**
 * @author <NAME>
 */
public class ListId extends StringParam implements StatusService.UploadImageUrlParam {
    public ListId(String value) {
        super(value);
    }

    @Override
    protected String paramKey() {
        return "list_id";
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/SearchSuggestionStatusResult.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.type.TypeReference;

import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class SearchSuggestionStatusResult {
    public static final TypeReference<List<SearchSuggestionStatusResult>> TYPE_SEARCH_SUGGESTION_STATUS_RESULT_LIST =
            new TypeReference<List<SearchSuggestionStatusResult>>() {
            };

    private String suggestion;
    private int count;

    public String getSuggestion() {
        return suggestion;
    }

    public void setSuggestion(String suggestion) {
        this.suggestion = suggestion;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }
}


<|start_filename|>src/main/java/weiboclient4j/LocationService.java<|end_filename|>
package weiboclient4j;

import org.codehaus.jackson.JsonNode;
import weiboclient4j.model.DomesticResult;
import weiboclient4j.model.Geo;
import weiboclient4j.model.LocationPoiList;
import weiboclient4j.params.Address;
import weiboclient4j.params.Coordinate;
import weiboclient4j.params.Coordinates;
import weiboclient4j.params.Ip;
import weiboclient4j.params.Paging;
import weiboclient4j.params.ParameterAction;
import static weiboclient4j.utils.CollectionUtils.firstItem;

import java.util.List;

/**
 * @author <NAME>
 */
public class LocationService extends AbstractService {
    public LocationService(WeiboClient client) {
        super(client);
    }

    public <T extends GetMapImageParam> String getMapImage(T... params) throws WeiboClientException {
        return doGet("location/base/get_map_image", buildParams(params), GetMapImageResponse.class).getMapImage();
    }

    public List<Geo> ipToGeo(Ip ip) throws WeiboClientException {
        return doGet("location/geo/ip_to_geo", withParams(ip), GeoListResponse.class).getGeos();
    }

    public List<Geo> addressToGeo(Address address) throws WeiboClientException {
        return doGet("location/geo/address_to_geo", withParams(address), GeoListResponse.class).getGeos();
    }

    public Geo geoToAddress(Coordinate coordinate) throws WeiboClientException {
        return firstItem(doGet("location/geo/geo_to_address", withParams(coordinate), GeoListResponse.class).getGeos());
    }

    public Geo gpsToOffset(Coordinate coordinate) throws WeiboClientException {
        return firstItem(doGet("location/geo/gps_to_offset", withParams(coordinate), GeoListResponse.class).getGeos());
    }

    public List<DomesticResult> isDomestic(Coordinates coordinates) throws WeiboClientException {
        JsonNode json = doGet("location/geo/is_domestic", withParams(coordinates), JsonNode.class);

        return DomesticResult.parseList(json);
    }

    public <T extends SearchByLocationParam> LocationPoiList searchByLocation(Paging paging, T... params)
            throws WeiboClientException {
        return doGet("location/pois/search/by_location", paging, buildParams(params), LocationPoiList.class);
    }

    public <T extends SearchByLocationParam> LocationPoiList searchByLocation(T... params) throws WeiboClientException {
        return searchByLocation(Paging.EMPTY, params);
    }

    public <T extends SearchByAreaParam> LocationPoiList searchByArea(Paging paging, T... params)
            throws WeiboClientException {
        return doGet("location/pois/search/by_area", paging, buildParams(params), LocationPoiList.class);
    }

    public <T extends SearchByAreaParam> LocationPoiList searchByArea(T... params)
            throws WeiboClientException {
        return searchByArea(Paging.EMPTY, params);
    }

    public static interface SearchByAreaParam extends ParameterAction {
    }

    public static interface SearchByLocationParam extends ParameterAction {
    }

    public static interface GetMapImageParam extends ParameterAction {
    }

    private class GeoListResponse {
        private List<Geo> geos;

        private List<Geo> getGeos() {
            return geos;
        }

        private void setGeos(List<Geo> geos) {
            this.geos = geos;
        }
    }

    private class GetMapImageResponse {
        private MapImageItem[] map;

        public String getMapImage() {
            return map != null && map.length > 0 ? map[0].getImageUrl() : null;
        }

        private MapImageItem[] getMap() {
            return map;
        }

        private void setMap(MapImageItem[] map) {
            this.map = map;
        }
    }

    private class MapImageItem {
        private String imageUrl;

        private String getImageUrl() {
            return imageUrl;
        }

        private void setImageUrl(String imageUrl) {
            this.imageUrl = imageUrl;
        }
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParseTimelineIdsTest.java<|end_filename|>
package weiboclient4j.model;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import org.junit.Test;
import weiboclient4j.utils.JsonUtils;

/**
 * @author <NAME>
 */
public class ParseTimelineIdsTest extends AbstractParseJsonTest {
    @Test
    public void testParseTimelineIds() throws Exception {
        String content = readResource("/weiboclient4j/model/timeline_ids.json");
        TimelineIds ids = JsonUtils.readValue(content, TimelineIds.class);
        assertEquals("Total number", 16, ids.getTotalNumber());
        assertTrue("Contains id", ids.getStatuses().contains(3382905252160340L));
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/CapitalLetter.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public class CapitalLetter extends StringParam {
    public CapitalLetter(String value) {
        super(value);
    }

    protected String paramKey() {
        return "capital";
    }
}


<|start_filename|>src/main/java/weiboclient4j/oauth2/ResponseType.java<|end_filename|>
package weiboclient4j.oauth2;

/**
 * @author <NAME>
 */
public enum ResponseType {
    Code("code"), Token("token");

    private String type;

    ResponseType(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/TemplateId.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public class TemplateId extends LongParam {
    public TemplateId(long value) {
        super(value);
    }

    protected String paramKey() {
        return "tpl_id";
    }
}


<|start_filename|>src/main/java/weiboclient4j/oauth2/SinaWeibo2AccessTokenResponse.java<|end_filename|>
package weiboclient4j.oauth2;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class SinaWeibo2AccessTokenResponse {
    private String accessToken;
    private long expiresIn;
    private long remindIn;
    private long uid;
    private boolean realName;

    public String getAccessToken() {
        return accessToken;
    }

    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }

    public long getExpiresIn() {
        return expiresIn;
    }

    public void setExpiresIn(long expiresIn) {
        this.expiresIn = expiresIn;
    }

    public long getRemindIn() {
        return remindIn;
    }

    public void setRemindIn(long remindIn) {
        this.remindIn = remindIn;
    }

    public long getUid() {
        return uid;
    }

    public void setUid(long uid) {
        this.uid = uid;
    }

    public boolean isRealName() {
        return realName;
    }

    @JsonProperty("isRealName")
    public void setRealName(boolean realName) {
        this.realName = realName;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/LocRange.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.PlaceService;

/**
 * @author <NAME>
 */
public class LocRange extends LongParam implements
        PlaceService.GetNearbyUsersParam,
        PlaceService.GetNearbyPoisParam,
        PlaceService.GetNearbyPhotosParam,
        PlaceService.GetNearbyUsersListParam,
        PlaceService.GetNearbyTimelineParam {

    public LocRange(long value) {
        super(value);
    }

    protected String paramKey() {
        return "range";
    }
}


<|start_filename|>src/main/java/weiboclient4j/SearchService.java<|end_filename|>
package weiboclient4j;

import weiboclient4j.model.SearchSuggestionAppResult;
import weiboclient4j.model.SearchSuggestionAtUserResult;
import weiboclient4j.model.SearchSuggestionCompanyResult;
import weiboclient4j.model.SearchSuggestionSchoolResult;
import weiboclient4j.model.SearchSuggestionStatusResult;
import weiboclient4j.model.SearchSuggestionUserResult;
import weiboclient4j.model.Timeline;
import weiboclient4j.params.Paging;
import weiboclient4j.params.Query;
import weiboclient4j.params.SchoolType;
import weiboclient4j.params.SuggestionRange;
import weiboclient4j.params.SuggestionType;

import java.util.List;

/**
 * @author <NAME>
 */
public class SearchService extends AbstractService {
    public SearchService(WeiboClient client) {
        super(client);
    }

    public List<SearchSuggestionUserResult> searchSuggestionUsers(Query query) throws WeiboClientException {
        return searchSuggestionUsers(query, Paging.EMPTY);
    }

    public List<SearchSuggestionUserResult> searchSuggestionUsers(Query query, Paging paging)
            throws WeiboClientException {
        return doGet("search/suggestions/users",
                paging, withParams(query),
                SearchSuggestionUserResult.TYPE_SEARCH_SUGGESTION_USER_RESULT_LIST);
    }

    public List<SearchSuggestionStatusResult> searchSuggestionStatuses(Query query) throws WeiboClientException {
        return searchSuggestionStatuses(query, Paging.EMPTY);
    }

    public List<SearchSuggestionStatusResult> searchSuggestionStatuses(Query query, Paging paging)
            throws WeiboClientException {
        return doGet("search/suggestions/statuses",
                paging, withParams(query),
                SearchSuggestionStatusResult.TYPE_SEARCH_SUGGESTION_STATUS_RESULT_LIST);
    }

    public List<SearchSuggestionSchoolResult> searchSuggestionSchools(Query query) throws WeiboClientException {
        return searchSuggestionSchools(query, Paging.EMPTY);
    }

    public List<SearchSuggestionSchoolResult> searchSuggestionSchools(Query query, Paging paging)
            throws WeiboClientException {
        return searchSuggestionSchools(query, SchoolType.All, paging);
    }

    public List<SearchSuggestionSchoolResult> searchSuggestionSchools(Query query, SchoolType schoolType)
            throws WeiboClientException {
        return searchSuggestionSchools(query, schoolType, Paging.EMPTY);
    }

    public List<SearchSuggestionSchoolResult> searchSuggestionSchools(Query query, SchoolType schoolType, Paging paging)
            throws WeiboClientException {
        return doGet("search/suggestions/schools",
                paging, withParams(query, schoolType),
                SearchSuggestionSchoolResult.TYPE_SEARCH_SUGGESTION_SCHOOL_RESULT_LIST);
    }

    public List<SearchSuggestionCompanyResult> searchSuggestionCompanies(Query query) throws WeiboClientException {
        return searchSuggestionCompanies(query, Paging.EMPTY);
    }

    public List<SearchSuggestionCompanyResult> searchSuggestionCompanies(Query query, Paging paging)
            throws WeiboClientException {
        return doGet("search/suggestions/companies",
                paging, withParams(query),
                SearchSuggestionCompanyResult.TYPE_SEARCH_SUGGESTION_COMPANY_RESULT_LIST);
    }

    public List<SearchSuggestionAppResult> searchSuggestionApps(Query query) throws WeiboClientException {
        return searchSuggestionApps(query, Paging.EMPTY);
    }

    public List<SearchSuggestionAppResult> searchSuggestionApps(Query query, Paging paging)
            throws WeiboClientException {
        return doGet("search/suggestions/apps",
                paging, withParams(query),
                SearchSuggestionAppResult.TYPE_SEARCH_SUGGESTION_APP_RESULT_LIST);
    }

    public List<SearchSuggestionAtUserResult> searchSuggestionAtUsers(Query query, SuggestionType type)
            throws WeiboClientException {
        return searchSuggestionAtUsers(query, type, SuggestionRange.All);
    }

    public List<SearchSuggestionAtUserResult> searchSuggestionAtUsers(Query query, SuggestionType type, Paging paging)
            throws WeiboClientException {
        return searchSuggestionAtUsers(query, type, SuggestionRange.All, paging);
    }

    public List<SearchSuggestionAtUserResult> searchSuggestionAtUsers(Query query, SuggestionType type,
                                                                      SuggestionRange range)
            throws WeiboClientException {
        return searchSuggestionAtUsers(query, type, range, Paging.EMPTY);
    }

    public List<SearchSuggestionAtUserResult> searchSuggestionAtUsers(Query query, SuggestionType type,
                                                                      SuggestionRange range, Paging paging)
            throws WeiboClientException {
        return doGet("search/suggestions/at_users",
                paging, withParams(query, type, range),
                SearchSuggestionAtUserResult.TYPE_SEARCH_SUGGESTION_AT_USER_RESULT_LIST);
    }

    public Timeline searchTopics(Query query) throws WeiboClientException {
        return searchTopics(query, Paging.EMPTY);
    }

    public Timeline searchTopics(Query query, Paging paging) throws WeiboClientException {
        return doGet("search/topics",
                paging, withParams(query), Timeline.class);
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/DomesticResult.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.JsonNode;

import java.util.ArrayList;
import java.util.List;

public class DomesticResult {

    private static final int MAX_RESULTS = 50;

    private boolean domestic;

    private String address;

    /**
     * json format:
     *
     * <pre>
     * {
     *   "g1": {
     *     "type": 1,
     *     "address": "台湾"
     *   },
     *   "g2": {
     *     "type": 1,
     *     "address": "河北省 衡水市 武强县"
     *   },
     *   "g3": {
     *     "type": 0,
     *     "address": ""
     *   }
     * }
     * </pre>
     *
     * @param json response json string
     * @return list of DomesticResult
     */
    public static List<DomesticResult> parseList(JsonNode json) {
        List<DomesticResult> results = new ArrayList<DomesticResult>();

        for (int i = 1; i <= MAX_RESULTS; i++) {
            String itemFieldName = String.format("g%d", i);

            if (json.has(itemFieldName)) {
                results.add(parseItem(json.get(itemFieldName)));
            } else {
                break;
            }
        }

        return results;
    }

    public boolean isDomestic() {
        return domestic;
    }

    public void setDomestic(boolean domestic) {
        this.domestic = domestic;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    private static DomesticResult parseItem(JsonNode itemNode) {
        DomesticResult result = new DomesticResult();

        result.setDomestic(itemNode.get("type").asInt() == 1);
        result.setAddress(itemNode.get("address").asText());

        return result;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/Url.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.type.TypeReference;

import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class Url {
    public static final TypeReference<List<Url>> TYPE_URL_LIST = new TypeReference<List<Url>>() {
    };

    private int type;
    private String urlShort;
    private String urlLong;
    private boolean result;
    private int clicks;
    private int shareCounts;
    private int commentCounts;
    private List<UrlReferer> referers;
    private List<UrlLocation> locations;
    private List<Status> shareStatuses;
    private List<Comment> shareComments;

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public String getUrlShort() {
        return urlShort;
    }

    public void setUrlShort(String urlShort) {
        this.urlShort = urlShort;
    }

    public String getUrlLong() {
        return urlLong;
    }

    public void setUrlLong(String urlLong) {
        this.urlLong = urlLong;
    }

    public boolean isResult() {
        return result;
    }

    public void setResult(boolean result) {
        this.result = result;
    }

    public int getClicks() {
        return clicks;
    }

    public void setClicks(int clicks) {
        this.clicks = clicks;
    }

    public int getShareCounts() {
        return shareCounts;
    }

    public void setShareCounts(int shareCounts) {
        this.shareCounts = shareCounts;
    }

    public int getCommentCounts() {
        return commentCounts;
    }

    public void setCommentCounts(int commentCounts) {
        this.commentCounts = commentCounts;
    }

    public List<UrlReferer> getReferers() {
        return referers;
    }

    public void setReferers(List<UrlReferer> referers) {
        this.referers = referers;
    }

    public List<UrlLocation> getLocations() {
        return locations;
    }

    public void setLocations(List<UrlLocation> locations) {
        this.locations = locations;
    }

    public List<Status> getShareStatuses() {
        return shareStatuses;
    }

    public void setShareStatuses(List<Status> shareStatuses) {
        this.shareStatuses = shareStatuses;
    }

    public List<Comment> getShareComments() {
        return shareComments;
    }

    public void setShareComments(List<Comment> shareComments) {
        this.shareComments = shareComments;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/SuggestionUser.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

import java.util.ArrayList;
import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class SuggestionUser {
    private Long uid;

    private List<Reason> reasonList;

    public static List<SuggestionUser> convertFromRawSuggestionUserList(List<RawSuggestionUser> rawSuggestionUsers) {
        ArrayList<SuggestionUser> result = new ArrayList<SuggestionUser>();

        for (RawSuggestionUser rawSuggestionUser : rawSuggestionUsers) {
            result.add(convertFromRawSuggestionUser(rawSuggestionUser));
        }

        return result;
    }

    public Long getUid() {
        return uid;
    }

    public void setUid(Long uid) {
        this.uid = uid;
    }

    public List<Reason> getReasonList() {
        return reasonList;
    }

    public void setReasonList(List<Reason> reasonList) {
        this.reasonList = reasonList;
    }

    private static SuggestionUser convertFromRawSuggestionUser(RawSuggestionUser rawSuggestionUser) {
        SuggestionUser suggestionUser = new SuggestionUser();

        suggestionUser.setUid(rawSuggestionUser.getUid());
        RawSuggestionUser.Reason rawReason = rawSuggestionUser.getReason();
        List<Reason> reasonList = new ArrayList<Reason>();

        if (rawReason.getC() != null) {
            reasonList.add(new Reason(rawReason.getC(), ReasonType.C));
        }

        if (rawReason.getF() != null) {
            reasonList.add(new Reason(rawReason.getF(), ReasonType.F));
        }

        if (rawReason.getH() != null) {
            reasonList.add(new Reason(rawReason.getH(), ReasonType.H));
        }

        if (rawReason.getS() != null) {
            reasonList.add(new Reason(rawReason.getS(), ReasonType.S));
        }

        if (rawReason.getT() != null) {
            reasonList.add(new Reason(rawReason.getT(), ReasonType.T));
        }

        suggestionUser.setReasonList(reasonList);

        return suggestionUser;
    }

    public enum ReasonType {
        F, H, S, C, T
    }

    public static class Reason {
        private String name;

        private ReasonType type;

        private List<Long> uidList;

        private int numOfRelationship;

        public Reason(RawSuggestionUser.Reason.Item item, ReasonType reasonType) {
            setName(item.getName());
            setType(reasonType);
            setUidList(uidList);
            setNumOfRelationship(item.getN());
        }

        public ReasonType getType() {
            return type;
        }

        public void setType(ReasonType type) {
            this.type = type;
        }

        public int getNumOfRelationship() {
            return numOfRelationship;
        }

        public void setNumOfRelationship(int numOfRelationship) {
            this.numOfRelationship = numOfRelationship;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public List<Long> getUidList() {
            return uidList;
        }

        public void setUidList(List<Long> uidList) {
            this.uidList = uidList;
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/SuggestionRange.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public enum SuggestionRange implements ParameterAction {
    Name(0), Remark(1), All(2);

    private int value;

    SuggestionRange(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void addParameter(Parameters params) {
        if (this != All) {
            params.add("range", getValue());
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/CommentList.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;

import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class CommentList {
    private List<Comment> comments;
    private long previousCursor;
    private long nextCursor;
    private int totalNumber;
    @JsonProperty("hasvisible")
    private boolean visible;

    public List<Comment> getComments() {
        return comments;
    }

    public void setComments(List<Comment> comments) {
        this.comments = comments;
    }

    public long getPreviousCursor() {
        return previousCursor;
    }

    public void setPreviousCursor(long previousCursor) {
        this.previousCursor = previousCursor;
    }

    public long getNextCursor() {
        return nextCursor;
    }

    public void setNextCursor(long nextCursor) {
        this.nextCursor = nextCursor;
    }

    public int getTotalNumber() {
        return totalNumber;
    }

    public void setTotalNumber(int totalNumber) {
        this.totalNumber = totalNumber;
    }

    public boolean isVisible() {
        return visible;
    }

    public void setVisible(boolean visible) {
        this.visible = visible;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/Poi.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import weiboclient4j.utils.SimpleDateDeserializer;

import java.util.Date;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class Poi {
    private String poiid;
    private String title;
    private String address;
    private double lon;
    private double lat;
    private String category;
    private String city;
    private String province;
    private String country;
    private String url;
    private String phone;
    private String postcode;
    private String weiboId;
    private String icon;
    private String extra;
    private String rid;
    private String categorys;
    private String categoryName;
    private int checkinNum;
    private int checkinUserNum;
    @JsonDeserialize(using = SimpleDateDeserializer.class)
    private Date checkinTime;
    private int tipNum;
    private int photoNum;
    private int todoNum;

    public String getPoiid() {
        return poiid;
    }

    public void setPoiid(String poiid) {
        this.poiid = poiid;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public double getLon() {
        return lon;
    }

    public void setLon(double lon) {
        this.lon = lon;
    }

    public double getLat() {
        return lat;
    }

    public void setLat(double lat) {
        this.lat = lat;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getPostcode() {
        return postcode;
    }

    public void setPostcode(String postcode) {
        this.postcode = postcode;
    }

    public String getWeiboId() {
        return weiboId;
    }

    public void setWeiboId(String weiboId) {
        this.weiboId = weiboId;
    }

    public String getIcon() {
        return icon;
    }

    public void setIcon(String icon) {
        this.icon = icon;
    }

    public String getExtra() {
        return extra;
    }

    public void setExtra(String extra) {
        this.extra = extra;
    }

    public String getRid() {
        return rid;
    }

    public void setRid(String rid) {
        this.rid = rid;
    }

    public String getCategorys() {
        return categorys;
    }

    public void setCategorys(String categorys) {
        this.categorys = categorys;
    }

    public String getCategoryName() {
        return categoryName;
    }

    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }

    public int getCheckinUserNum() {
        return checkinUserNum;
    }

    public void setCheckinUserNum(int checkinUserNum) {
        this.checkinUserNum = checkinUserNum;
    }

    public Date getCheckinTime() {
        return checkinTime;
    }

    public void setCheckinTime(Date checkinTime) {
        this.checkinTime = checkinTime;
    }

    public int getCheckinNum() {
        return checkinNum;
    }

    public void setCheckinNum(int checkinNum) {
        this.checkinNum = checkinNum;
    }

    public int getTipNum() {
        return tipNum;
    }

    public void setTipNum(int tipNum) {
        this.tipNum = tipNum;
    }

    public int getPhotoNum() {
        return photoNum;
    }

    public void setPhotoNum(int photoNum) {
        this.photoNum = photoNum;
    }

    public int getTodoNum() {
        return todoNum;
    }

    public void setTodoNum(int todoNum) {
        this.todoNum = todoNum;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/FilterBySource.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.StatusService;

import java.util.HashMap;
import java.util.Map;

/**
 * @author <NAME>
 */
public enum FilterBySource implements
        StatusService.GetMentionsParam,
        StatusService.GetMentionsIdsParam {

    All(0), FromWeibo(1), FromWeiqun(2);

    private static Map<Integer, FilterBySource> map = new HashMap<Integer, FilterBySource>();

    static {
        for (FilterBySource filterBySource : FilterBySource.values()) {
            map.put(filterBySource.getValue(), filterBySource);
        }
    }

    private int value;

    FilterBySource(int value) {
        this.value = value;
    }

    public static FilterBySource fromValue(int value) {
        return map.get(value);
    }

    public int getValue() {
        return value;
    }

    public void addParameter(Parameters params) {
        if (this != All) {
            params.add("filter_by_source", getValue());
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/RateLimitStatus.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import weiboclient4j.utils.SimpleDateDeserializer;

import java.util.Date;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class RateLimitStatus {
    private int ipLimit;
    private String limitTimeUnit;
    private int remainingIpHits;
    private int remainingUserHits;
    @JsonDeserialize(using = SimpleDateDeserializer.class)
    private Date resetTime;
    private int resetTimeInSeconds;
    private int userLimit;

    public int getIpLimit() {
        return ipLimit;
    }

    public void setIpLimit(int ipLimit) {
        this.ipLimit = ipLimit;
    }

    public String getLimitTimeUnit() {
        return limitTimeUnit;
    }

    public void setLimitTimeUnit(String limitTimeUnit) {
        this.limitTimeUnit = limitTimeUnit;
    }

    public int getRemainingIpHits() {
        return remainingIpHits;
    }

    public void setRemainingIpHits(int remainingIpHits) {
        this.remainingIpHits = remainingIpHits;
    }

    public int getRemainingUserHits() {
        return remainingUserHits;
    }

    public void setRemainingUserHits(int remainingUserHits) {
        this.remainingUserHits = remainingUserHits;
    }

    public Date getResetTime() {
        return resetTime;
    }

    public void setResetTime(Date resetTime) {
        this.resetTime = resetTime;
    }

    public int getResetTimeInSeconds() {
        return resetTimeInSeconds;
    }

    public void setResetTimeInSeconds(int resetTimeInSeconds) {
        this.resetTimeInSeconds = resetTimeInSeconds;
    }

    public int getUserLimit() {
        return userLimit;
    }

    public void setUserLimit(int userLimit) {
        this.userLimit = userLimit;
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParseGlobalTrendListTest.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.JsonNode;
import org.junit.Test;
import static weiboclient4j.utils.JsonUtils.readValue;

/**
 * @author <NAME>
 */
public class ParseGlobalTrendListTest extends AbstractParseJsonTest {
    @Test
    public void testParseGlobalTrendList() throws Exception {
        String content = readResource("/weiboclient4j/model/global_trend_list.json");

        new GlobalTrendList(readValue(content, JsonNode.class));
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Lines.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.LocationService;

public class Lines extends StringParam implements
        LocationService.GetMapImageParam {

    public Lines(String value) {
        super(value);
    }

    protected String paramKey() {
        return "lines";
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Country.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.PlaceService;

/**
 * @author <NAME>
 */
public class Country extends StringParam implements
        PlaceService.CreatePoiParam {

    public Country(String value) {
        super(value);
    }

    protected String paramKey() {
        return "country";
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Size.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.LocationService;

public class Size extends StringParam implements
        LocationService.GetMapImageParam {

    public Size(String value) {
        super(value);
    }

    public Size(int width, int height) {
        this(String.format("%dx%d", width, height));
    }

    protected String paramKey() {
        return "size";
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParseRawSuggestionUserTest.java<|end_filename|>
package weiboclient4j.model;

import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import org.junit.Test;
import static org.junit.matchers.JUnitMatchers.hasItem;
import weiboclient4j.utils.JsonUtils;

import java.util.List;

/**
 * @author <NAME>
 */
public class ParseRawSuggestionUserTest extends AbstractParseJsonTest {

    public static final long FIRST_UID = 1581362064L;

    @Test
    public void testParseSuggestionUser() throws Exception {
        String content = readResource("/weiboclient4j/model/suggestions_users_may_interested.json");

        List<RawSuggestionUser> rawSuggestionUserList = JsonUtils.readValue(content, RawSuggestionUser.TYPE_SUGGESTION_USER_LIST);

        assertThat(rawSuggestionUserList.size(), is(10));

        RawSuggestionUser rawUser0 = rawSuggestionUserList.get(0);
        assertThat(rawUser0.getUid(), is(FIRST_UID));

        RawSuggestionUser.Reason.Item item0 = rawUser0.getReason().getF();
        assertThat("item0.getN()", item0.getN(), is(2));
        assertThat(item0.getUid(), hasItem(1919667517L));
        assertThat(item0.getUid(), hasItem(1710369261L));

        List<SuggestionUser> suggestionUsers = SuggestionUser.convertFromRawSuggestionUserList(rawSuggestionUserList);
        assertThat(suggestionUsers, is(notNullValue()));

        SuggestionUser user0 = suggestionUsers.get(0);
        assertThat(user0.getUid(), is(FIRST_UID));
        assertThat(user0.getReasonList().size(), is(1));

        SuggestionUser.Reason reason0ForUser0 = user0.getReasonList().get(0);
        assertThat(reason0ForUser0.getType(), is(SuggestionUser.ReasonType.F));
        assertThat("reason0ForUser0.getNumOfRelationship()", reason0ForUser0.getNumOfRelationship(), is(2));

        SuggestionUser user6 = suggestionUsers.get(6);
        assertThat(user6.getReasonList().size(), is(2));
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/PoiSortType.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.PlaceService;

/**
 * @author <NAME>
 */
public enum PoiSortType implements
        PlaceService.GetPoiPhotosParam,
        PlaceService.GetPoiTipsParam {

    Time(0), Hot(1);

    private int value;

    PoiSortType(int value) {
        this.value = value;
    }

    public void addParameter(Parameters params) {
        if (this != Time) {
            params.add("sort", value);
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/FavoriteService.java<|end_filename|>
package weiboclient4j;

import weiboclient4j.model.Favorites;
import weiboclient4j.model.FavoritesIds;
import weiboclient4j.model.FavoritesItem;
import weiboclient4j.model.FavoritesTags;
import weiboclient4j.model.Tag;
import weiboclient4j.params.Id;
import weiboclient4j.params.Paging;
import weiboclient4j.params.TagName;
import weiboclient4j.params.Tid;

import java.util.Collection;

/**
 * @author <NAME>
 */
public class FavoriteService extends AbstractService {
    public FavoriteService(WeiboClient client) {
        super(client);
    }

    public Favorites getFavorites() throws WeiboClientException {
        return getFavorites(Paging.EMPTY);
    }

    public Favorites getFavorites(Paging paging) throws WeiboClientException {
        return doGet("favorites", paging, Favorites.class);
    }

    public FavoritesIds getIds() throws WeiboClientException {
        return getIds(Paging.EMPTY);
    }

    public FavoritesIds getIds(Paging paging) throws WeiboClientException {
        return doGet("favorites/ids", paging, FavoritesIds.class);
    }

    public FavoritesItem show(Id id) throws WeiboClientException {
        return doGet("favorites/show", withParams(id), FavoritesItem.class);
    }

    public Favorites getFavoritesByTags(Tid tid) throws WeiboClientException {
        return getFavoritesByTags(tid, Paging.EMPTY);
    }

    public Favorites getFavoritesByTags(Tid tid, Paging paging) throws WeiboClientException {
        return doGet("favorites/by_tags", paging, withParams(tid), Favorites.class);
    }

    public FavoritesTags getTags() throws WeiboClientException {
        return getTags(Paging.EMPTY);
    }

    public FavoritesTags getTags(Paging paging) throws WeiboClientException {
        return doGet("favorites/tags", paging, FavoritesTags.class);
    }

    public FavoritesIds getIdsByTags(Tid tid) throws WeiboClientException {
        return getIdsByTags(tid, Paging.EMPTY);
    }

    public FavoritesIds getIdsByTags(Tid tid, Paging paging) throws WeiboClientException {
        return doGet("favorites/by_tags/ids", paging, withParams(tid), FavoritesIds.class);
    }

    public FavoritesItem create(Id id) throws WeiboClientException {
        return doPost("favorites/create", withParams(id), FavoritesItem.class);
    }

    public FavoritesItem destroy(Id id) throws WeiboClientException {
        return doPost("favorites/destroy", withParams(id), FavoritesItem.class);
    }

    public boolean destroyBatch(Collection<Id> ids) throws WeiboClientException {
        ResultResponse response = doPost("favorites/destroy_batch",
                withParams(Id.idsParam(ids)), ResultResponse.class);

        return response.isResult();
    }

    public FavoritesItem updateTags(Id id) throws WeiboClientException {
        return updateTags(id, null);
    }

    public FavoritesItem updateTags(Id id, Collection<TagName> tags) throws WeiboClientException {
        return doPost("favorites/tags/update",
                withParams(id, TagName.tagsParam(tags)), FavoritesItem.class);
    }

    public Tag updateTagsBatch(Tid tid, TagName tagName) throws WeiboClientException {
        return doPost("favorites/tags/update_batch",
                withParams(tid, tagName), Tag.class);
    }

    public boolean destroyTagsBatch(Tid tid) throws WeiboClientException {
        ResultResponse response = doPost("favorites/tags/destroy_batch",
                withParams(tid), ResultResponse.class);
        return response.isResult();
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParseEmotionTest.java<|end_filename|>
package weiboclient4j.model;

import org.junit.Test;
import static weiboclient4j.utils.JsonUtils.parseJsonObject;

/**
 * @author <NAME>
 */
public class ParseEmotionTest extends AbstractParseJsonTest {
    @Test
    public void testParseEmotions() throws Exception {
        String content = readResource("/weiboclient4j/model/emotions.json");

        parseJsonObject(content, Emotion.TYPE_EMOTION_LIST);
    }
}


<|start_filename|>src/test/resources/weiboclient4j/model/friendship.json<|end_filename|>
{
  "target":{
    "id":1418348195,
    "screen_name":"zaku",
    "followed_by":false,
    "following":true,
    "notifications_enabled":false
  },
  "source":{
    "id":1734528095,
    "screen_name":"檀木幻想",
    "followed_by":false,
    "following":false,
    "notifications_enabled":false
  }
}


<|start_filename|>src/main/java/weiboclient4j/params/AddressCode.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.utils.StringUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author <NAME>
 */
public class AddressCode extends StringParam {
    public AddressCode(String value) {
        super(value);
    }

    protected String paramKey() {
        throw new UnsupportedOperationException("paramKey not supported yet");
    }

    public static ParameterAction codesParam(final Collection<AddressCode> codes) {
        return new ParameterAction() {
            public void addParameter(Parameters params) {
                if (codes != null && codes.size() > 0) {
                    List<String> codeList = new ArrayList<String>(codes.size());
                    for (AddressCode code : codes) {
                        codeList.add(code.getValue());
                    }
                    params.add("codes", StringUtils.join(codeList, ","));
                }
            }
        };
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParseVerifyNicknameResultTest.java<|end_filename|>
package weiboclient4j.model;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import weiboclient4j.utils.JsonUtils;

/**
 * @author <NAME>
 */
public class ParseVerifyNicknameResultTest extends AbstractParseJsonTest {
    @Test
    public void testParseVerifyNicknameResult() throws Exception {
        String content = readResource("/weiboclient4j/model/verify_nickname_result.json");

        VerifyNicknameResult response = JsonUtils.readValue(content, VerifyNicknameResult.class);
        assertNotNull(response);
        assertTrue(response.isLegal());
        assertTrue(response.getSuggestNickname().contains("nick001"));
    }
}


<|start_filename|>src/test/resources/weiboclient4j/model/empty_repost_timeline.json<|end_filename|>
{
  "reposts": [],
  "hasvisible": false,
  "previous_cursor": 0,
  "next_cursor": 0,
  "total_number": 0
}


<|start_filename|>src/main/java/weiboclient4j/model/RepostTimeline.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;

import java.util.ArrayList;
import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class RepostTimeline {
    public static final RepostTimeline EMPTY = new RepostTimeline() {
        {
            setReposts(new ArrayList<Status>());
        }
    };

    @JsonProperty("hasvisible")
    private boolean visible;
    private long previousCursor;
    private long nextCursor;
    private int totalNumber;
    private List<Status> reposts;

    public boolean isVisible() {
        return visible;
    }

    public void setVisible(boolean visible) {
        this.visible = visible;
    }

    public long getPreviousCursor() {
        return previousCursor;
    }

    public void setPreviousCursor(long previousCursor) {
        this.previousCursor = previousCursor;
    }

    public long getNextCursor() {
        return nextCursor;
    }

    public void setNextCursor(long nextCursor) {
        this.nextCursor = nextCursor;
    }

    public int getTotalNumber() {
        return totalNumber;
    }

    public void setTotalNumber(int totalNumber) {
        this.totalNumber = totalNumber;
    }

    public List<Status> getReposts() {
        return reposts;
    }

    public void setReposts(List<Status> reposts) {
        this.reposts = reposts;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/StatusIdList.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class StatusIdList {
    private List<Long> statuses;
    private long totalNumber;

    public List<Long> getStatuses() {
        return statuses;
    }

    public void setStatuses(List<Long> statuses) {
        this.statuses = statuses;
    }

    public long getTotalNumber() {
        return totalNumber;
    }

    public void setTotalNumber(long totalNumber) {
        this.totalNumber = totalNumber;
    }
}


<|start_filename|>src/main/java/weiboclient4j/oauth2/SinaWeibo2AccessToken.java<|end_filename|>
package weiboclient4j.oauth2;

import org.scribe.model.Token;

/**
 * @author <NAME>
 */
public class SinaWeibo2AccessToken extends Token {
    private long expiresIn;
    private long remindIn;
    private long uid;

    public SinaWeibo2AccessToken(String token, String secret) {
        super(token, secret);
    }

    public SinaWeibo2AccessToken(String token) {
        this(token, "");
    }

    public SinaWeibo2AccessToken(SinaWeibo2AccessTokenResponse response) {
        this(response.getAccessToken(), "");

        expiresIn = response.getExpiresIn();
        remindIn = response.getRemindIn();
        uid = response.getUid();
    }

    public long getExpiresIn() {
        return expiresIn;
    }

    public long getRemindIn() {
        return remindIn;
    }

    public long getUid() {
        return uid;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/SourceScreenName.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public class SourceScreenName extends StringParam {
    public static final SourceScreenName EMPTY = new SourceScreenName(null);

    public SourceScreenName(String value) {
        super(value);
    }

    protected String paramKey() {
        return "source_screen_name";
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/SchoolType.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public enum SchoolType implements ParameterAction {
    All(0), University(1), SeniorHighSchool(2), TechnicalSecondarySchool(3), JuniorHighSchool(4), PrimarySchool(5);

    private int value;

    SchoolType(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void addParameter(Parameters params) {
        if (this != All) {
            params.add("type", getValue());
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/UserService.java<|end_filename|>
package weiboclient4j;

import weiboclient4j.model.User;
import weiboclient4j.model.UserCount;
import weiboclient4j.params.Domain;
import weiboclient4j.params.ScreenName;
import weiboclient4j.params.Uid;

import java.util.Collection;
import java.util.List;

/**
 * @author <NAME>
 */
public class UserService extends AbstractService {

    public UserService(WeiboClient client) {
        super(client);
    }

    public User show(ScreenName screenName) throws WeiboClientException {
        return show(Uid.EMPTY, screenName);
    }

    public User show(Uid uid) throws WeiboClientException {
        return show(uid, ScreenName.EMPTY);
    }

    private User show(Uid uid, ScreenName screenName) throws WeiboClientException {
        return doGet("users/show", withParams(uid, screenName), User.class);
    }

    public User showByDomain(Domain domain) throws WeiboClientException {
        return doGet("users/domain_show", withParams(domain), User.class);
    }

    public User showByDomain(String domain) throws WeiboClientException {
        return showByDomain(new Domain(domain));
    }

    public List<UserCount> getCounts(Collection<Uid> uids) throws WeiboClientException {
        return doGet("users/counts", withParams(Uid.uidsParam(uids)), UserCount.LIST_TYPE);
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParsePoiCategoryListTest.java<|end_filename|>
package weiboclient4j.model;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
import org.junit.Test;
import weiboclient4j.utils.JsonUtils;

import java.util.List;

/**
 * @author <NAME>
 */
public class ParsePoiCategoryListTest extends AbstractParseJsonTest {
    @Test
    public void parsePoiCategoryList() throws Exception {
        String content = readResource("/weiboclient4j/model/poi_category_list.json");
        List<PoiCategory> categories = JsonUtils.readValue(content, PoiCategory.POI_CATEGORY_LIST);

        assertThat(categories, is(notNullValue()));
        assertThat(categories.size(), is(9));

        PoiCategory category = categories.get(4);
        assertThat(category.getId(), is("115"));
    }
}


<|start_filename|>src/main/java/weiboclient4j/utils/SimpleDateDeserializer.java<|end_filename|>
package weiboclient4j.utils;

import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.deser.std.DateDeserializer;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author <NAME>
 */
public class SimpleDateDeserializer extends DateDeserializer {

    public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    protected Date _parseDate(JsonParser jp, DeserializationContext ctxt) throws IOException {
        try {
            return DATE_FORMAT.parse(jp.getText());
        } catch (ParseException e) {
            throw new JsonParseException(e.getMessage(), jp.getCurrentLocation());
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/TrendId.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public class TrendId extends LongParam {
    public TrendId(long value) {
        super(value);
    }

    protected String paramKey() {
        return "trend_id";
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/SuggestionType.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public enum SuggestionType implements ParameterAction {
    Friends(0), Followers(1);

    private int value;

    SuggestionType(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void addParameter(Parameters params) {
        params.add("type", getValue());
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/CreatePoiResponse.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class CreatePoiResponse {
    private int status;
    private String poiid;

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public String getPoiid() {
        return poiid;
    }

    public void setPoiid(String poiid) {
        this.poiid = poiid;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/UploadedPic.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class UploadedPic {
    private String picId;
    private String thumbnailPic;
    private String bmiddlePic;
    private String originalPic;

    public String getPicId() {
        return picId;
    }

    public void setPicId(String picId) {
        this.picId = picId;
    }

    public String getThumbnailPic() {
        return thumbnailPic;
    }

    public void setThumbnailPic(String thumbnailPic) {
        this.thumbnailPic = thumbnailPic;
    }

    public String getBmiddlePic() {
        return bmiddlePic;
    }

    public void setBmiddlePic(String bmiddlePic) {
        this.bmiddlePic = bmiddlePic;
    }

    public String getOriginalPic() {
        return originalPic;
    }

    public void setOriginalPic(String originalPic) {
        this.originalPic = originalPic;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/MidType.java<|end_filename|>
package weiboclient4j.params;

import java.util.HashMap;
import java.util.Map;

/**
 * @author <NAME>
 */
public enum MidType implements ParameterAction {
    Status(1), Comment(2), Message(3);

    private static Map<Integer, MidType> map = new HashMap<Integer, MidType>();

    static {
        for (MidType midType : MidType.values()) {
            map.put(midType.getValue(), midType);
        }
    }

    private int value;

    MidType(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public static MidType fromValue(int value) {
        return map.get(value);
    }

    public void addParameter(Parameters params) {
        params.add("type", getValue());
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/ActionUrl.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public class ActionUrl extends StringParam {
    public static final ActionUrl EMPTY = new ActionUrl(null);

    public ActionUrl(String value) {
        super(value);
    }

    protected String paramKey() {
        return "action_url";
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/UserLBS.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserLBS {
    private long uid;
    private int checkinNum;
    private int tipNum;
    private int photoNum;
    private int todoNum;
    private int geoStatusesNum;

    public long getUid() {
        return uid;
    }

    public void setUid(long uid) {
        this.uid = uid;
    }

    public int getCheckinNum() {
        return checkinNum;
    }

    public void setCheckinNum(int checkinNum) {
        this.checkinNum = checkinNum;
    }

    public int getTipNum() {
        return tipNum;
    }

    public void setTipNum(int tipNum) {
        this.tipNum = tipNum;
    }

    public int getPhotoNum() {
        return photoNum;
    }

    public void setPhotoNum(int photoNum) {
        this.photoNum = photoNum;
    }

    public int getTodoNum() {
        return todoNum;
    }

    public void setTodoNum(int todoNum) {
        this.todoNum = todoNum;
    }

    public int getGeoStatusesNum() {
        return geoStatusesNum;
    }

    public void setGeoStatusesNum(int geoStatusesNum) {
        this.geoStatusesNum = geoStatusesNum;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/VerifyNicknameResult.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;

import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class VerifyNicknameResult {
    @JsonProperty("is_legal")
    private boolean legal;

    private List<String> suggestNickname;

    public boolean isLegal() {
        return legal;
    }

    public void setLegal(boolean legal) {
        this.legal = legal;
    }

    public List<String> getSuggestNickname() {
        return suggestNickname;
    }

    public void setSuggestNickname(List<String> suggestNickname) {
        this.suggestNickname = suggestNickname;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/SenderApp.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class SenderApp {
    private String appkey62;

    public String getAppkey62() {
        return appkey62;
    }

    public void setAppkey62(String appkey62) {
        this.appkey62 = appkey62;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/Friendship.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class Friendship {
    private FriendshipInfo target;
    private FriendshipInfo source;

    public FriendshipInfo getTarget() {
        return target;
    }

    public void setTarget(FriendshipInfo target) {
        this.target = target;
    }

    public FriendshipInfo getSource() {
        return source;
    }

    public void setSource(FriendshipInfo source) {
        this.source = source;
    }
}


<|start_filename|>src/main/java/weiboclient4j/oauth2/GrantType.java<|end_filename|>
package weiboclient4j.oauth2;

/**
 * @author <NAME>
 */
public enum GrantType {
    AuthorizationCode("authorization_code"), Password("password"), RefreshToken("refresh_token");

    private String type;

    GrantType(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Longitude.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.StatusService;

/**
 * @author <NAME>
 */
public class Longitude extends FloatParam implements StatusService.UploadImageUrlParam {
    public Longitude(float value) {
        super(value);
    }

    protected String paramKey() {
        return "long";
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/LocSortType.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.PlaceService;

/**
 * @author <NAME>
 */
public enum LocSortType implements
        PlaceService.GetNearbyPhotosParam,
        PlaceService.GetNearbyUsersListParam,
        PlaceService.GetNearbyTimelineParam {

    Time(0), Dis(1), SocialRelationship(2);

    private int value;

    LocSortType(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void addParameter(Parameters params) {
        params.add("sort", getValue());
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParseCountryTest.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.type.TypeReference;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import weiboclient4j.utils.JsonUtils;

import java.util.List;
import java.util.Map;

/**
 * @author <NAME>
 */
public class ParseCountryTest extends AbstractParseJsonTest {
    @Test
    public void testParseCountry() throws Exception {
        String content = readResource("/weiboclient4j/model/country.json");
        List<Map<String, String>> result = JsonUtils.parseJsonObject(content, new TypeReference<List<Map<String, String>>>() {
        });

        assertNotNull(result);
        assertEquals(2, result.size());

        assertTrue(result.get(0).containsKey("001"));
        assertEquals("C1", result.get(0).get("001"));

        assertTrue(result.get(1).containsKey("002"));
        assertEquals("C2", result.get(1).get("002"));
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/SuggestionStatusType.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public enum SuggestionStatusType implements ParameterAction {
    Ent(1), Joke(2), Belle(3), Video(4), Constellation(5), Cute(6), Fashion(7), Car(8), Food(9), Music(10);

    private int value;

    SuggestionStatusType(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void addParameter(Parameters params) {
        params.add("type", getValue());
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Ip.java<|end_filename|>
package weiboclient4j.params;

public class Ip extends StringParam {

    public Ip(String value) {
        super(value);
    }

    protected String paramKey() {
        return "ip";
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Paging.java<|end_filename|>
package weiboclient4j.params;

import java.util.HashMap;
import java.util.Map;

/**
 * @author <NAME>
 */
public class Paging {
    public static final String SINCE_ID = "since_id";
    public static final String PAGE = "page";
    public static final String COUNT = "count";
    public static final String MAX_ID = "max_id";
    public static final String CURSOR = "cursor";

    public static final Paging EMPTY = new Paging() {
        @Override
        public void setPage(int page) {
            throw new UnsupportedOperationException();
        }

        @Override
        public void setCount(int count) {
            throw new UnsupportedOperationException();
        }

        @Override
        public void setSinceId(long sinceId) {
            throw new UnsupportedOperationException();
        }

        @Override
        public void setMaxId(long maxId) {
            throw new UnsupportedOperationException();
        }

        @Override
        public void setCursor(long cursor) {
            throw new UnsupportedOperationException();
        }
    };

    public static Paging create() {
        return new Paging();
    }

    private int page;
    private int count;
    private long sinceId;
    private long maxId;
    private long cursor;

    public Paging page(int newPage) {
        setPage(newPage);

        return this;
    }

    public Paging count(int newCount) {
        setCount(newCount);

        return this;
    }

    public Paging sinceId(long newSinceId) {
        setSinceId(newSinceId);

        return this;
    }

    public Paging maxId(long newMaxId) {
        setMaxId(newMaxId);

        return this;
    }

    public Paging cursor(long newCursor) {
        setCursor(newCursor);

        return this;
    }

    public boolean hasValue() {
        return page > 0 || count > 0 || sinceId > 0 || maxId > 0 || cursor > 0;
    }

    public Map<String, String> buildParameters() {
        Map<String, String> params = new HashMap<String, String>();

        if (page > 0) {
            params.put(PAGE, String.valueOf(page));
        }

        if (count > 0) {
            params.put(COUNT, String.valueOf(count));
        }

        if (sinceId > 0) {
            params.put(SINCE_ID, String.valueOf(sinceId));
        }

        if (maxId > 0) {
            params.put(MAX_ID, String.valueOf(maxId));
        }

        if (cursor > 0) {
            params.put(CURSOR, String.valueOf(cursor));
        }

        return params;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public long getSinceId() {
        return sinceId;
    }

    public void setSinceId(long sinceId) {
        this.sinceId = sinceId;
    }

    public long getMaxId() {
        return maxId;
    }

    public void setMaxId(long maxId) {
        this.maxId = maxId;
    }

    public long getCursor() {
        return cursor;
    }

    public void setCursor(long cursor) {
        this.cursor = cursor;
    }
}


<|start_filename|>src/test/java/weiboclient4j/utils/SinaJsonNamingStrategyTest.java<|end_filename|>
package weiboclient4j.utils;

import org.junit.Test;

import static org.junit.Assert.assertEquals;

/**
 * @author <NAME>
 */
public class SinaJsonNamingStrategyTest {
    private SinaJsonNamingStrategy strategy = new SinaJsonNamingStrategy();

    @Test
    public void testScreenName() {
        assertEquals("screen_name", strategy.convertName("screenName"));
    }

    @Test
    public void testProfileImageUrl() {
        assertEquals("profile_image_url", strategy.convertName("profileImageUrl"));
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/AccountUid.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class AccountUid {
    private long uid;

    public long getUid() {
        return uid;
    }

    public void setUid(long uid) {
        this.uid = uid;
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParseTokenInfoTest.java<|end_filename|>
package weiboclient4j.model;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertThat;
import org.junit.Test;
import weiboclient4j.utils.JsonUtils;

public class ParseTokenInfoTest extends AbstractParseJsonTest {
    @Test
    public void testParseTokenInfo() throws Exception {
        String content = readResource("/weiboclient4j/model/token_info.json");

        TokenInfo tokenInfo = JsonUtils.parseJsonObject(content, TokenInfo.class);

        assertThat(tokenInfo, is(notNullValue()));
        assertThat(tokenInfo.getUid(), is(equalTo(1073880650L)));
        assertThat(tokenInfo.getAppkey(), is(equalTo("1352222456")));
        assertThat(tokenInfo.getScope(), is(nullValue()));
        assertThat(tokenInfo.getCreateAt(), is(equalTo(1352267591L)));
        assertThat(tokenInfo.getExpireIn(), is(equalTo(157679471)));
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/LocOffset.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.PlaceService;

/**
 * @author <NAME>
 */
public enum LocOffset implements
        PlaceService.GetNearbyUsersParam,
        PlaceService.GetNearbyPoisParam,
        PlaceService.GetNearbyPhotosParam,
        PlaceService.GetNearbyUsersListParam,
        PlaceService.GetNearbyTimelineParam {

    Original(0), Transformed(1);

    private int value;

    LocOffset(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void addParameter(Parameters params) {
        params.add("offset", getValue());
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/Emotion.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.type.TypeReference;

import java.util.List;

/**
 * @author hover.ruan
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class Emotion {
    public static final TypeReference<List<Emotion>> TYPE_EMOTION_LIST = new TypeReference<List<Emotion>>() {
    };

    private String phrase;
    private String type;
    private String url;
    private boolean hot;
    private boolean common;
    private String category;
    private String icon;
    private String value;

    // API V1 fields
    private boolean isHot;
    private boolean isCommon;
    private int orderNumber;

    public String getPhrase() {
        return phrase;
    }

    public void setPhrase(String phrase) {
        this.phrase = phrase;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public boolean isIsHot() {
        return isHot;
    }

    public void setIsHot(boolean isHot) {
        this.isHot = isHot;
    }

    public boolean isIsCommon() {
        return isCommon;
    }

    public void setIsCommon(boolean isCommon) {
        this.isCommon = isCommon;
    }

    public boolean isHot() {
        return hot;
    }

    public void setHot(boolean hot) {
        this.hot = hot;
    }

    public boolean isCommon() {
        return common;
    }

    public void setCommon(boolean common) {
        this.common = common;
    }

    public int getOrderNumber() {
        return orderNumber;
    }

    public void setOrderNumber(int orderNumber) {
        this.orderNumber = orderNumber;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getIcon() {
        return icon;
    }

    public void setIcon(String icon) {
        this.icon = icon;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParseTrendStatusTest.java<|end_filename|>
package weiboclient4j.model;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import weiboclient4j.utils.JsonUtils;

/**
 * @author <NAME>
 */
public class ParseTrendStatusTest extends AbstractParseJsonTest {

    @Test
    public void testParseTrendStatus() throws Exception {
        String content = readResource("/weiboclient4j/model/trend_status.json");

        TrendStatus status = JsonUtils.parseJsonObject(content, TrendStatus.class);
        assertNotNull(status);
        assertTrue(status.isFollow());
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/InboxType.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.StatusService;

import java.util.HashMap;
import java.util.Map;

/**
 * @author <NAME>
 */
public enum InboxType implements
        StatusService.QueryIdParam,
        StatusService.QueryIdListParam {

    Outbox(0), Inbox(1);

    private static Map<Integer, InboxType> map = new HashMap<Integer, InboxType>();

    static {
        for (InboxType inboxType : InboxType.values()) {
            map.put(inboxType.getValue(), inboxType);
        }
    }

    private int value;

    InboxType(int value) {
        this.value = value;
    }

    public static InboxType fromValue(int value) {
        return map.get(value);
    }

    public int getValue() {
        return value;
    }

    public void addParameter(Parameters params) {
        if (this != Outbox) {
            params.add("inbox", getValue());
        }
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParseTimezoneTest.java<|end_filename|>
package weiboclient4j.model;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import weiboclient4j.utils.JsonUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * @author <NAME>
 */
@SuppressWarnings("unchecked")
public class ParseTimezoneTest extends AbstractParseJsonTest {
    @Test
    public void testParseTimezone() throws Exception {
        String content = readResource("/weiboclient4j/model/timezone.json");

        Map<String, String> result = JsonUtils.parseJsonObject(content, HashMap.class);
        assertNotNull(result);

        assertTrue(result.containsKey("001"));
        assertEquals("Zone1", result.get("001"));
        assertEquals("Other", result.get("999"));
    }
}


<|start_filename|>src/main/java/weiboclient4j/oauth2/ForceLogin.java<|end_filename|>
package weiboclient4j.oauth2;

/**
 * @author <NAME>
 */
public enum ForceLogin {
    Yes(true), No(false);

    private boolean value;

    ForceLogin(boolean value) {
        this.value = value;
    }

    public String getValue() {
        return String.valueOf(value);
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/TrimUser.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.StatusService;

/**
 * @author <NAME>
 */
public enum TrimUser implements
        StatusService.GetFriendsTimelineParam,
        StatusService.GetHomeTimelineParam,
        StatusService.GetUserTimelineParam {

    Yes(1), No(0);

    private int value;

    TrimUser(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public static TrimUser fromValue(int value) {
        if (value == Yes.getValue()) {
            return Yes;
        } else if (value == No.getValue()) {
            return No;
        } else {
            return null;
        }
    }

    public void addParameter(Parameters params) {
        if (this == Yes) {
            params.add("trim_user", getValue());
        }
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParseAccountUidTest.java<|end_filename|>
package weiboclient4j.model;

import static junit.framework.Assert.assertEquals;
import org.junit.Test;
import weiboclient4j.utils.JsonUtils;

/**
 * @author <NAME>
 */
public class ParseAccountUidTest extends AbstractParseJsonTest {
    @Test
    public void testParseAccountUidResponseTest() throws Exception {
        String content = readResource("/weiboclient4j/model/account_uid.json");
        AccountUid response = JsonUtils.readValue(content, AccountUid.class);

        assertEquals("Account uid", 3456676543L, response.getUid());
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParsePoiTest.java<|end_filename|>
package weiboclient4j.model;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
import org.junit.Test;
import static weiboclient4j.utils.JsonUtils.readValue;

/**
 * @author <NAME>
 */
public class ParsePoiTest extends AbstractParseJsonTest {
    @Test
    public void parsePoi() throws Exception {
        String content = readResource("/weiboclient4j/model/poi.json");
        Poi poi = readValue(content, Poi.class);

        assertThat(poi, is(notNullValue()));
        assertThat(poi.getPoiid(), is("B2094654D16CABFE419E"));
        assertThat(poi.getLon(), is(116.30987));
        assertThat(poi.getLat(), is(39.98437));
        assertThat(poi.getCategory(), is("46"));
        assertThat(poi.getCity(), is("0010"));
        assertThat(poi.getPhone(), is("010-82607123"));
        assertThat(poi.getPostcode(), is("100000"));
        assertThat(poi.getWeiboId(), is("2513895201"));
        assertThat(poi.getIcon(), is("http://u1.sinaimg.cn/upload/lbs/poi/icon/88/46.png"));
        assertThat(poi.getRid(), is("46"));
        assertThat(poi.getCategorys(), is("44 46"));
        assertThat(poi.getCheckinNum(), is(3114));
        assertThat(poi.getCheckinUserNum(), is(1315));
        assertThat(poi.getTipNum(), is(3080));
        assertThat(poi.getPhotoNum(), is(1119));
        assertThat(poi.getTodoNum(), is(106));
    }
}


<|start_filename|>src/main/java/weiboclient4j/utils/SinaJsonNamingStrategy.java<|end_filename|>
package weiboclient4j.utils;

import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.MapperConfig;
import org.codehaus.jackson.map.PropertyNamingStrategy;
import org.codehaus.jackson.map.introspect.AnnotatedField;
import org.codehaus.jackson.map.introspect.AnnotatedMethod;

/**
 * @author <NAME>
 */
public class SinaJsonNamingStrategy extends PropertyNamingStrategy.PropertyNamingStrategyBase {

    @Override
    public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName) {
        return translateWithAnnotation(field.getAnnotation(JsonProperty.class), defaultName);
    }

    @Override
    public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
        return translateWithAnnotation(method.getAnnotation(JsonProperty.class), defaultName);
    }

    public String translate(String propertyName) {
        return convertName(propertyName);
    }

    private String translateWithAnnotation(JsonProperty jsonPropertyAnn, String defaultName) {
        if (jsonPropertyAnn != null) {
            String propertyName = jsonPropertyAnn.value();
            if (StringUtils.isNotBlank(propertyName)) {
                return propertyName;
            }
        }

        return translate(defaultName);
    }

    String convertName(String defaultName) {
        StringBuilder buf = new StringBuilder();

        for (char ch : defaultName.toCharArray()) {
            if (Character.isUpperCase(ch)) {
                buf.append('_').append(Character.toLowerCase(ch));
            } else {
                buf.append(ch);
            }
        }

        return buf.toString();
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/SearchSuggestionAppResult.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.type.TypeReference;

import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class SearchSuggestionAppResult {
    public static final TypeReference<List<SearchSuggestionAppResult>> TYPE_SEARCH_SUGGESTION_APP_RESULT_LIST =
            new TypeReference<List<SearchSuggestionAppResult>>() {
            };

    private String appsName;
    private int membersCount;

    public String getAppsName() {
        return appsName;
    }

    public void setAppsName(String appsName) {
        this.appsName = appsName;
    }

    public int getMembersCount() {
        return membersCount;
    }

    public void setMembersCount(int membersCount) {
        this.membersCount = membersCount;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/NearbySortType.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.PlaceService;

/**
 * @author <NAME>
 */
public enum NearbySortType implements
        PlaceService.GetNearbyUsersParam,
        PlaceService.GetNearbyPoisParam {
    Weight(0);

    private int value;

    NearbySortType(int value) {
        this.value = value;
    }

    public void addParameter(Parameters params) {
        params.add("sort", value);
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/PoiId.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public class PoiId extends StringParam {
    public PoiId(String value) {
        super(value);
    }

    protected String paramKey() {
        return "poiid";
    }
}


<|start_filename|>src/main/java/weiboclient4j/AccountService.java<|end_filename|>
package weiboclient4j;

import weiboclient4j.model.AccountUid;
import weiboclient4j.model.Privacy;
import weiboclient4j.model.RateLimitStatus;
import weiboclient4j.model.User;

/**
 * @author <NAME>
 */
public class AccountService extends AbstractService {
    public AccountService(WeiboClient client) {
        super(client);
    }

    public long getUid() throws WeiboClientException {
        AccountUid accountUid = doGet("account/get_uid", AccountUid.class);

        return accountUid.getUid();
    }

    public Privacy getPrivacy() throws WeiboClientException {
        return doGet("account/get_privacy", Privacy.class);
    }

    public RateLimitStatus getRateLimitStatus() throws WeiboClientException {
        return doGet("account/rate_limit_status", RateLimitStatus.class);
    }

    public User endSession() throws WeiboClientException {
        return doGet("account/end_session", User.class);
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/P.java<|end_filename|>
package weiboclient4j.params;

public final class P extends CoreParameters {
}


<|start_filename|>src/main/java/weiboclient4j/model/UrlInfo.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

import java.util.Date;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class UrlInfo {
    private String urlShort;
    private String urlLong;
    private int type;
    private boolean result;
    private String title;
    private String description;
    private Date lastModified;

    public String getUrlShort() {
        return urlShort;
    }

    public void setUrlShort(String urlShort) {
        this.urlShort = urlShort;
    }

    public String getUrlLong() {
        return urlLong;
    }

    public void setUrlLong(String urlLong) {
        this.urlLong = urlLong;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public boolean isResult() {
        return result;
    }

    public void setResult(boolean result) {
        this.result = result;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Date getLastModified() {
        return lastModified;
    }

    public void setLastModified(Date lastModified) {
        this.lastModified = lastModified;
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParseLocationPoiListTest.java<|end_filename|>
package weiboclient4j.model;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
import org.junit.Test;
import weiboclient4j.utils.JsonUtils;

import java.util.List;

public class ParseLocationPoiListTest extends AbstractParseJsonTest {
    @Test
    public void testParseLocationPoiList() throws Exception {
        String content = readResource("/weiboclient4j/model/location_poi_list.json");
        LocationPoiList locationPoiList = JsonUtils.readValue(content, LocationPoiList.class);

        assertThat(locationPoiList, is(notNullValue()));
        assertThat(locationPoiList.getTotalNumber(), is(equalTo(325L)));

        List<LocationPoi> pois = locationPoiList.getPois();
        assertThat(pois, is(notNullValue()));
        assertThat(pois.size(), is(equalTo(10)));

        LocationPoi poi = pois.get(0);
        assertThat(poi.getLongitude().toString(), is(equalTo("116.31067")));
        assertThat(poi.getLatitude().toString(), is(equalTo("39.98445")));
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/FavoritesItem.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

import java.util.Date;
import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class FavoritesItem {
    private Status status;
    private List<Tag> tags;
    private Date favoritedTime;

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    public List<Tag> getTags() {
        return tags;
    }

    public void setTags(List<Tag> tags) {
        this.tags = tags;
    }

    public Date getFavoritedTime() {
        return favoritedTime;
    }

    public void setFavoritedTime(Date favoritedTime) {
        this.favoritedTime = favoritedTime;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/SearchSuggestionSchoolResult.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.type.TypeReference;

import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class SearchSuggestionSchoolResult {
    public static final TypeReference<List<SearchSuggestionSchoolResult>> TYPE_SEARCH_SUGGESTION_SCHOOL_RESULT_LIST =
            new TypeReference<List<SearchSuggestionSchoolResult>>() {
            };

    private long id;
    private String schoolName;
    private int location;
    private int type;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getSchoolName() {
        return schoolName;
    }

    public void setSchoolName(String schoolName) {
        this.schoolName = schoolName;
    }

    public int getLocation() {
        return location;
    }

    public void setLocation(int location) {
        this.location = location;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/SearchSuggestionCompanyResult.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.type.TypeReference;

import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class SearchSuggestionCompanyResult {
    public static final TypeReference<List<SearchSuggestionCompanyResult>> TYPE_SEARCH_SUGGESTION_COMPANY_RESULT_LIST =
            new TypeReference<List<SearchSuggestionCompanyResult>>() {
            };

    private String suggestion;

    public String getSuggestion() {
        return suggestion;
    }

    public void setSuggestion(String suggestion) {
        this.suggestion = suggestion;
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParseTimelineTest.java<|end_filename|>
package weiboclient4j.model;

import static junit.framework.Assert.assertEquals;
import org.junit.Test;
import weiboclient4j.utils.JsonUtils;

/**
 * @author <NAME>
 */
public class ParseTimelineTest extends AbstractParseJsonTest {
    @Test
    public void testParseTimeline() throws Exception {
        String content = readResource("/weiboclient4j/model/timeline.json");

        Timeline timeline = JsonUtils.readValue(content, Timeline.class);
        assertEquals("Total number: ", 20, timeline.getTotalNumber());
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/TargetUid.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public class TargetUid extends LongParam {
    public static final TargetUid EMPTY = new TargetUid(0);

    public TargetUid(long value) {
        super(value);
    }

    public TargetUid(String value) {
        super(value);
    }

    protected String paramKey() {
        return "target_id";
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/City.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.LocationService;
import weiboclient4j.PlaceService;

/**
 * @author <NAME>
 */
public class City extends StringParam implements
        PlaceService.SearchPoisParam,
        LocationService.GetMapImageParam,
        LocationService.SearchByLocationParam,
        LocationService.SearchByAreaParam {

    public City(String value) {
        super(value);
    }

    protected String paramKey() {
        return "city";
    }
}


<|start_filename|>src/test/java/weiboclient4j/oauth2/ParseSinaWeibo2AccessTokenResponseTest.java<|end_filename|>
package weiboclient4j.oauth2;

import static junit.framework.Assert.assertEquals;
import org.junit.Test;
import weiboclient4j.model.AbstractParseJsonTest;
import static weiboclient4j.utils.JsonUtils.parseJsonObject;

/**
 * @author <NAME>
 */
public class ParseSinaWeibo2AccessTokenResponseTest extends AbstractParseJsonTest {
    @Test
    public void testParseAccessTokenResponse() throws Exception {
        String content = readResource("/weiboclient4j/oauth2/access_token_response.json");

        SinaWeibo2AccessTokenResponse response = parseJsonObject(content, SinaWeibo2AccessTokenResponse.class);
        assertEquals("AccessToken", "ACCESS_TOKEN", response.getAccessToken());
        assertEquals("ExpiresIn", 1234, response.getExpiresIn());
        assertEquals("RemindIn", 798114, response.getRemindIn());
        assertEquals("Uid", 12341234, response.getUid());
        assertEquals("isRealName", true, response.isRealName());
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/TargetScreenName.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public class TargetScreenName extends StringParam {
    public static final TargetScreenName EMPTY = new TargetScreenName(null);

    public TargetScreenName(String value) {
        super(value);
    }

    protected String paramKey() {
        return "target_screen_name";
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/PoiList.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class PoiList {
    private List<Poi> pois;
    private int totalNumber;

    public int getTotalNumber() {
        return totalNumber;
    }

    public void setTotalNumber(int totalNumber) {
        this.totalNumber = totalNumber;
    }

    public List<Poi> getPois() {
        return pois;
    }

    public void setPois(List<Poi> pois) {
        this.pois = pois;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Language.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public enum Language implements ParameterAction {
    ZH_CN("zh-cn"), ZH_TW("zh-tw"), ENGLISH("english");

    private String value;

    Language(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public void addParameter(Parameters params) {
        params.add("language", getValue());
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/CoreParameters.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public class CoreParameters {
    public static ActionUrl actionUrl(String value) {
        return new ActionUrl(value);
    }

    public static Address address(String value) {
        return new Address(value);
    }

    public static AddressCode addressCode(String value) {
        return new AddressCode(value);
    }

    public static CapitalLetter capitalLetter(String value) {
        return new CapitalLetter(value);
    }

    public static Category category(String value) {
        return new Category(value);
    }

    public static Cid cid(long value) {
        return new Cid(value);
    }

    public static Cid cid(String value) {
        return new Cid(value);
    }

    public static City city(String value) {
        return new City(value);
    }

    public static CommentParam commentParam(String value) {
        return new CommentParam(value);
    }

    public static Content content(String value) {
        return new Content(value);
    }

    public static Country country(String value) {
        return new Country(value);
    }

    public static Domain domain(String value) {
        return new Domain(value);
    }

    public static EndBirth endBirth(long value) {
        return new EndBirth(value);
    }

    public static EndTime endTime(long value) {
        return new EndTime(value);
    }

    public static Extra extra(String value) {
        return new Extra(value);
    }

    public static Id id(long value) {
        return new Id(value);
    }

    public static Id id(String value) {
        return new Id(value);
    }

    public static Keyword keyword(String value) {
        return new Keyword(value);
    }

    public static Latitude latitude(float value) {
        return new Latitude(value);
    }

    public static ListId listId(String value) {
        return new ListId(value);
    }

    public static LocRange locRange(long value) {
        return new LocRange(value);
    }

    public static Longitude longitude(float value) {
        return new Longitude(value);
    }

    public static Mid mid(String value) {
        return new Mid(value);
    }

    public static Nickname nickname(String value) {
        return new Nickname(value);
    }

    public static Num num(long value) {
        return new Num(value);
    }

    public static Phone phone(String value) {
        return new Phone(value);
    }

    public static Pid pid(String value) {
        return new Pid(value);
    }

    public static PostCode postCode(String value) {
        return new PostCode(value);
    }

    public static Province province(String value) {
        return new Province(value);
    }

    public static Query query(String value) {
        return new Query(value);
    }

    public static Remark remark(String value) {
        return new Remark(value);
    }

    public static ScreenName screenName(String value) {
        return new ScreenName(value);
    }

    public static Section section(long value) {
        return new Section(value);
    }

    public static SourceScreenName sourceScreenName(String value) {
        return new SourceScreenName(value);
    }

    public static SourceUid sourceUid(long value) {
        return new SourceUid(value);
    }

    public static SourceUid sourceUid(String value) {
        return new SourceUid(value);
    }

    public static StartBirth startBirth(long value) {
        return new StartBirth(value);
    }

    public static StartTime startTime(long value) {
        return new StartTime(value);
    }

    public static Suid suid(long value) {
        return new Suid(value);
    }

    public static Suid suid(String value) {
        return new Suid(value);
    }

    public static TagId tagId(long value) {
        return new TagId(value);
    }

    public static TagId tagId(String value) {
        return new TagId(value);
    }

    public static TagName tagName(String value) {
        return new TagName(value);
    }

    public static TargetScreenName targetScreenName(String value) {
        return new TargetScreenName(value);
    }

    public static TargetUid targetUid(long value) {
        return new TargetUid(value);
    }

    public static TargetUid targetUid(String value) {
        return new TargetUid(value);
    }

    public static TemplateId templateId(long value) {
        return new TemplateId(value);
    }

    public static Tid tid(long value) {
        return new Tid(value);
    }

    public static Title title(String value) {
        return new Title(value);
    }

    public static TrendId trendId(long value) {
        return new TrendId(value);
    }

    public static TrendName trendName(String value) {
        return new TrendName(value);
    }

    public static Uid uid(long value) {
        return new Uid(value);
    }

    public static Uid uid(String value) {
        return new Uid(value);
    }

    public static UrlLong urlLong(String value) {
        return new UrlLong(value);
    }

    public static UrlShort urlShort(String value) {
        return new UrlShort(value);
    }

    public static CenterCoordinate centerCoordinate(String value) {
        return new CenterCoordinate(value);
    }

    public static CenterCoordinate centerCoordinate(Coordinate coordinate) {
        return new CenterCoordinate(coordinate);
    }

    public static CenterCoordinate centerCoordinate(Longitude longitude, Latitude latitude) {
        return new CenterCoordinate(longitude, latitude);
    }

    public static Coordinates coordinates(String value) {
        return new Coordinates(value);
    }

    public static Coordinates coordinates(Coordinate... coordinatesParam) {
        return new Coordinates(coordinatesParam);
    }

    public static Font font(String value) {
        return new Font(value);
    }

    public static Format format(String value) {
        return new Format(value);
    }

    public static Lines lines(String value) {
        return new Lines(value);
    }

    public static Names names(String... namesParam) {
        return new Names(namesParam);
    }

    public static OffsetX offsetX(String value) {
        return new OffsetX(value);
    }

    public static OffsetY offsetY(String value) {
        return new OffsetY(value);
    }

    public static Polygons polygons(String value) {
        return new Polygons(value);
    }

    public static Scale scale(boolean value) {
        return new Scale(value);
    }

    public static Traffic traffic(boolean value) {
        return new Traffic(value);
    }

    public static Zoom zoom(long value) {
        return new Zoom(value);
    }

    public static Ip ip(String value) {
        return new Ip(value);
    }

    public static PicId picId(String... picIdList) {
        return new PicId(picIdList);
    }

    public static Pic pic(String value) {
        return new Pic(value);
    }
}


<|start_filename|>src/main/java/weiboclient4j/ShortUrlService.java<|end_filename|>
package weiboclient4j;

import weiboclient4j.model.Url;
import weiboclient4j.model.UrlInfo;
import weiboclient4j.params.Paging;
import weiboclient4j.params.UrlLong;
import weiboclient4j.params.UrlShort;
import weiboclient4j.utils.CollectionUtils;
import static weiboclient4j.utils.CollectionUtils.firstItem;

import java.util.Collection;
import java.util.List;

/**
 * @author <NAME>
 */
public class ShortUrlService extends AbstractService {
    public ShortUrlService(WeiboClient client) {
        super(client);
    }

    public Url shortenUrl(UrlLong urlLong) throws WeiboClientException {
        return firstItem(shortenUrl(CollectionUtils.newArrayList(urlLong)));
    }

    public List<Url> shortenUrl(Collection<UrlLong> urlList) throws WeiboClientException {
        UrlResponse response = doGet("short_url/shorten",
                withParams(UrlLong.urlLongParam(urlList)), UrlResponse.class);

        return response.getUrls();
    }

    public Url expandUrl(UrlShort urlShort) throws WeiboClientException {
        return firstItem(expandUrl(CollectionUtils.newArrayList(urlShort)));
    }

    public List<Url> expandUrl(Collection<UrlShort> urlList) throws WeiboClientException {
        UrlResponse response = doGet("short_url/expand",
                withParams(UrlShort.urlShortParam(urlList)), UrlResponse.class);

        return response.getUrls();
    }

    public List<Url> getClicks(Collection<UrlShort> urlList) throws WeiboClientException {
        UrlResponse response = doGet("short_url/clicks",
                withParams(UrlShort.urlShortParam(urlList)), UrlResponse.class);

        return response.getUrls();
    }

    public Url getReferers(UrlShort urlShort) throws WeiboClientException {
        return doGet("short_url/referers", withParams(urlShort), Url.class);
    }

    public Url getLocations(UrlShort urlShort) throws WeiboClientException {
        return doGet("short_url/locations", withParams(urlShort), Url.class);
    }

    public List<Url> getShareCounts(Collection<UrlShort> urlList) throws WeiboClientException {
        UrlResponse response = doGet("short_url/share/counts",
                withParams(UrlShort.urlShortParam(urlList)), UrlResponse.class);

        return response.getUrls();
    }

    public Url getShareStatuses(UrlShort urlShort) throws WeiboClientException {
        return getShareStatuses(urlShort, Paging.EMPTY);
    }

    public Url getShareStatuses(UrlShort urlShort, Paging paging) throws WeiboClientException {
        return doGet("short_url/share/statuses",
                paging, withParams(urlShort), Url.class);
    }

    public List<Url> getCommentCounts(Collection<UrlShort> urlList) throws WeiboClientException {
        UrlResponse response = doGet("short_url/comment/counts",
                withParams(UrlShort.urlShortParam(urlList)), UrlResponse.class);

        return response.getUrls();
    }

    public Url getComments(UrlShort urlShort) throws WeiboClientException {
        return getComments(urlShort, Paging.EMPTY);
    }

    public Url getComments(UrlShort urlShort, Paging paging) throws WeiboClientException {
        return doGet("short_url/comment/comments",
                paging, withParams(urlShort), Url.class);
    }

    public List<UrlInfo> getInfo(Collection<UrlShort> urlList) throws WeiboClientException {
        UrlInfoResponse response = doGet("short_url/info",
                withParams(UrlShort.urlShortParam(urlList)), UrlInfoResponse.class);

        return response.getUrls();
    }
}


<|start_filename|>src/test/resources/weiboclient4j/model/emotions.json<|end_filename|>
[
  {
    "phrase":"[呵呵]",
    "type":"face",
    "url":"http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/eb/smile.gif",
    "is_hot":false,
    "is_common":true,
    "order_number":0,
    "category":""
  }
]

<|start_filename|>src/main/java/weiboclient4j/NotificationService.java<|end_filename|>
package weiboclient4j;

import weiboclient4j.model.NotificationResult;
import weiboclient4j.params.ActionUrl;
import weiboclient4j.params.ParameterAction;
import weiboclient4j.params.Parameters;
import weiboclient4j.params.TemplateId;
import weiboclient4j.params.Uid;
import weiboclient4j.utils.StringUtils;

import java.util.Collection;

/**
 * @author <NAME>
 */
public class NotificationService extends AbstractService {
    public NotificationService(WeiboClient client) {
        super(client);
    }

    public NotificationResult send(Collection<Uid> uids, TemplateId templateId) throws WeiboClientException {
        return send(uids, templateId, null);
    }

    public NotificationResult send(Collection<Uid> uids, TemplateId templateId, ActionUrl actionUrl)
            throws WeiboClientException {
        return send(uids, templateId, null, 0, actionUrl);
    }

    public NotificationResult send(Collection<Uid> uids,
                                   TemplateId templateId,
                                   final String objects1,
                                   final int objects1Count) throws WeiboClientException {
        return send(uids, templateId, objects1, objects1Count, null, 0);
    }

    public NotificationResult send(Collection<Uid> uids,
                                   TemplateId templateId,
                                   final String objects1,
                                   final int objects1Count,
                                   final String objects2,
                                   final int objects2Count) throws WeiboClientException {
        return send(uids, templateId, objects1, objects1Count, objects2, objects2Count, null, 0);
    }

    public NotificationResult send(Collection<Uid> uids,
                                   TemplateId templateId,
                                   final String objects1,
                                   final int objects1Count,
                                   final String objects2,
                                   final int objects2Count,
                                   final String objects3,
                                   final int objects3Count) throws WeiboClientException {
        return send(uids, templateId, objects1, objects1Count, objects2, objects2Count, objects3, objects3Count,
                ActionUrl.EMPTY);
    }

    public NotificationResult send(Collection<Uid> uids,
                                   TemplateId templateId,
                                   final String objects1,
                                   final int objects1Count,
                                   ActionUrl actionUrl) throws WeiboClientException {
        return send(uids, templateId, objects1, objects1Count, null, 0, actionUrl);
    }

    public NotificationResult send(Collection<Uid> uids,
                                   TemplateId templateId,
                                   final String objects1,
                                   final int objects1Count,
                                   final String objects2,
                                   final int objects2Count,
                                   ActionUrl actionUrl) throws WeiboClientException {
        return send(uids, templateId, objects1, objects1Count, objects2, objects2Count, null, 0, actionUrl);
    }

    public NotificationResult send(Collection<Uid> uids,
                                   TemplateId templateId,
                                   final String objects1,
                                   final int objects1Count,
                                   final String objects2,
                                   final int objects2Count,
                                   final String objects3,
                                   final int objects3Count,
                                   ActionUrl actionUrl) throws WeiboClientException {
        ParameterAction objectsParamAction = new ParameterAction() {
            public void addParameter(Parameters params) {
                if (StringUtils.isNotBlank(objects1)) {
                    params.add("objects1", objects1);
                }

                if (objects1Count > 0) {
                    params.add("objects1_count", objects1Count);
                }

                if (StringUtils.isNotBlank(objects2)) {
                    params.add("objects2", objects2);
                }

                if (objects2Count > 0) {
                    params.add("objects2_count", objects2Count);
                }

                if (StringUtils.isNotBlank(objects3)) {
                    params.add("objects3", objects3);
                }

                if (objects3Count > 0) {
                    params.add("objects3_count", objects3Count);
                }
            }
        };

        return doPost("notification/send",
                withParams(Uid.uidsParam(uids), templateId, objectsParamAction, actionUrl), NotificationResult.class);
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/BaseApp.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.PlaceService;
import weiboclient4j.StatusService;

/**
 * @author <NAME>
 */
public enum BaseApp implements
        PlaceService.GetPoiPhotosParam,
        PlaceService.GetPoiTipsParam,
        PlaceService.GetPoiUsersParam,
        PlaceService.GetPublishTimelineParam,
        PlaceService.GetUserTimelineParam,
        PlaceService.GetPoiTimelineParam,
        PlaceService.GetNearbyTimelineParam,
        PlaceService.GetUserCheckinsParam,
        PlaceService.GetUserPhotosParam,
        PlaceService.GetUserTipsParam,
        PlaceService.GetUserTodosParam,
        StatusService.GetFriendsTimelineParam,
        StatusService.GetPublicTimelineParam,
        StatusService.GetHomeTimelineParam,
        StatusService.GetFriendsTimelineIdsParam,
        StatusService.GetUserTimelineParam,
        StatusService.GetUserTimelineIdsParam,
        StatusService.GetBilateralTimelineParam {

    Yes(1), No(0);

    private int value;

    BaseApp(int value) {
        this.value = value;
    }

    public static BaseApp fromValue(int value) {
        if (value == Yes.getValue()) {
            return Yes;
        } else if (value == No.getValue()) {
            return No;
        }

        return null;
    }

    public int getValue() {
        return value;
    }

    public void addParameter(Parameters params) {
        if (this == Yes) {
            params.add("base_app", getValue());
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/oauth2/DisplayType.java<|end_filename|>
package weiboclient4j.oauth2;

/**
 * @author <NAME>
 */
public enum DisplayType {

    Default("default"),

    Mobile("mobile"),

    Popup("popup"),

    Wap12("wap1.2"),

    Wap20("wap2.0"),

    Js("js"),

    Wap("wap"),

    Client("client"),

    AppOnWeibo("apponweibo");

    private String display;

    DisplayType(String display) {
        this.display = display;
    }

    public String getDisplay() {
        return display;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/Status.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.type.TypeReference;

import java.util.Date;
import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class Status {
    public static final TypeReference<List<Status>> TYPE_STATUS_LIST = new TypeReference<List<Status>>() {
    };

    private Date createdAt;
    private String idstr;
    private long id;
    private String text;
    private String source;
    private boolean favorited;
    private boolean truncated;
    private String inReplyToStatusId;
    private String inReplyToUserId;
    private String inReplyToScreenName;
    private String thumbnailPic;
    private String bmiddlePic;
    private String originalPic;
    private Status retweetedStatus;
    private User user;
    private String userId;
    private Geo geo;
    private String mid;
    private String deleted;
    private int repostsCount;
    private int commentsCount;

    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public String getSource() {
        return source;
    }

    public void setSource(String source) {
        this.source = source;
    }

    public boolean isFavorited() {
        return favorited;
    }

    public void setFavorited(boolean favorited) {
        this.favorited = favorited;
    }

    public boolean isTruncated() {
        return truncated;
    }

    public void setTruncated(boolean truncated) {
        this.truncated = truncated;
    }

    public String getInReplyToStatusId() {
        return inReplyToStatusId;
    }

    public void setInReplyToStatusId(String inReplyToStatusId) {
        this.inReplyToStatusId = inReplyToStatusId;
    }

    public String getInReplyToUserId() {
        return inReplyToUserId;
    }

    public void setInReplyToUserId(String inReplyToUserId) {
        this.inReplyToUserId = inReplyToUserId;
    }

    public String getInReplyToScreenName() {
        return inReplyToScreenName;
    }

    public void setInReplyToScreenName(String inReplyToScreenName) {
        this.inReplyToScreenName = inReplyToScreenName;
    }

    public String getThumbnailPic() {
        return thumbnailPic;
    }

    public void setThumbnailPic(String thumbnailPic) {
        this.thumbnailPic = thumbnailPic;
    }

    public String getBmiddlePic() {
        return bmiddlePic;
    }

    public void setBmiddlePic(String bmiddlePic) {
        this.bmiddlePic = bmiddlePic;
    }

    public String getOriginalPic() {
        return originalPic;
    }

    public void setOriginalPic(String originalPic) {
        this.originalPic = originalPic;
    }

    public Status getRetweetedStatus() {
        return retweetedStatus;
    }

    public void setRetweetedStatus(Status retweetedStatus) {
        this.retweetedStatus = retweetedStatus;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public Geo getGeo() {
        return geo;
    }

    public void setGeo(Geo geo) {
        this.geo = geo;
    }

    public String getMid() {
        return mid;
    }

    public void setMid(String mid) {
        this.mid = mid;
    }

    public String getDeleted() {
        return deleted;
    }

    public void setDeleted(String deleted) {
        this.deleted = deleted;
    }

    public String getIdstr() {
        return idstr;
    }

    public void setIdstr(String idstr) {
        this.idstr = idstr;
    }

    public int getRepostsCount() {
        return repostsCount;
    }

    public void setRepostsCount(int repostsCount) {
        this.repostsCount = repostsCount;
    }

    public int getCommentsCount() {
        return commentsCount;
    }

    public void setCommentsCount(int commentsCount) {
        this.commentsCount = commentsCount;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Extra.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.PlaceService;

/**
 * @author <NAME>
 */
public class Extra extends StringParam implements
        PlaceService.CreatePoiParam {

    public Extra(String value) {
        super(value);
    }

    protected String paramKey() {
        return "extra";
    }
}


<|start_filename|>src/main/java/weiboclient4j/CommonService.java<|end_filename|>
package weiboclient4j;

import weiboclient4j.params.AddressCode;
import weiboclient4j.params.CapitalLetter;
import weiboclient4j.params.Country;
import weiboclient4j.params.Language;
import weiboclient4j.params.Province;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author <NAME>
 */
public class CommonService extends AbstractService {
    public CommonService(WeiboClient client) {
        super(client);
    }

    public Map<String, String> getTimezoneMap() throws WeiboClientException {
        return getTimezoneMap(null);
    }

    @SuppressWarnings("unchecked")
    public Map<String, String> getTimezoneMap(Language language) throws WeiboClientException {
        return doGet("common/get_timezone",
                withParams(language), HashMap.class);
    }

    public Map<String, String> getCountryMap() throws WeiboClientException {
        return getCountryMap(null, null);
    }

    public Map<String, String> getCountryMap(Language language, CapitalLetter capitalLetter)
            throws WeiboClientException {
        List<Map<String, String>> response = doGet("common/get_country",
                withParams(language, capitalLetter), LIST_MAP_S_S_TYPE_REFERENCE);

        return mergeSingleItemMap(response);
    }

    public Map<String, String> getProvinceMap(Country country) throws WeiboClientException {
        return getProvinceMap(country, null, null);
    }

    public Map<String, String> getProvinceMap(Country country, Language language, CapitalLetter capitalLetter)
            throws WeiboClientException {
        List<Map<String, String>> response = doGet("common/get_province",
                withParams(country, language, capitalLetter), LIST_MAP_S_S_TYPE_REFERENCE);

        return mergeSingleItemMap(response);
    }

    public Map<String, String> getCityMap(Province province) throws WeiboClientException {
        return getCityMap(province, null, null);
    }

    public Map<String, String> getCityMap(Province province, Language language, CapitalLetter capitalLetter)
            throws WeiboClientException {
        List<Map<String, String>> response = doGet("common/get_city",
                withParams(province, language, capitalLetter), LIST_MAP_S_S_TYPE_REFERENCE);

        return mergeSingleItemMap(response);
    }

    public Map<String, String> codeToLocation(Collection<AddressCode> codes) throws WeiboClientException {
        List<Map<String, String>> response = doGet("common/code_to_location",
                withParams(AddressCode.codesParam(codes)), LIST_MAP_S_S_TYPE_REFERENCE);

        return mergeSingleItemMap(response);
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/TagId.java<|end_filename|>
package weiboclient4j.params;

import static weiboclient4j.utils.StringUtils.join;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author <NAME>
 */
public class TagId extends LongParam {
    public TagId(long value) {
        super(value);
    }

    public TagId(String value) {
        super(value);
    }

    protected String paramKey() {
        return "tag_id";
    }

    public static ParameterAction idsParam(final Collection<TagId> tagIds) {
        return new ParameterAction() {
            public void addParameter(Parameters params) {
                if (tagIds != null && tagIds.size() > 0) {
                    List<String> idStringList = new ArrayList<String>(tagIds.size());
                    for (TagId tagId : tagIds) {
                        idStringList.add(String.valueOf(tagId.getValue()));
                    }
                    String idsString = join(idStringList, ",");
                    params.add("ids", idsString);
                }
            }
        };
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/Privacy.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class Privacy {
    private boolean badge;
    private boolean comment;
    private boolean geo;
    private boolean message;
    private boolean mobile;
    private boolean realname;

    public boolean isBadge() {
        return badge;
    }

    public void setBadge(boolean badge) {
        this.badge = badge;
    }

    public boolean isComment() {
        return comment;
    }

    public void setComment(boolean comment) {
        this.comment = comment;
    }

    public boolean isGeo() {
        return geo;
    }

    public void setGeo(boolean geo) {
        this.geo = geo;
    }

    public boolean isMessage() {
        return message;
    }

    public void setMessage(boolean message) {
        this.message = message;
    }

    public boolean isMobile() {
        return mobile;
    }

    public void setMobile(boolean mobile) {
        this.mobile = mobile;
    }

    public boolean isRealname() {
        return realname;
    }

    public void setRealname(boolean realname) {
        this.realname = realname;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/FilterByAuthor.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.StatusService;

import java.util.HashMap;
import java.util.Map;

/**
 * @author <NAME>
 */
public enum FilterByAuthor implements
        StatusService.GetRepostTimelineParam,
        StatusService.GetRepostTimelineIdsParam,
        StatusService.GetMentionsParam,
        StatusService.GetMentionsIdsParam {

    All(0), Friends(1), Stranger(2);

    private static Map<Integer, FilterByAuthor> map = new HashMap<Integer, FilterByAuthor>();

    static {
        for (FilterByAuthor filterByAuthor : FilterByAuthor.values()) {
            map.put(filterByAuthor.getValue(), filterByAuthor);
        }
    }

    private int value;

    FilterByAuthor(int value) {
        this.value = value;
    }

    public static FilterByAuthor fromValue(int value) {
        return map.get(value);
    }

    public int getValue() {
        return value;
    }

    public void addParameter(Parameters params) {
        if (this != All) {
            params.add("filter_by_author", getValue());
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/BooleanParam.java<|end_filename|>
package weiboclient4j.params;

public abstract class BooleanParam implements ParameterAction {
    private boolean value;

    public BooleanParam(boolean value) {
        this.value = value;
    }

    public boolean getValue() {
        return value;
    }

    public void addParameter(Parameters params) {
        params.add(paramKey(), value);
    }

    @Override
    public String toString() {
        return String.valueOf(value);
    }

    protected abstract String paramKey();
}


<|start_filename|>src/main/java/weiboclient4j/AbstractService.java<|end_filename|>
package weiboclient4j;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.type.TypeReference;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Verb;
import weiboclient4j.model.Url;
import weiboclient4j.model.UrlInfo;
import weiboclient4j.oauth2.SinaWeibo2AccessToken;
import weiboclient4j.params.Paging;
import weiboclient4j.params.ParameterAction;
import weiboclient4j.params.Parameters;
import static weiboclient4j.utils.JsonUtils.parseJsonObject;
import weiboclient4j.utils.StreamUtils;
import static weiboclient4j.utils.StreamUtils.closeQuietly;
import static weiboclient4j.utils.StreamUtils.newStreamWriter;
import weiboclient4j.utils.StringUtils;
import static weiboclient4j.utils.StringUtils.isNotBlank;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author <NAME>
 */
public class AbstractService {
    public static final String API2_URL = "https://api.weibo.com/2/";

    protected static final TypeReference<List<Map<String, String>>> LIST_MAP_S_S_TYPE_REFERENCE =
            new TypeReference<List<Map<String, String>>>() {
            };

    protected static final TypeReference<List<TagActionResponse>> TYPE_TAG_ACTION_RESPONSE_LIST =
            new TypeReference<List<TagActionResponse>>() {
            };

    protected static final TypeReference<List<LongIdStringValue>> TYPE_LONG_ID_STRING_VALUE_LIST =
            new TypeReference<List<LongIdStringValue>>() {
            };

    private static final int DEFAULT_TIMEOUT = 30;

    private WeiboClient client;

    private SinaWeibo2AccessToken accessToken;

    private int connectTimeoutDuration = DEFAULT_TIMEOUT;

    private TimeUnit connectTimeoutUnit = TimeUnit.SECONDS;

    private int readTimeoutDuration = DEFAULT_TIMEOUT;

    private TimeUnit readTimeoutUnit = TimeUnit.SECONDS;

    public AbstractService(WeiboClient client) {
        this.client = client;

        client.initService(this);
    }

    public static Parameters withParams(ParameterAction... actions) {
        return Parameters.create().addAll(actions);
    }

    public static Parameters buildParams(ParameterAction[] optionalParams, ParameterAction... requireParams) {
        return Parameters.create().addAll(optionalParams).addAll(requireParams);
    }

    protected static void buildUploadRequest(OAuthRequest request, String fileParamName, File file, Parameters params)
            throws IOException {
        ByteArrayOutputStream baos = null;
        OutputStream os = null;
        DataOutputStream dos = null;

        try {
            baos = new ByteArrayOutputStream();
            os = new BufferedOutputStream(baos);
            dos = new DataOutputStream(os);

            StreamUtils.StreamWriter writer = newStreamWriter(dos);

            String boundary = "----weiboclient4j-upload" + System.currentTimeMillis();
            request.addHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
            boundary = "--" + boundary;

            writeFile(writer, boundary, fileParamName, file);
            writeParameters(writer, boundary, params);
            writer.writeLine(boundary + "--").writeLine();

            dos.flush();

            request.addPayload(baos.toByteArray());
        } finally {
            closeQuietly(dos);
            closeQuietly(os);
            closeQuietly(baos);
        }
    }

    protected static void writeFile(StreamUtils.StreamWriter writer, String boundary, String fileParamName, File file)
            throws IOException {
        writer.writeLine(boundary)
                .writeLine(String.format("Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"",
                        fileParamName, file.getName()))
                .writeLine("Content-Type: " + getContentTypeFromImage(file))
                .writeLine()
                .writeFile(file);
    }

    protected static void writeParameters(StreamUtils.StreamWriter writer, String boundary,
                                          Parameters params) throws IOException {
        for (Parameters.Parameter param : params.getParameterList()) {
            writer.writeLine(boundary)
                    .writeLine("Content-Disposition: form-data; name=\"" + param.getKey() + "\"")
                    .writeLine("Content-Type: text/plain; charset=" + StringUtils.DEFAULT_ENCODING)
                    .writeLine()
                    .writeLine(param.getValue().getBytes(StringUtils.DEFAULT_ENCODING));
        }
    }

    protected static String getContentTypeFromImage(File imageFile) {
        String contentType = "image/jpeg";

        String fileName = imageFile.getName();

        if (isNotBlank(fileName)) {
            String lowerCaseFileName = fileName.toLowerCase();
            if (lowerCaseFileName.endsWith(".gif")) {
                contentType = "image/gif";
            } else if (lowerCaseFileName.endsWith(".png")) {
                contentType = "image/png";
            }
        }

        return contentType;
    }

    public WeiboClient getClient() {
        return client;
    }

    public void setAccessToken(SinaWeibo2AccessToken accessToken) {
        this.accessToken = accessToken;
    }

    public void setConnectTimeoutDuration(int connectTimeoutDuration) {
        this.connectTimeoutDuration = connectTimeoutDuration;
    }

    public void setConnectTimeoutUnit(TimeUnit connectTimeoutUnit) {
        this.connectTimeoutUnit = connectTimeoutUnit;
    }

    public void setReadTimeoutDuration(int readTimeoutDuration) {
        this.readTimeoutDuration = readTimeoutDuration;
    }

    public void setReadTimeoutUnit(TimeUnit readTimeoutUnit) {
        this.readTimeoutUnit = readTimeoutUnit;
    }

    public <T> T doGet(String path, Paging paging, Parameters params, Class<T> clazz) throws WeiboClientException {
        return sendRequestAndGetResponseObject(createGetRequest(path), paging, params, clazz);
    }

    public <T> T doGet(String path, Parameters params, Class<T> clazz) throws WeiboClientException {
        return sendRequestAndGetResponseObject(createGetRequest(path), params, clazz);
    }

    public <T> T doGet(String path, Paging paging, Class<T> clazz) throws WeiboClientException {
        return sendRequestAndGetResponseObject(createGetRequest(path), paging, clazz);
    }

    public <T> T doGet(String path, Class<T> clazz) throws WeiboClientException {
        return sendRequestAndGetResponseObject(createGetRequest(path), clazz);
    }

    public <T> List<T> doGet(String path, TypeReference<List<T>> typeReference) throws WeiboClientException {
        return sendRequestAndGetResponseObject(createGetRequest(path), typeReference);
    }

    public <T> List<T> doGet(String path, Paging paging, TypeReference<List<T>> typeReference)
            throws WeiboClientException {
        return sendRequestAndGetResponseObject(createGetRequest(path), paging, typeReference);
    }

    public <T> List<T> doGet(String path, Parameters params, TypeReference<List<T>> typeReference)
            throws WeiboClientException {
        return sendRequestAndGetResponseObject(createGetRequest(path), params, typeReference);
    }

    public <T> List<T> doGet(String path, Paging paging, Parameters params,
                             TypeReference<List<T>> typeReference) throws WeiboClientException {
        return sendRequestAndGetResponseObject(createGetRequest(path), paging, params, typeReference);
    }

    public <T> T doPost(String path, Paging paging, Parameters params, Class<T> clazz) throws WeiboClientException {
        return sendRequestAndGetResponseObject(createPostRequest(path), paging, params, clazz);
    }

    public <T> T doPost(String path, Parameters params, Class<T> clazz) throws WeiboClientException {
        return sendRequestAndGetResponseObject(createPostRequest(path), params, clazz);
    }

    public <T> T doPost(String path, Paging paging, Class<T> clazz) throws WeiboClientException {
        return sendRequestAndGetResponseObject(createPostRequest(path), paging, clazz);
    }

    public <T> T doPost(String path, Class<T> clazz) throws WeiboClientException {
        return sendRequestAndGetResponseObject(createPostRequest(path), clazz);
    }

    public <T> List<T> doPost(String path, Paging paging, Parameters params, TypeReference<List<T>> typeReference)
            throws WeiboClientException {
        return sendRequestAndGetResponseObject(createPostRequest(path), paging, params, typeReference);
    }

    public <T> List<T> doPost(String path, Parameters params, TypeReference<List<T>> typeReference)
            throws WeiboClientException {
        return sendRequestAndGetResponseObject(createPostRequest(path), params, typeReference);
    }

    public <T> List<T> doPost(String path, Paging paging, TypeReference<List<T>> typeReference)
            throws WeiboClientException {
        return sendRequestAndGetResponseObject(createPostRequest(path), paging, typeReference);
    }

    public <T> List<T> doPost(String path, TypeReference<List<T>> typeReference) throws WeiboClientException {
        return sendRequestAndGetResponseObject(createPostRequest(path), typeReference);
    }

    public <T> List<T> sendRequestAndGetResponseObject(OAuthRequest request,
                                                       Parameters params,
                                                       TypeReference<List<T>> typeReference)
            throws WeiboClientException {
        return sendRequestAndGetResponseObject(request, Paging.EMPTY, params, typeReference);
    }

    public <T> List<T> sendRequestAndGetResponseObject(OAuthRequest request, Paging paging,
                                                       TypeReference<List<T>> typeReference)
            throws WeiboClientException {
        return sendRequestAndGetResponseObject(request, paging, Parameters.create(), typeReference);
    }

    public <T> List<T> sendRequestAndGetResponseObject(OAuthRequest request, Paging paging, Parameters params,
                                                       TypeReference<List<T>> typeReference)
            throws WeiboClientException {
        if (paging != null) {
            params.add(paging);
        }

        params.appendTo(request);

        return sendRequestAndGetResponseObject(request, typeReference);
    }

    public <T> List<T> sendRequestAndGetResponseObject(OAuthRequest request, TypeReference<List<T>> typeReference)
            throws WeiboClientException {
        Response response = request.send();

        return parseJsonObject(response, typeReference);
    }

    public <T> T sendRequestAndGetResponseObject(OAuthRequest request, Parameters params, Class<T> clazz)
            throws WeiboClientException {
        return sendRequestAndGetResponseObject(request, Paging.EMPTY, params, clazz);
    }

    public <T> T sendRequestAndGetResponseObject(OAuthRequest request, Paging paging, Class<T> clazz)
            throws WeiboClientException {
        return sendRequestAndGetResponseObject(request, paging, Parameters.create(), clazz);
    }

    public <T> T sendRequestAndGetResponseObject(OAuthRequest request, Paging paging, Parameters params, Class<T> clazz)
            throws WeiboClientException {
        if (paging != null) {
            params.add(paging);
        }

        params.appendTo(request);

        return sendRequestAndGetResponseObject(request, clazz);
    }

    public <T> T sendRequestAndGetResponseObject(OAuthRequest request, Class<T> clazz) throws WeiboClientException {
        Response response = request.send();

        return parseJsonObject(response, clazz);
    }

    public OAuthRequest createGetRequest(String path) {
        return createRequest(Verb.GET, path);
    }

    public OAuthRequest createPostRequest(String path) {
        return createRequest(Verb.POST, path);
    }

    private OAuthRequest createRequest(Verb verb, String path) {
        OAuthRequest request = new OAuthRequest(verb, getFullPath(path));
        setRequestTimeout(request);
        setRequestAccessToken(request);

        return request;
    }

    private void setRequestTimeout(OAuthRequest request) {
        request.setConnectTimeout(connectTimeoutDuration, connectTimeoutUnit);
        request.setReadTimeout(readTimeoutDuration, readTimeoutUnit);
    }

    private void setRequestAccessToken(OAuthRequest request) {
        if (accessToken != null) {
            request.addHeader("Authorization", "OAuth2 " + accessToken.getToken());
        }
    }

    public String getFullPath(String path) {
        if (path.startsWith("http://") || path.startsWith("https://")) {
            return path;
        } else {
            return API2_URL + path + ".json";
        }
    }

    protected Map<String, String> mergeSingleItemMap(List<Map<String, String>> response) {
        Map<String, String> map = new HashMap<String, String>();
        for (Map<String, String> item : response) {
            map.putAll(item);
        }

        return map;
    }

    protected ParameterAction urlParam(final URL url) {
        return new ParameterAction() {
            public void addParameter(Parameters params) {
                if (url != null) {
                    params.add("url", url.toExternalForm());
                }
            }
        };
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    protected static class TagActionResponse {
        private long tagid;

        public static List<Long> toLongList(List<TagActionResponse> responseList) {
            List<Long> result = new ArrayList<Long>(responseList.size());
            for (TagActionResponse response : responseList) {
                result.add(response.getTagid());
            }

            return result;
        }

        public long getTagid() {
            return tagid;
        }

        public void setTagid(long tagid) {
            this.tagid = tagid;
        }
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    protected static class LongIdStringValue {
        private long id;

        private String value;

        public long getId() {
            return id;
        }

        public void setId(long id) {
            this.id = id;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    protected static class FollowTrendResponse {
        private long topicid;

        public long getTopicid() {
            return topicid;
        }

        public void setTopicid(long topicid) {
            this.topicid = topicid;
        }
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    protected static class UrlInfoResponse {
        private List<UrlInfo> urls;

        public List<UrlInfo> getUrls() {
            return urls;
        }

        public void setUrls(List<UrlInfo> urls) {
            this.urls = urls;
        }
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    protected static class UrlResponse {
        private List<Url> urls;

        public List<Url> getUrls() {
            return urls;
        }

        public void setUrls(List<Url> urls) {
            this.urls = urls;
        }
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    protected static class ResultResponse {
        private boolean result;

        public boolean isResult() {
            return result;
        }

        public void setResult(boolean result) {
            this.result = result;
        }
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    protected static class StatusResponse {
        private int status;

        public int getStatus() {
            return status;
        }

        public void setStatus(int status) {
            this.status = status;
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Category.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.LocationService;
import weiboclient4j.PlaceService;

/**
 * @author <NAME>
 */
public class Category extends StringParam implements
        PlaceService.GetNearbyPoisParam,
        PlaceService.SearchPoisParam,
        LocationService.SearchByLocationParam,
        LocationService.SearchByAreaParam {

    public Category(String value) {
        super(value);
    }

    protected String paramKey() {
        return "category";
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/CountType.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public enum CountType implements ParameterAction {
    Status("status"),
    Follower("follower"),
    Comment("cmt"),
    DirectMessage("dm"),
    MentionStatus("mention_status"),
    MentionComment("mention_cmt");

    private String value;

    CountType(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public void addParameter(Parameters params) {
        params.add("type", getValue());
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/FilterByType.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.StatusService;

import java.util.HashMap;
import java.util.Map;

/**
 * @author <NAME>
 */
public enum FilterByType implements
        StatusService.GetMentionsParam,
        StatusService.GetMentionsIdsParam {

    All(0), Original(1);

    private static Map<Integer, FilterByType> map = new HashMap<Integer, FilterByType>();

    static {
        for (FilterByType filterByType : FilterByType.values()) {
            map.put(filterByType.getValue(), filterByType);
        }
    }

    private int value;

    FilterByType(int value) {
        this.value = value;
    }

    public static FilterByType fromValue(int value) {
        return map.get(value);
    }

    public int getValue() {
        return value;
    }

    public void addParameter(Parameters params) {
        if (this != All) {
            params.add("filter_by_type", getValue());
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/RelationshipFilter.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.PlaceService;

/**
 * @author <NAME>
 */
public enum RelationshipFilter implements
        PlaceService.GetNearbyUsersListParam {
    All(0), StrangerOnly(1), Following(2);

    private int value;

    RelationshipFilter(int value) {
        this.value = value;
    }

    public void addParameter(Parameters params) {
        params.add("filter", value);
    }
}


<|start_filename|>src/main/java/weiboclient4j/oauth2/SinaWeibo2ServiceImpl.java<|end_filename|>
package weiboclient4j.oauth2;

import org.scribe.exceptions.OAuthException;
import org.scribe.model.OAuthConfig;
import org.scribe.model.OAuthConstants;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuth20ServiceImpl;
import weiboclient4j.WeiboClientException;
import weiboclient4j.WeiboError;
import weiboclient4j.utils.JsonUtils;

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author <NAME>
 */
public class SinaWeibo2ServiceImpl extends OAuth20ServiceImpl {
    public static final String GRANT_TYPE = "grant_type";

    public static final String USERNAME = "username";

    public static final String PASSWORD = "password";

    private static Logger log = Logger.getLogger(SinaWeibo2ServiceImpl.class.getName());

    private SinaWeibo2Api api;

    private OAuthConfig config;

    public SinaWeibo2ServiceImpl(SinaWeibo2Api api, OAuthConfig config) {
        super(api, config);

        this.api = api;
        this.config = config;
    }

    @Override
    public Token getAccessToken(Token requestToken, Verifier verifier) {
        OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint());
        request.addBodyParameter(OAuthConstants.CLIENT_ID, config.getApiKey());
        request.addBodyParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret());
        request.addBodyParameter(GRANT_TYPE, api.getGrantType().getType());

        if (api.getGrantType() == GrantType.AuthorizationCode) {
            request.addBodyParameter(OAuthConstants.CODE, verifier.getValue());
            request.addBodyParameter(OAuthConstants.REDIRECT_URI, config.getCallback());
        } else if (api.getGrantType() == GrantType.Password && requestToken != null) {
            request.addBodyParameter(USERNAME, requestToken.getToken());
            request.addBodyParameter(PASSWORD, requestToken.getSecret());
        }

        Response response = request.send();
        String responseBody = response.getBody();

        if (!response.isSuccessful()) {
            try {
                WeiboError error = JsonUtils.readValue(responseBody, WeiboError.class);
                if (error.isNotEmpty()) {
                    throw new OAuthException("Failed with weibo error", new WeiboClientException(error));
                }
            } catch (IOException e) {
                log.log(Level.WARNING, String.format("Failed to parse response: %d, %s", response.getCode(),
                        responseBody));
            }

            return null;
        }

        return api.getAccessTokenExtractor().extract(responseBody);
    }
}


<|start_filename|>src/main/java/weiboclient4j/WeiboError.java<|end_filename|>
package weiboclient4j;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import static weiboclient4j.utils.StringUtils.isBlank;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class WeiboError {
    // http://open.weibo.com/wiki/Error_code
    public static final int ERR_SYSTEM = 10001;

    public static final int ERR_SERVICE_UNAVAILABLE = 10002;

    public static final int ERR_REMOTE_SERVICE = 10003;

    public static final int ERR_IP_LIMIT = 10004;

    public static final int ERR_PERMISSION_DENIED = 10005;

    public static final int ERR_MISSING_APPKEY = 10006;

    public static final int ERR_UNSUPPORTED_MEDIA_TYPE = 10007;

    public static final int ERR_PARAMETER = 10008;

    public static final int ERR_SYSTEM_BUSY = 10009;

    public static final int ERR_JOB_EXPIRED = 10010;

    public static final int ERR_RPC = 10011;

    public static final int ERR_ILLEGAL_REQUEST = 10012;

    public static final int ERR_INVALID_WEIBO_USER = 10013;

    public static final int ERR_INSUFFICIENT_PERMISSIONS = 10014;

    public static final int ERR_MISS_REQUIRED_PARAMETER = 10016;

    public static final int ERR_INVALID_PARAMETER_VALUE = 10017;

    public static final int ERR_REQUEST_BODY_EXCEED = 10018;

    public static final int ERR_API_NOT_FOUND = 10020;

    public static final int ERR_HTTP_METHOD_NOT_SUPPORTED = 10021;

    public static final int ERR_IP_OUT_OF_RATE_LIMIT = 10022;

    public static final int ERR_USER_OUT_OF_RATE_LIMIT = 10023;

    public static final int ERR_USER_OUT_OF_RATE_LIMIT_SPECIAL = 10024;

    public static final int ERR_IDS_IS_NULL = 20001;

    public static final int ERR_UID_IS_NULL = 20002;

    public static final int ERR_USER_NOT_EXISTS = 20003;

    public static final int ERR_UNSUPPORTED_IMAGE_TYPE = 20005;

    public static final int ERR_IMAGE_TOO_LARGE = 20006;

    public static final int ERR_NO_IMAGE_IN_MULTIPART = 20007;

    public static final int ERR_CONTENT_IS_NULL = 20008;

    public static final int ERR_TOO_MUCH_IDS = 20009;

    public static final int ERR_TEXT_LONGER_THAN_140 = 20012;

    public static final int ERR_TEXT_LONGER_THAN_300 = 20013;

    public static final int ERR_SECURITY_PARAMETER = 20014;

    public static final int ERR_INVALID_ACCOUNT_IP_APP = 20015;

    public static final int ERR_UPDATE_OUT_OF_LIMIT = 20016;

    public static final int ERR_SIMILAR_CONTENT = 20017;

    public static final int ERR_CONTAINS_ILLEGAL_WEBSITE = 20018;

    public static final int ERR_DUPLICATED_CONTENT = 20019;

    public static final int ERR_CONTAINS_ADVERTISING = 20020;

    public static final int ERR_CONTAINS_ILLEGAL_CONTENT = 20021;

    public static final int ERR_IP_ABNORMAL_BEHAVIOR = 20022;

    public static final int ERR_VERIFICATION_CODE_REQUIRED = 20031;

    public static final int ERR_SUCCESS_BUT_MAY_DELAY = 20032;

    public static final int ERR_STATUS_NOT_FOUND = 20101;

    public static final int ERR_NOT_OWNER_OF_STATUS = 20102;

    public static final int ERR_CANNOT_REPOST_SELF_STATUS = 20103;

    public static final int ERR_ILLEGAL_STATUS = 20104;

    public static final int ERR_STATUS_ID_IS_NULL = 20109;

    public static final int ERR_DUPLICATED_STATUS_TEXT = 20111;

    public static final int ERR_COMMENT_NOT_FOUND = 20201;

    public static final int ERR_ILLEGAL_COMMENT = 20202;

    public static final int ERR_NOT_OWNER_OF_COMMENT = 20203;

    public static final int ERR_COMMENT_ID_IS_NULL = 20204;

    public static final int ERR_CANNOT_SEND_DIRECT_MESSAGE_TO_NOT_FOLLOWER = 20301;

    public static final int ERR_ILLEGAL_DIRECT_MESSAGE = 20302;

    public static final int ERR_NOT_OWNER_OF_DIRECT_MESSAGE = 20303;

    public static final int ERR_DIRECT_MESSAGE_NOT_FOUND = 20305;

    public static final int ERR_DUPLICATED_DIRECT_MESSAGE = 20306;

    public static final int ERR_INVALID_DIRECT_MESSAGE_ID = 20307;

    public static final int ERR_DOMAIN_NOT_FOUND = 20401;

    public static final int ERR_INVALID_VERIFIER = 20402;

    public static final int ERR_SOURCE_OR_TARGET_USER_NOT_FOUND = 20501;

    public static final int ERR_TARGET_USER_ID_OR_SCREEN_NAME_REQUIRED = 20502;

    public static final int ERR_USER_ID_SHOULD_BE_YOUR_FOLLOWER = 20503;

    public static final int ERR_CANNOT_FOLLOW_YOURSELF = 20504;

    public static final int ERR_SOCIAL_GRAPH_UPDATES_OUT_OF_RATE_LIMIT = 20505;

    public static final int ERR_ALREADY_FOLLOWED = 20506;

    public static final int ERR_PLEASE_INPUT_VERIFICATION_CODE = 20507;

    public static final int ERR_ACTION_PROHIBITED_ACCORDING_TO_USER_PRIVACY = 20508;

    public static final int ERR_QUIETLY_FOLLOW_COUNT_EXCEED = 20509;

    public static final int ERR_NOT_QUIETLY_FRIEND = 20510;

    public static final int ERR_ALREADY_QUIETLY_FOLLOWED = 20511;

    public static final int ERR_USER_IN_YOUR_BLACK_LIST = 20512;

    public static final int ERR_FRIENDS_COUNT_EXCEED = 20513;

    public static final int ERR_FOLLOWING_TOO_MANY = 20521;

    public static final int ERR_NOT_FOLLOWED = 20522;

    public static final int ERR_NOT_FOLLOWERS = 20523;

    public static final int ERR_CANCEL_FOLLOW_TOO_MANY = 20524;

    public static final int ERR_LIST_NAME_TOO_LONG = 20601;

    public static final int ERR_LIST_DESCRIPTION_TOO_LONG = 20602;

    public static final int ERR_LIST_NOT_FOUND = 20603;

    public static final int ERR_NOT_LIST_OWNER = 20604;

    public static final int ERR_ILLEGAL_LIST_NAME_OR_DESCRIPTION = 20605;

    public static final int ERR_OBJECT_ALREADY_EXISTS = 20606;

    public static final int ERR_DB_ERROR = 20607;

    public static final int ERR_LIST_NAME_DUPLICATED = 20608;

    public static final int ERR_PRIVATE_LIST_NOT_SUPPORTED = 20610;

    public static final int ERR_FAILED_CREATING_LIST = 20611;

    public static final int ERR_ONLY_PRIVATE_LIST_SUPPORTED = 20612;

    public static final int ERR_SUBSCRIBED_TOO_MANY_LISTS = 20613;

    public static final int ERR_TOO_MANY_LISTS = 20614;

    public static final int ERR_TOO_MANY_LIST_MEMBERS = 20615;

    public static final int ERR_DUPLICATED_TAG = 20701;

    public static final int ERR_TOO_MANY_TAGS = 20702;

    public static final int ERR_ILLEGAL_TAG_NAME = 20703;

    public static final int ERR_TREND_NAME_IS_NULL = 20801;

    public static final int ERR_TREND_ID_IS_NULL = 20802;

    public static final int ERR_ALREADY_IN_BLACK_LIST = 20901;

    public static final int ERR_BLACK_LIST_COUNT_EXCEED = 20902;

    public static final int ERR_CANNOT_ADD_SYSTEM_ADMINISTRATOR_TO_BLACK_LIST = 20903;

    public static final int ERR_CANNOT_ADD_YOURSELF_TO_BLACK_LIST = 20904;

    public static final int ERR_NOT_IN_BLACK_LIST = 20905;

    public static final int ERR_TAG_PARAMETER_IS_NULL = 21001;

    public static final int ERR_TAG_NAME_TOO_LONG = 21002;

    public static final int ERR_DOMAIN_PARAMETER = 21101;

    public static final int ERR_PHONE_NUMBER_HAS_BEEN_USED = 21102;

    public static final int ERR_ACCOUNT_ALREADY_BIND_PHONE_NUMBER = 21103;

    public static final int ERR_WRONG_VERIFIER = 21104;

    public static final int ERR_AUTH_FAILED = 21301;

    public static final int ERR_INVALID_USERNAME_OR_PASSWORD = <PASSWORD>;

    public static final int ERR_PASSWORD_AUTH_OUT_OF_RATE_LIMIT = 21303;

    public static final int ERR_VERSION_REJECTED = 21304;

    public static final int ERR_PARAMETER_ABSENT = 21305;

    public static final int ERR_OAUTH_PARAMETER_REJECTED = 21306;

    public static final int ERR_INVALID_TIMESTAMP = 21307;

    public static final int ERR_NONCE_HAS_BEEN_USED = 21308;

    public static final int ERR_SIGNATURE_ALGORITHM_REJECTED = 21309;

    public static final int ERR_INVALID_SIGNATURE = 21310;

    public static final int ERR_UNKNOWN_CONSUMER_KEY = 21311;

    public static final int ERR_CONSUMER_KEY_REJECTED = 21312;

    public static final int ERR_CONSUMER_KEY_REQUIRED = 21313;

    public static final int ERR_TOKEN_HAS_BEEN_USED = 21314;

    public static final int ERR_TOKEN_EXPIRED = 21315;

    public static final int ERR_TOKEN_REVOKED = 21316;

    public static final int ERR_TOKEN_REJECTED = 21317;

    public static final int ERR_VERIFIER_FAILED = 21318;

    public static final int ERR_ACCESSOR_REVOKED = 21319;

    public static final int ERR_OATH2_ONLY_SUPPORTS_HTTPS = 21320;

    public static final int ERR_UNAUDITED_APP_USERS_COUNT_EXCEED = 21321;

    public static final int ERR_EXPIRED_TOKEN = 21327;

    public static final int ERR_URLS_IS_NULL = 21501;

    public static final int ERR_TOO_MANY_URLS = 21502;

    public static final int ERR_IP_IS_NULL = 21503;

    public static final int ERR_URL_IS_NULL = 21504;

    public static final int ERR_ADMINISTRATOR_PERMISSION_REQUIRED = 21601;

    public static final int ERR_CONTAINS_FORBIDDEN_WORDS = 21602;

    public static final int ERR_SEND_NOTIFICATIONS_EXCEED = 21603;

    public static final int ERR_REMIND_FAILED_WITHOUT_PERMISSION = 21701;

    public static final int ERR_INVALID_CATEGORY = 21702;

    public static final int ERR_INVALID_STATUS_CODE = 21703;

    public static final int ERR_INVALID_GEO_CODE = 21901;

    private String request;

    private String errorCode;

    private String error;

    public boolean isNotEmpty() {
        return !(isBlank(request) && isBlank(errorCode) && isBlank(error));
    }

    public String getRequest() {
        return request;
    }

    public void setRequest(String request) {
        this.request = request;
    }

    public String getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(String errorCode) {
        this.errorCode = errorCode;
    }

    public int getErrorCodeAsInt() {
        return Integer.parseInt(errorCode);
    }

    public String getError() {
        return error;
    }

    @Override
    public String toString() {
        return String.format("%s: %s", errorCode, error);
    }

    public void setError(String error) {
        this.error = error;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/SourceUid.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public class SourceUid extends LongParam {
    public static final SourceUid EMPTY = new SourceUid(0);

    public SourceUid(long value) {
        super(value);
    }

    public SourceUid(String value) {
        super(value);
    }

    protected String paramKey() {
        return "source_id";
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParseTagTest.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.JsonNode;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import static weiboclient4j.utils.JsonUtils.readValue;

import java.util.List;

/**
 * @author <NAME>
 */
public class ParseTagTest extends AbstractParseJsonTest {

    @Test
    public void testParseTests() throws Exception {
        String content = readResource("/weiboclient4j/model/tags.json");

        List<Tag> tags = Tag.parseTags(readValue(content, JsonNode.class));
        assertNotNull(tags);

        Tag tag = tags.get(0);
        assertTrue(tag.getId() > 0);
        assertTrue(tag.getWeight() > 0);
    }
}


<|start_filename|>src/main/java/weiboclient4j/utils/StringUtils.java<|end_filename|>
package weiboclient4j.utils;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;

/**
 * @author <NAME>
 */
public final class StringUtils {

    public static final String DEFAULT_ENCODING = "UTF-8";

    private StringUtils() {
    }

    public static boolean isBlank(String value) {
        return !isNotBlank(value);
    }

    public static boolean isNotBlank(String value) {
        return value != null && value.trim().length() > 0;
    }

    public static String join(Collection<String> strings, String sep) {
        StringBuilder buf = new StringBuilder();
        for (String str : strings) {
            buf.append(sep).append(str);
        }

        return buf.substring(sep.length());
    }

    public static String join(Object[] array, String sep) {
        return join(toStringArray(array), sep);
    }

    public static Collection<String> toStringArray(Object[] array) {
        Collection<String> result = new ArrayList<String>(array.length);
        for (Object coordinate : array) {
            result.add(coordinate.toString());
        }

        return result;
    }

    public static String encodeUrl(String url) {
        try {
            return URLEncoder.encode(url, DEFAULT_ENCODING);
        } catch (UnsupportedEncodingException ignore) {
            return url;
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/UserLevel.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.PlaceService;

/**
 * @author <NAME>
 */
public enum UserLevel implements
        PlaceService.GetNearbyUsersListParam {
    All(0), Normal(1), VIP(2), Talent(7);

    private int value;

    UserLevel(int value) {
        this.value = value;
    }

    public void addParameter(Parameters params) {
        params.add("level", value);
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Latitude.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.StatusService;

/**
 * @author <NAME>
 */
public class Latitude extends FloatParam implements StatusService.UploadImageUrlParam {
    public Latitude(float value) {
        super(value);
    }

    protected String paramKey() {
        return "lat";
    }
}


<|start_filename|>src/test/resources/weiboclient4j/model/poi.json<|end_filename|>
{
  "poiid": "B2094654D16CABFE419E",
  "title": "理想国际大厦",
  "address": "北四环西路58号理想国际大厦",
  "lon": "116.30987",
  "lat": "39.98437",
  "category": "46",
  "city": "0010",
  "province": "",
  "country": "",
  "url": "http://hotel.qunar.com/city/beijing_city/dt-2904/",
  "phone": "010-82607123",
  "postcode": "100000",
  "weibo_id": "2513895201",
  "icon": "http://u1.sinaimg.cn/upload/lbs/poi/icon/88/46.png",
  "extra": "从银锭桥旁刻着“银锭观山”的大石头向西，沿湖边走下去，直到你认为前面不会再有酒吧的时候，“左岸”就快到了。左岸是前海北沿最靠南的一家，也是什刹海酒吧中的“前辈”。它的风格、品位跟它的地理位置一样，与其他酒吧拉开一段距离，如同一台戏的大轴，赫然、笃定地缀在最后。“左岸”门前有个院子，正对前海湖心的小岛，可惜有一排绿化带挡住了大部分视线。小院用铁栅栏围成，很规矩，不像其它店铺跑到街上占地盘。院里摆放了露天的座位，周围种着竹子，大理石碎片铺地，收拾得一尘不染，那棵粗大的古树一定是夏季最好的天然遮阳伞。走进竹林掩映的小院，迎面是一个通透、敞亮的大房间。墙壁涂成绿茶奶昔的颜色，家具和梁柱像深深浅浅的朱古力。除了青花瓷缸里的红色金鱼在不知疲倦地游走，老式英文打字机沉默着，流泪到天明的蜡烛沉默着，一捧怒放的白百合也沉默着……那股静若处子的淡定，实在不像酒吧，更像是一间书房或画室。惟有墙角深褐色的旧皮箱出卖了主人的浪子情怀，它收藏着放肆、狂野和反叛，让自己的心随时远走高飞。“左岸”的大门是仿古的，通常是关着的，门口守着一对麒麟。进门处有个小方几，放着一台erika牌的打字机，周围是各种允许客人带走的直投杂志。大门正对着的是一张旧条案，上面总是摆着一大捧漂亮的、叫不出名字的鲜花；中间有个大瓷盘，几尾小金鱼在里面快活地游着。这里的蜡烛给人留下很深的印象，即使在没有客人的下午，也会照样点燃。各式的蜡托很有趣，有杯子、小灯笼，条案上的那对圆柱体大蜡烛放在摆满雨花石的方形碟子里，挺有味儿。大多数来过“左岸”的客人都很喜欢这里的沙发，确实舒服，质量也很好，不会因为超载而变形。室内的墙壁刷成柠檬色，光线柔和。座位的组台共分七个大小不同的区域，每一块都有一盏大罩子的台灯。主人是搞音乐的，这里播放的都是精心挑选的音乐，一点儿也不闹。为了保持安静的气氛，店里规定不许玩牌。从靠墙的窗户向外看是后院，小院非常整洁，听说是郁达夫的故居，现在是什刹海的社区居委会。别看总有正在装修的新酒吧，可经常被吧虫挂嘴边的往往是那几个元老级的。现在的“左岸”以前叫“蓝莲花”，被公认为什刹海最早的酒吧。酒吧里的音乐就像它的主人，一点儿都不闹腾，而且是花心思了的。屋里院里都可以坐，不管是哪儿，都安静整洁，适合跟朋友聊天。披着夏日的夕阳走来，这里会有怡神的清凉。门口为常客准备了chinadaily的beijingweekend。永远的richie低声吟唱着永远的“sayyou，sayme”。装在高脚杯里的爱尔兰咖啡，因为对了酒，香得更加浓烈。一大杯的香蕉奶昔，放不放糖听你的，常常是女孩子的第一选择。",
  "rid": "46",
  "categorys": "44 46",
  "category_name": "楼宇",
  "checkin_num": 3114,
  "checkin_user_num": "1315",
  "tip_num": 3080,
  "photo_num": 1119,
  "todo_num": 106
}


<|start_filename|>src/main/java/weiboclient4j/model/Favorites.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class Favorites {
    private List<FavoritesItem> favorites;
    private int totalNumber;

    public List<FavoritesItem> getFavorites() {
        return favorites;
    }

    public void setFavorites(List<FavoritesItem> favorites) {
        this.favorites = favorites;
    }

    public int getTotalNumber() {
        return totalNumber;
    }

    public void setTotalNumber(int totalNumber) {
        this.totalNumber = totalNumber;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/Notification.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

import java.util.Date;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class Notification {
    private long notificationId;
    private String title;
    private String content;
    private Date createdAt;
    private SenderApp senderApp;
    private long senderUid;

    public long getNotificationId() {
        return notificationId;
    }

    public void setNotificationId(long notificationId) {
        this.notificationId = notificationId;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    public SenderApp getSenderApp() {
        return senderApp;
    }

    public void setSenderApp(SenderApp senderApp) {
        this.senderApp = senderApp;
    }

    public long getSenderUid() {
        return senderUid;
    }

    public void setSenderUid(long senderUid) {
        this.senderUid = senderUid;
    }
}


<|start_filename|>src/main/java/weiboclient4j/FriendshipService.java<|end_filename|>
package weiboclient4j;

import weiboclient4j.model.Friendship;
import weiboclient4j.model.User;
import weiboclient4j.model.UserIdList;
import weiboclient4j.model.UserList;
import weiboclient4j.params.Paging;
import weiboclient4j.params.Remark;
import weiboclient4j.params.ScreenName;
import weiboclient4j.params.SourceScreenName;
import weiboclient4j.params.SourceUid;
import weiboclient4j.params.Suid;
import weiboclient4j.params.TargetScreenName;
import weiboclient4j.params.TargetUid;
import weiboclient4j.params.Uid;

/**
 * @author <NAME>
 */
public class FriendshipService extends AbstractService {

    public FriendshipService(WeiboClient client) {
        super(client);
    }

    public UserList getFriends(Uid uid) throws WeiboClientException {
        return getFriends(uid, Paging.EMPTY);
    }

    public UserList getFriends(Uid uid, Paging paging) throws WeiboClientException {
        return getFriends(uid, ScreenName.EMPTY, paging);
    }

    public UserList getFriends(ScreenName screenName) throws WeiboClientException {
        return getFriends(screenName, Paging.EMPTY);
    }

    public UserList getFriends(ScreenName screenName, Paging paging) throws WeiboClientException {
        return getFriends(Uid.EMPTY, screenName, paging);
    }

    private UserList getFriends(Uid uid, ScreenName screenName, Paging paging) throws WeiboClientException {
        return doGet("friendships/friends",
                paging, withParams(uid, screenName), UserList.class);
    }

    public UserIdList getFriendsIds(Uid uid) throws WeiboClientException {
        return getFriendsIds(uid, Paging.EMPTY);
    }

    public UserIdList getFriendsIds(Uid uid, Paging paging) throws WeiboClientException {
        return getFriendsIds(uid, ScreenName.EMPTY, paging);
    }

    public UserIdList getFriendsIds(ScreenName screenName) throws WeiboClientException {
        return getFriendsIds(screenName, Paging.EMPTY);
    }

    public UserIdList getFriendsIds(ScreenName screenName, Paging paging) throws WeiboClientException {
        return getFriendsIds(Uid.EMPTY, screenName, paging);
    }

    private UserIdList getFriendsIds(Uid uid, ScreenName screenName, Paging paging) throws WeiboClientException {
        return doGet("friendships/friends/ids",
                paging, withParams(uid, screenName), UserIdList.class);
    }

    public UserList getFriendsInCommon(Uid uid) throws WeiboClientException {
        return getFriendsInCommon(uid, Suid.EMPTY);
    }

    public UserList getFriendsInCommon(Uid uid, Paging paging) throws WeiboClientException {
        return getFriendsInCommon(uid, Suid.EMPTY, paging);
    }

    public UserList getFriendsInCommon(Uid uid, Suid suid) throws WeiboClientException {
        return getFriendsInCommon(uid, suid, Paging.EMPTY);
    }

    public UserList getFriendsInCommon(Uid uid, Suid suid, Paging paging) throws WeiboClientException {
        return doGet("friendships/friends/in_common",
                paging, withParams(uid, suid), UserList.class);
    }

    public UserList getFriendsBilateral(Uid uid) throws WeiboClientException {
        return getFriendsBilateral(uid, Paging.EMPTY);
    }

    public UserList getFriendsBilateral(Uid uid, Paging paging) throws WeiboClientException {
        return doGet("friendships/friends/bilateral",
                paging, withParams(uid), UserList.class);
    }

    public UserIdList getFriendsBilateralIds(Uid uid) throws WeiboClientException {
        return getFriendsBilateralIds(uid, Paging.EMPTY);
    }

    public UserIdList getFriendsBilateralIds(Uid uid, Paging paging) throws WeiboClientException {
        return doGet("friendships/friends/bilateral/ids",
                paging, withParams(uid), UserIdList.class);
    }

    public UserList getFollowers(ScreenName screenName) throws WeiboClientException {
        return getFollowers(screenName, Paging.EMPTY);
    }

    public UserList getFollowers(ScreenName screenName, Paging paging) throws WeiboClientException {
        return getFollowers(Uid.EMPTY, screenName, paging);
    }

    public UserList getFollowers(Uid uid) throws WeiboClientException {
        return getFollowers(uid, Paging.EMPTY);
    }

    public UserList getFollowers(Uid uid, Paging paging) throws WeiboClientException {
        return getFollowers(uid, ScreenName.EMPTY, paging);
    }

    public UserList getFollowers(Uid uid, ScreenName screenName, Paging paging) throws WeiboClientException {
        return doGet("friendships/followers",
                paging, withParams(uid, screenName), UserList.class);
    }

    public UserIdList getFollowersIds(ScreenName screenName) throws WeiboClientException {
        return getFollowersIds(screenName, Paging.EMPTY);
    }

    public UserIdList getFollowersIds(ScreenName screenName, Paging paging) throws WeiboClientException {
        return getFollowersIds(Uid.EMPTY, screenName, paging);
    }

    public UserIdList getFollowersIds(Uid uid) throws WeiboClientException {
        return getFollowersIds(uid, Paging.EMPTY);
    }

    public UserIdList getFollowersIds(Uid uid, Paging paging) throws WeiboClientException {
        return getFollowersIds(uid, ScreenName.EMPTY, paging);
    }

    public UserIdList getFollowersIds(Uid uid, ScreenName screenName, Paging paging) throws WeiboClientException {
        return doGet("friendships/followers/ids",
                paging, withParams(uid, screenName), UserIdList.class);
    }

    public UserList getActiveFollowers(Uid uid) throws WeiboClientException {
        return getActiveFollowers(uid, Paging.EMPTY);
    }

    public UserList getActiveFollowers(Uid uid, Paging paging) throws WeiboClientException {
        return doGet("friendships/followers/active",
                paging, withParams(uid), UserList.class);
    }

    public UserList getChainFollowers(Uid uid) throws WeiboClientException {
        return getChainFollowers(uid, Paging.EMPTY);
    }

    public UserList getChainFollowers(Uid uid, Paging paging) throws WeiboClientException {
        return doGet("friendships/friends_chain/followers",
                paging, withParams(uid), UserList.class);
    }

    public Friendship show(SourceUid sourceUid, TargetUid targetUid) throws WeiboClientException {
        return show(sourceUid, SourceScreenName.EMPTY, targetUid, TargetScreenName.EMPTY);
    }

    public Friendship show(SourceScreenName sourceScreenName, TargetScreenName targetScreenName)
            throws WeiboClientException {
        return show(SourceUid.EMPTY, sourceScreenName, TargetUid.EMPTY, targetScreenName);
    }

    public Friendship show(SourceUid sourceUid, SourceScreenName sourceScreenName,
                           TargetUid targetUid, TargetScreenName targetScreenName) throws WeiboClientException {
        return doGet("friendships/show",
                withParams(sourceUid, sourceScreenName, targetUid, targetScreenName), Friendship.class);
    }

    public User create(Uid uid) throws WeiboClientException {
        return create(uid, ScreenName.EMPTY);
    }

    public User create(ScreenName screenName) throws WeiboClientException {
        return create(Uid.EMPTY, screenName);
    }

    public User create(Uid uid, ScreenName screenName) throws WeiboClientException {
        return doPost("friendships/create",
                withParams(uid, screenName), User.class);
    }

    public User destroy(Uid uid) throws WeiboClientException {
        return destroy(uid, ScreenName.EMPTY);
    }

    public User destroy(ScreenName screenName) throws WeiboClientException {
        return destroy(Uid.EMPTY, screenName);
    }

    public User destroy(Uid uid, ScreenName screenName) throws WeiboClientException {
        return doPost("friendships/destroy",
                withParams(uid, screenName), User.class);
    }

    public User updateRemark(Uid uid, Remark remark) throws WeiboClientException {
        return doPost("friendships/remark/update",
                withParams(uid, remark), User.class);
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/IsPublic.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public enum IsPublic implements ParameterAction {
    Yes(1), No(0);

    private int value;

    IsPublic(int value) {
        this.value = value;
    }

    public void addParameter(Parameters params) {
        params.add("public", value);
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/Count.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.type.TypeReference;

import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class Count {
    public static final TypeReference<List<Count>> TYPE_COUNT_LIST = new TypeReference<List<Count>>() {
    };

    private long id;
    private int comments;
    private int reposts;
    private int attitudes;

    // API V1 fields
    private int rt;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public int getComments() {
        return comments;
    }

    public void setComments(int comments) {
        this.comments = comments;
    }

    public int getRt() {
        return rt;
    }

    public void setRt(int rt) {
        this.rt = rt;
    }

    public int getReposts() {
        return reposts;
    }

    public void setReposts(int reposts) {
        this.reposts = reposts;
    }

    public int getAttitudes() {
        return attitudes;
    }

    public void setAttitudes(int attitudes) {
        this.attitudes = attitudes;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/Comment.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.type.TypeReference;

import java.util.Date;
import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class Comment {
    public static final TypeReference<List<Comment>> TYPE_COMMENT_LIST = new TypeReference<List<Comment>>() {
    };

    private long id;
    private String idstr;
    private String text;
    private String source;
    private boolean favorited;
    private boolean truncated;
    private Date createdAt;
    private User user;
    private Status status;
    private Comment replyComment;
    private String mid;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getIdstr() {
        return idstr;
    }

    public void setIdstr(String idstr) {
        this.idstr = idstr;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public String getSource() {
        return source;
    }

    public void setSource(String source) {
        this.source = source;
    }

    public boolean isFavorited() {
        return favorited;
    }

    public void setFavorited(boolean favorited) {
        this.favorited = favorited;
    }

    public boolean isTruncated() {
        return truncated;
    }

    public void setTruncated(boolean truncated) {
        this.truncated = truncated;
    }

    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    public Comment getReplyComment() {
        return replyComment;
    }

    public void setReplyComment(Comment replyComment) {
        this.replyComment = replyComment;
    }

    public String getMid() {
        return mid;
    }

    public void setMid(String mid) {
        this.mid = mid;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Cid.java<|end_filename|>
package weiboclient4j.params;

import static weiboclient4j.utils.StringUtils.join;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author <NAME>
 */
public class Cid extends LongParam {
    public Cid(long value) {
        super(value);
    }

    public Cid(String value) {
        super(value);
    }

    protected String paramKey() {
        return "cid";
    }

    public static ParameterAction cidsParam(final Collection<Cid> cids) {
        return new ParameterAction() {
            public void addParameter(Parameters params) {
                if (cids != null && cids.size() > 0) {
                    List<String> idList = new ArrayList<String>();
                    for (Cid cid : cids) {
                        if (cid.isValid()) {
                            idList.add(String.valueOf(cid.getValue()));
                        }
                    }
                    String idListString = join(idList, ",");
                    params.add("cids", idListString);
                }
            }
        };
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Remark.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public class Remark extends StringParam {
    public Remark(String value) {
        super(value);
    }

    protected String paramKey() {
        return "remark";
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/TagName.java<|end_filename|>
package weiboclient4j.params;

import static weiboclient4j.utils.StringUtils.join;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author <NAME>
 */
public class TagName extends StringParam {
    public TagName(String value) {
        super(value);
    }

    protected String paramKey() {
        return "tag";
    }

    public static ParameterAction tagsParam(final Collection<TagName> tags) {
        return new ParameterAction() {
            public void addParameter(Parameters params) {
                if (tags != null && tags.size() > 0) {
                    List<String> tagList = new ArrayList<String>(tags.size());
                    for (TagName tag : tags) {
                        if (tag.isValid()) {
                            tagList.add(tag.getValue());
                        }
                    }
                    params.add("tags", join(tagList, ","));
                }
            }
        };
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/PicId.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.utils.StringUtils;

public class PicId extends StringParam {
    public PicId(String... picIdList) {
        super(StringUtils.join(picIdList, ","));
    }

    protected String paramKey() {
        return "pic_id";
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/AbstractParseJsonTest.java<|end_filename|>
package weiboclient4j.model;

import java.io.*;

/**
 * @author <NAME>
 */
public abstract class AbstractParseJsonTest {
    protected String readResource(String path) throws Exception {
        BufferedReader reader = null;
        StringWriter result;
        try {
            InputStream inputStream = getClass().getResourceAsStream(path);
            reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));

            result = new StringWriter();
            PrintWriter out = new PrintWriter(result);

            String line;
            while ((line = reader.readLine()) != null) {
                out.println(line);
            }
        } finally {
            if (reader != null) {
                reader.close();
            }
        }

        return result.toString();
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Tid.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public class Tid extends LongParam {
    public Tid(long value) {
        super(value);
    }

    protected String paramKey() {
        return "tid";
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Suid.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public class Suid extends LongParam {
    public static final Suid EMPTY = new Suid(0);

    public Suid(long value) {
        super(value);
    }

    public Suid(String value) {
        super(value);
    }

    protected String paramKey() {
        return "suid";
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Address.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.PlaceService;

/**
 * @author <NAME>
 */
public class Address extends StringParam implements
        PlaceService.CreatePoiParam {

    public Address(String value) {
        super(value);
    }

    protected String paramKey() {
        return "address";
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/LocationPoi.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

import java.math.BigDecimal;

@JsonIgnoreProperties(ignoreUnknown = true)
public class LocationPoi {
    private String pid;
    private BigDecimal longitude;
    private BigDecimal latitude;
    private String name;
    private String cityName;
    private String provinceName;
    private String address;
    private String telephone;
    private String category;
    private String navigator;
    private String picUrl;

    public String getPid() {
        return pid;
    }

    public void setPid(String pid) {
        this.pid = pid;
    }

    public BigDecimal getLongitude() {
        return longitude;
    }

    public void setLongitude(BigDecimal longitude) {
        this.longitude = longitude;
    }

    public BigDecimal getLatitude() {
        return latitude;
    }

    public void setLatitude(BigDecimal latitude) {
        this.latitude = latitude;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCityName() {
        return cityName;
    }

    public void setCityName(String cityName) {
        this.cityName = cityName;
    }

    public String getProvinceName() {
        return provinceName;
    }

    public void setProvinceName(String provinceName) {
        this.provinceName = provinceName;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getNavigator() {
        return navigator;
    }

    public void setNavigator(String navigator) {
        this.navigator = navigator;
    }

    public String getPicUrl() {
        return picUrl;
    }

    public void setPicUrl(String picUrl) {
        this.picUrl = picUrl;
    }
}


<|start_filename|>src/main/java/weiboclient4j/oauth2/SinaWeibo2AccessTokenExtractor.java<|end_filename|>
package weiboclient4j.oauth2;

import org.scribe.extractors.AccessTokenExtractor;
import org.scribe.model.Token;
import weiboclient4j.WeiboClientException;
import static weiboclient4j.utils.JsonUtils.parseJsonObject;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author <NAME>
 */
public class SinaWeibo2AccessTokenExtractor implements AccessTokenExtractor {
    private static Logger log = Logger.getLogger("weiboclient2/access_token_extractor");

    public Token extract(String response) {
        try {
            SinaWeibo2AccessTokenResponse tokenResponse =
                    parseJsonObject(response, SinaWeibo2AccessTokenResponse.class);
            return new SinaWeibo2AccessToken(tokenResponse);
        } catch (WeiboClientException e) {
            log.log(Level.WARNING, "Failed to parse access token response: " + e.getMessage(), e);
            return null;
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Visible.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.StatusService;

/**
 * @author <NAME>
 */
public enum Visible implements StatusService.UploadImageUrlParam {
    All(0), Myself(1), CloseFriend(2), List(3);

    private int value;

    Visible(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    @Override
    public void addParameter(Parameters params) {
        if (this != All) {
            params.add("visible", getValue());
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/FriendshipType.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.PlaceService;

/**
 * @author <NAME>
 */
public enum FriendshipType implements
        PlaceService.GetFriendsTimelineParam {

    Followed(0), Friends(1);

    private int value;

    FriendshipType(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void addParameter(Parameters params) {
        if (this == Friends) {
            params.add("type", getValue());
        }
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParsePoiListTest.java<|end_filename|>
package weiboclient4j.model;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
import org.junit.Test;
import weiboclient4j.utils.JsonUtils;
import weiboclient4j.utils.SimpleDateDeserializer;

import java.util.Date;
import java.util.List;

/**
 * @author <NAME>
 */
public class ParsePoiListTest extends AbstractParseJsonTest {
    @Test
    public void testParsePoiList() throws Exception {
        String content = readResource("/weiboclient4j/model/poi_list.json");

        PoiList poiList = JsonUtils.readValue(content, PoiList.class);

        assertThat(poiList, is(notNullValue()));
        assertThat(poiList.getTotalNumber(), is(65));

        List<Poi> pois = poiList.getPois();
        assertThat(pois, is(notNullValue()));
        assertThat(pois.size(), is(20));

        Poi poi = pois.get(0);
        Date checkinTime = SimpleDateDeserializer.DATE_FORMAT.parse("2012-11-19 00:01:13");
        assertThat(poi.getCheckinTime(), is(checkinTime));
    }
}


<|start_filename|>src/main/java/weiboclient4j/RegisterService.java<|end_filename|>
package weiboclient4j;

import weiboclient4j.model.VerifyNicknameResult;
import weiboclient4j.params.Nickname;

/**
 * @author <NAME>
 */
public class RegisterService extends AbstractService {
    public RegisterService(WeiboClient client) {
        super(client);
    }

    public VerifyNicknameResult verifyNickname(Nickname nickname) throws WeiboClientException {
        return doGet("register/verify_nickname",
                withParams(nickname), VerifyNicknameResult.class);
    }
}


<|start_filename|>src/test/java/weiboclient4j/params/PagingTest.java<|end_filename|>
package weiboclient4j.params;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;

/**
 * @author <NAME>
 */
public class PagingTest {
    @Test
    public void testHasValue() throws Exception {
        Paging paging = Paging.create();

        assertFalse(paging.hasValue());

        paging.count(20);

        assertTrue(paging.hasValue());
    }
}


<|start_filename|>src/main/java/weiboclient4j/WeiboClient.java<|end_filename|>
package weiboclient4j;

import org.codehaus.jackson.type.TypeReference;
import org.scribe.builder.ServiceBuilder;
import org.scribe.exceptions.OAuthException;
import org.scribe.model.Token;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuthService;
import weiboclient4j.model.TokenInfo;
import weiboclient4j.oauth2.DisplayType;
import weiboclient4j.oauth2.ForceLogin;
import weiboclient4j.oauth2.GrantType;
import weiboclient4j.oauth2.ResponseType;
import weiboclient4j.oauth2.SinaWeibo2AccessToken;
import weiboclient4j.oauth2.SinaWeibo2Api;
import weiboclient4j.params.Paging;
import weiboclient4j.params.Parameters;
import static weiboclient4j.utils.StringUtils.isNotBlank;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * API V2 client.
 *
 * @author <NAME>
 */
public class WeiboClient {

    private static final int DEFAULT_TIMEOUT = 30;

    private String clientId;

    private String clientSecret;

    private SinaWeibo2AccessToken accessToken;

    private int connectTimeoutDuration = DEFAULT_TIMEOUT;

    private TimeUnit connectTimeoutUnit = TimeUnit.SECONDS;

    private int readTimeoutDuration = DEFAULT_TIMEOUT;

    private TimeUnit readTimeoutUnit = TimeUnit.SECONDS;

    private AbstractService defaultService;

    /**
     * Create api client v2.
     *
     * @param clientId     Client ID, or Api Key
     * @param clientSecret Client Secret, or Api Secret
     */
    public WeiboClient(String clientId, String clientSecret) {
        this.clientId = clientId;
        this.clientSecret = clientSecret;

        initDefaultService();
    }

    public WeiboClient(String accessToken) {
        setAccessToken(accessToken);

        initDefaultService();
    }

    public long getConnectTimeout() {
        return connectTimeoutUnit.toMillis(connectTimeoutDuration);
    }

    public void setConnectTimeout(int duration, TimeUnit unit) {
        this.connectTimeoutDuration = duration;
        this.connectTimeoutUnit = unit;
    }

    public long getReadTimeout() {
        return readTimeoutUnit.toMillis(readTimeoutDuration);
    }

    public void setReadTimeout(int duration, TimeUnit unit) {
        this.readTimeoutDuration = duration;
        this.readTimeoutUnit = unit;
    }

    public String getAuthorizationUrl(String callback) {
        return getAuthorizationUrl(null, callback);
    }

    public String getAuthorizationUrl(String callback, ForceLogin forceLogin) {
        return getAuthorizationUrl(null, callback, forceLogin);
    }

    public String getAuthorizationUrl(String state, String callback) {
        return getAuthorizationUrl(ResponseType.Code, DisplayType.Default, state, callback);
    }

    public String getAuthorizationUrl(String state, String callback, ForceLogin forceLogin) {
        return getAuthorizationUrl(ResponseType.Code, DisplayType.Default, state, callback, forceLogin);
    }

    public String getAuthorizationUrl(ResponseType responseType, DisplayType displayType, String state,
                                      String callback) {
        return getAuthorizationUrl(responseType, displayType, state, callback, ForceLogin.No);
    }

    public String getAuthorizationUrl(ResponseType responseType, DisplayType displayType, String state,
                                      String callback, ForceLogin forceLogin) {
        SinaWeibo2Api api = new SinaWeibo2Api(responseType, displayType, forceLogin);
        api.setState(state);

        OAuthService service = new ServiceBuilder()
                .apiKey(clientId)
                .apiSecret(clientSecret)
                .callback(callback)
                .provider(api)
                .build();

        return service.getAuthorizationUrl(null);
    }

        /**
         * @deprecated Use {@link #getAccessTokenByCode(String, String)} for 'authorization_code' grant type
         */
    @Deprecated
    public SinaWeibo2AccessToken getAccessToken(GrantType grantType, String code, String callback)
            throws WeiboClientException {
        return getAccessTokenByCode(code, callback);
    }

    public SinaWeibo2AccessToken getAccessTokenByCode(String code, String callback) throws WeiboClientException {
        SinaWeibo2Api api = new SinaWeibo2Api(GrantType.AuthorizationCode);

        ServiceBuilder serviceBuilder = new ServiceBuilder();

        if (isNotBlank(callback)) {
            serviceBuilder.callback(callback);
        }

        OAuthService service = serviceBuilder
                .apiKey(clientId)
                .apiSecret(clientSecret)
                .provider(api)
                .build();

        return retrieveAccessToken(service, null, new Verifier(code));
    }

    public SinaWeibo2AccessToken getAccessTokenByCode(String code) throws WeiboClientException {
        return getAccessTokenByCode(code, null);
    }

    public SinaWeibo2AccessToken getAccessTokenByPassword(String username, String password)
            throws WeiboClientException {
        SinaWeibo2Api api = new SinaWeibo2Api(GrantType.Password);

        OAuthService service = new ServiceBuilder()
                .apiKey(clientId)
                .apiSecret(clientSecret)
                .provider(api)
                .build();

        return retrieveAccessToken(service, new Token(username, password), null);
    }

    public void setAccessToken(SinaWeibo2AccessToken accessToken) {
        this.accessToken = accessToken;
    }

    public void setAccessToken(String accessToken) {
        setAccessToken(new SinaWeibo2AccessToken(accessToken));
    }

    public TokenInfo getTokenInfo() throws WeiboClientException {
        return post("https://api.weibo.com/oauth2/get_token_info", TokenInfo.class);
    }

    public StatusService getStatusService() {
        return new StatusService(this);
    }

    public CommentService getCommentService() {
        return new CommentService(this);
    }

    public UserService getUserService() {
        return new UserService(this);
    }

    public FriendshipService getFriendshipService() {
        return new FriendshipService(this);
    }

    public AccountService getAccountService() {
        return new AccountService(this);
    }

    public FavoriteService getFavoriteService() {
        return new FavoriteService(this);
    }

    public TrendService getTrendService() {
        return new TrendService(this);
    }

    public TagService getTagService() {
        return new TagService(this);
    }

    public RegisterService getRegisterService() {
        return new RegisterService(this);
    }

    public SearchService getSearchService() {
        return new SearchService(this);
    }

    public SuggestionService getSuggestionService() {
        return new SuggestionService(this);
    }

    public RemindService getRemindService() {
        return new RemindService(this);
    }

    public ShortUrlService getShortUrlService() {
        return new ShortUrlService(this);
    }

    public NotificationService getNotificationService() {
        return new NotificationService(this);
    }

    public CommonService getCommonService() {
        return new CommonService(this);
    }

    public PlaceService getPlaceService() {
        return new PlaceService(this);
    }

    public LocationService getLocationService() {
        return new LocationService(this);
    }

    public <T> T get(String path, Paging paging, Parameters params, Class<T> clazz) throws WeiboClientException {
        return defaultService.doGet(path, paging, params, clazz);
    }

    public <T> T get(String path, Parameters params, Class<T> clazz) throws WeiboClientException {
        return defaultService.doGet(path, params, clazz);
    }

    public <T> T get(String path, Paging paging, Class<T> clazz) throws WeiboClientException {
        return defaultService.doGet(path, paging, clazz);
    }

    public <T> T get(String path, Class<T> clazz) throws WeiboClientException {
        return defaultService.doGet(path, clazz);
    }

    public <T> List<T> get(String path, Paging paging, Parameters params, TypeReference<List<T>> typeReference)
            throws WeiboClientException {
        return defaultService.doGet(path, paging, params, typeReference);
    }

    public <T> List<T> get(String path, Parameters params, TypeReference<List<T>> typeReference)
            throws WeiboClientException {
        return defaultService.doGet(path, params, typeReference);
    }

    public <T> List<T> get(String path, Paging paging, TypeReference<List<T>> typeReference)
            throws WeiboClientException {
        return defaultService.doGet(path, paging, typeReference);
    }

    public <T> List<T> get(String path, TypeReference<List<T>> typeReference) throws WeiboClientException {
        return defaultService.doGet(path, typeReference);
    }

    public <T> T post(String path, Paging paging, Parameters params, Class<T> clazz) throws WeiboClientException {
        return defaultService.doPost(path, paging, params, clazz);
    }

    public <T> T post(String path, Parameters params, Class<T> clazz) throws WeiboClientException {
        return defaultService.doPost(path, params, clazz);
    }

    public <T> T post(String path, Paging paging, Class<T> clazz) throws WeiboClientException {
        return defaultService.doPost(path, paging, clazz);
    }

    public <T> T post(String path, Class<T> clazz) throws WeiboClientException {
        return defaultService.doPost(path, clazz);
    }

    public <T> List<T> post(String path, Paging paging, Parameters params, TypeReference<List<T>> typeReference)
            throws WeiboClientException {
        return defaultService.doPost(path, paging, params, typeReference);
    }

    public <T> List<T> post(String path, Parameters params, TypeReference<List<T>> typeReference)
            throws WeiboClientException {
        return defaultService.doPost(path, params, typeReference);
    }

    public <T> List<T> post(String path, Paging paging, TypeReference<List<T>> typeReference)
            throws WeiboClientException {
        return defaultService.doPost(path, paging, typeReference);
    }

    public <T> List<T> post(String path, TypeReference<List<T>> typeReference) throws WeiboClientException {
        return defaultService.doPost(path, typeReference);
    }

    protected void initService(AbstractService service) {
        service.setAccessToken(accessToken);
        service.setConnectTimeoutDuration(connectTimeoutDuration);
        service.setConnectTimeoutUnit(connectTimeoutUnit);
        service.setReadTimeoutDuration(readTimeoutDuration);
        service.setReadTimeoutUnit(readTimeoutUnit);
    }

    private void initDefaultService() {
        defaultService = new AbstractService(this);
    }

    private SinaWeibo2AccessToken retrieveAccessToken(OAuthService service, Token token, Verifier verifier)
            throws WeiboClientException {
        try {
            accessToken = (SinaWeibo2AccessToken) service.getAccessToken(token, verifier);
        } catch (OAuthException oe) {
            if (oe.getCause() instanceof WeiboClientException) {
                throw (WeiboClientException) oe.getCause();
            }

            throw new WeiboClientException("OAuth error", oe);
        }

        return accessToken;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/TrendStatus.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class TrendStatus {

    private long trendId;

    @JsonProperty("is_follow")
    private boolean follow;

    public long getTrendId() {
        return trendId;
    }

    public void setTrendId(long trendId) {
        this.trendId = trendId;
    }

    public boolean isFollow() {
        return follow;
    }

    public void setFollow(boolean follow) {
        this.follow = follow;
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParseCommentListTest.java<|end_filename|>
package weiboclient4j.model;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
import org.junit.Test;
import static weiboclient4j.utils.JsonUtils.parseJsonObject;

/**
 * @author <NAME>
 */
public class ParseCommentListTest extends AbstractParseJsonTest {

    @Test
    public void testParseComments() throws Exception {
        String content = readResource("/weiboclient4j/model/comment_list.json");

        CommentList commentList = parseJsonObject(content, CommentList.class);
        assertThat(commentList.getTotalNumber(), is(53));
        assertThat(commentList.getComments(), is(notNullValue()));
        assertThat(commentList.getComments().size(), is(46));
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParseNotificationResultTest.java<|end_filename|>
package weiboclient4j.model;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import weiboclient4j.utils.JsonUtils;

/**
 * @author <NAME>
 */
public class ParseNotificationResultTest extends AbstractParseJsonTest {
    @Test
    public void testParseNotificationResult() throws Exception {
        String content = readResource("/weiboclient4j/model/notification_result.json");
        NotificationResult result = JsonUtils.readValue(content, NotificationResult.class);

        assertNotNull(result);

        assertEquals(12035, result.getNotification().getNotificationId());
        assertEquals("4Gcqmc", result.getNotification().getSenderApp().getAppkey62());

        assertTrue(result.getFailedUid().contains(21485798475L));
        assertTrue(result.getFailedUid().contains(21485798476L));
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/UrlLocation.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class UrlLocation {
    private int clicks;
    private int province;
    private String location;

    public int getClicks() {
        return clicks;
    }

    public void setClicks(int clicks) {
        this.clicks = clicks;
    }

    public int getProvince() {
        return province;
    }

    public void setProvince(int province) {
        this.province = province;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }
}


<|start_filename|>src/main/java/weiboclient4j/CommentService.java<|end_filename|>
package weiboclient4j;

import weiboclient4j.model.Comment;
import weiboclient4j.model.CommentList;
import weiboclient4j.params.Cid;
import weiboclient4j.params.CommentOri;
import weiboclient4j.params.CommentParam;
import weiboclient4j.params.FilterByAuthor;
import weiboclient4j.params.FilterBySource;
import weiboclient4j.params.Id;
import weiboclient4j.params.Paging;
import weiboclient4j.params.WithoutMention;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author <NAME>
 */
public class CommentService extends AbstractService {

    public CommentService(WeiboClient client) {
        super(client);
    }

    public CommentList getComments(Id id) throws WeiboClientException {
        return getComments(id, Paging.EMPTY);
    }

    public CommentList getComments(Id id, Paging paging) throws WeiboClientException {
        return getComments(id, paging, FilterByAuthor.All);
    }

    public CommentList getComments(Id id, Paging paging, FilterByAuthor filterByAuthor) throws WeiboClientException {
        return doGet("comments/show",
                paging, withParams(id, filterByAuthor), CommentList.class);
    }

    public CommentList getCommentsByMe() throws WeiboClientException {
        return getCommentsByMe(Paging.EMPTY);
    }

    public CommentList getCommentsByMe(Paging paging) throws WeiboClientException {
        return getCommentsByMe(paging, FilterByAuthor.All);
    }

    public CommentList getCommentsByMe(Paging paging, FilterByAuthor filterByAuthor) throws WeiboClientException {
        return doGet("comments/by_me",
                paging, withParams(filterByAuthor), CommentList.class);
    }

    public CommentList getCommentsToMe() throws WeiboClientException {
        return getCommentsToMe(Paging.EMPTY);
    }

    public CommentList getCommentsToMe(Paging paging) throws WeiboClientException {
        return getCommentsToMe(paging, FilterByAuthor.All, FilterBySource.All);
    }

    public CommentList getCommentsToMe(Paging paging, FilterByAuthor filterByAuthor, FilterBySource filterBySource)
            throws WeiboClientException {
        return doGet("comments/to_me",
                paging, withParams(filterByAuthor, filterBySource), CommentList.class);
    }

    public CommentList getCommentsTimeline() throws WeiboClientException {
        return getCommentsTimeline(Paging.EMPTY);
    }

    public CommentList getCommentsTimeline(Paging paging) throws WeiboClientException {
        return doGet("comments/timeline", paging, CommentList.class);
    }

    public CommentList getMentionsComments() throws WeiboClientException {
        return getMentionsComments(Paging.EMPTY);
    }

    public CommentList getMentionsComments(Paging paging) throws WeiboClientException {
        return getMentionsComments(paging, FilterByAuthor.All, FilterBySource.All);
    }

    public CommentList getMentionsComments(Paging paging, FilterByAuthor filterByAuthor, FilterBySource filterBySource)
            throws WeiboClientException {
        return doGet("comments/mentions",
                paging, withParams(filterByAuthor, filterBySource), CommentList.class);
    }

    public List<Comment> getCommentsBatch(Collection<Cid> cids) throws WeiboClientException {
        return doGet("comments/show_batch",
                withParams(Cid.cidsParam(cids)), Comment.TYPE_COMMENT_LIST);
    }

    public Comment createComment(Id id, String comment) throws WeiboClientException {
        return createComment(id, comment, CommentOri.No);
    }

    public Comment createComment(Id id, CommentParam comment, CommentOri commentOri) throws WeiboClientException {
        return doPost("comments/create",
                withParams(id, comment, commentOri), Comment.class);
    }

    public Comment createComment(Id id, String comment, CommentOri commentOri) throws WeiboClientException {
        return createComment(id, new CommentParam(comment), commentOri);
    }

    public Comment destroyComment(Cid cid) throws WeiboClientException {
        return doPost("comments/destroy", withParams(cid), Comment.class);
    }

    public List<Comment> destroyCommentBatch(Collection<Cid> cids) throws WeiboClientException {
        List<Id> ids = new ArrayList<Id>(cids.size());
        for (Cid cid : cids) {
            ids.add(new Id(cid.getValue()));
        }

        return doPost("comments/destroy_batch",
                withParams(Id.idsParam(ids)), Comment.TYPE_COMMENT_LIST);
    }

    public Comment replyComment(Id id, Cid cid, String comment) throws WeiboClientException {
        return replyComment(id, cid, comment, WithoutMention.No, CommentOri.No);
    }

    public Comment replyComment(Id id, Cid cid, String comment, WithoutMention withoutMention, CommentOri commentOri)
            throws WeiboClientException {
        return replyComment(id, cid, new CommentParam(comment), withoutMention, commentOri);
    }

    public Comment replyComment(Id id, Cid cid, CommentParam comment, WithoutMention withoutMention,
                                CommentOri commentOri) throws WeiboClientException {
        return doPost("comments/reply",
                withParams(id, cid, comment, withoutMention, commentOri), Comment.class);
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/UserTagList.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.node.ArrayNode;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserTagList {
    private long id;
    private List<Tag> tags;

    public UserTagList() {
    }

    public UserTagList(long id, List<Tag> tags) {
        this.id = id;
        this.tags = tags;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public List<Tag> getTags() {
        return tags;
    }

    public void setTags(List<Tag> tags) {
        this.tags = tags;
    }

    public static List<UserTagList> parse(ArrayNode arrayNode) {
        List<UserTagList> result = new ArrayList<UserTagList>(arrayNode.size());

        Iterator<JsonNode> elements = arrayNode.getElements();
        while (elements.hasNext()) {
            JsonNode json = elements.next();
            long userId = json.get("id").asLong();
            List<Tag> tags = Tag.parseTags(json.get("tags"));

            UserTagList userTagList = new UserTagList(userId, tags);
            result.add(userTagList);
        }

        return result;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/IsComment.java<|end_filename|>
package weiboclient4j.params;

import java.util.HashMap;
import java.util.Map;

/**
 * @author <NAME>
 */
public enum IsComment implements ParameterAction {
    No(0), Current(1), Original(2), Both(3);

    private static Map<Integer, IsComment> map = new HashMap<Integer, IsComment>();

    static {
        for (IsComment isComment : IsComment.values()) {
            map.put(isComment.getValue(), isComment);
        }
    }

    private int value;

    IsComment(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public static IsComment fromValue(int value) {
        return map.get(value);
    }

    public void addParameter(Parameters params) {
        if (this != No) {
            params.add("is_comment", getValue());
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/utils/CollectionUtils.java<|end_filename|>
package weiboclient4j.utils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author <NAME>
 */
public final class CollectionUtils {
    private CollectionUtils() {
    }

    public static <E> List<E> newArrayList(E... elements) {
        List<E> list = new ArrayList<E>(elements.length);
        Collections.addAll(list, elements);

        return list;
    }

    public static <T> T firstItem(List<T> list) {
        return list != null && list.size() > 0 ? list.get(0) : null;
    }
}


<|start_filename|>src/main/java/weiboclient4j/examples/OAuth2CommandLine.java<|end_filename|>
package weiboclient4j.examples;

import static java.util.Arrays.asList;
import weiboclient4j.AccountService;
import weiboclient4j.CommentService;
import weiboclient4j.StatusService;
import weiboclient4j.WeiboClient;
import weiboclient4j.WeiboClientException;
import weiboclient4j.model.Comment;
import weiboclient4j.model.CommentList;
import weiboclient4j.model.Status;
import weiboclient4j.model.Timeline;
import weiboclient4j.model.TimelineIds;
import weiboclient4j.oauth2.DisplayType;
import weiboclient4j.oauth2.ResponseType;
import weiboclient4j.oauth2.SinaWeibo2AccessToken;
import weiboclient4j.params.BaseApp;
import weiboclient4j.params.Cid;
import static weiboclient4j.params.CoreParameters.cid;
import static weiboclient4j.params.CoreParameters.id;
import static weiboclient4j.params.CoreParameters.mid;
import static weiboclient4j.params.CoreParameters.uid;
import weiboclient4j.params.Feature;
import weiboclient4j.params.Id;
import weiboclient4j.params.IsBase62;
import weiboclient4j.params.Mid;
import weiboclient4j.params.MidType;
import weiboclient4j.params.Paging;
import weiboclient4j.params.ScreenName;
import weiboclient4j.params.TrimUser;
import weiboclient4j.params.Uid;
import static weiboclient4j.utils.JsonUtils.writeObjectAsString;
import static weiboclient4j.utils.StringUtils.isBlank;
import static weiboclient4j.utils.StringUtils.isNotBlank;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Map;
import java.util.prefs.Preferences;

/**
 * @author <NAME>
 */
public class OAuth2CommandLine {

    public static final String API_KEY = "api_key";

    public static final String API_SECRET = "api_secret";

    private static final long STATUS_ID = 3436240135184587L;

    private static final long ANOTHER_STATUS_ID = 3436255091659029L;

    private static final long UID = 1834561765L;

    private WeiboClient client;

    private BufferedReader in;

    private Status justPostStatus;

    public OAuth2CommandLine(BufferedReader in) {
        this.in = in;
    }

    public static void main(String[] args) throws Exception {
        Preferences pref = Preferences.userRoot().node("/weiboclient4j/example/oauth2");

        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

        String savedKey = pref.get(API_KEY, "");
        String defaultKey = isBlank(savedKey) ? "" : " [" + savedKey + "] ";
        System.out.print("Input client id (api key)" + defaultKey + ": ");
        String apiKey = in.readLine();
        if (isNotBlank(apiKey)) {
            pref.put(API_KEY, apiKey);
        } else if (isNotBlank(savedKey)) {
            apiKey = savedKey;
        }

        String savedSecret = pref.get(API_SECRET, "");
        String defaultSecret = isBlank(savedSecret) ? "" : " [" + savedSecret + "] ";
        System.out.print("Input client secret (api secret)" + defaultSecret + ": ");
        String apiSecret = in.readLine();
        if (isNotBlank(apiSecret)) {
            pref.put(API_SECRET, apiSecret);
        } else if (isNotBlank(savedSecret)) {
            apiSecret = savedSecret;
        }

        WeiboClient client = new WeiboClient(apiKey, apiSecret);

        OAuth2CommandLine cmd = new OAuth2CommandLine(in);
        cmd.setClient(client);

        cmd.retrieveAccessToken();
        cmd.retrieveAccountUid();
        cmd.retrievePublicTimeline();
        cmd.retrieveFriendsTimeline();
        cmd.retrieveHomeTimeline();
        cmd.retrieveUserTimeline();
        cmd.retrieveOtherTimeline();
        cmd.retrieveIds();
        cmd.updateStatus();
        cmd.retrieveAndUpdateComments();
    }

    public void setClient(WeiboClient client) {
        this.client = client;
    }

    private void retrieveAndUpdateComments() throws WeiboClientException, IOException {
        StatusService statusService = client.getStatusService();

        CommentService commentService = client.getCommentService();
        commentService.getComments(id(STATUS_ID));
        CommentList commentsByMe = commentService.getCommentsByMe();
        long firstCommentId = commentsByMe.getComments().get(0).getId();

        commentService.getCommentsToMe();
        commentService.getCommentsTimeline();
        commentService.getMentionsComments();

        List<Cid> batchCids = asList(cid(firstCommentId));
        commentService.getCommentsBatch(batchCids);

        Comment comment = commentService.createComment(id(justPostStatus.getId()), "Create comment test");
        Comment reply = commentService.replyComment(
                id(justPostStatus.getId()),
                cid(comment.getId()),
                "Reply test");
        commentService.destroyComment(cid(comment.getId()));
        commentService.destroyComment(cid(reply.getId()));

        statusService.destroy(id(justPostStatus.getId()));
    }

    private void updateStatus() throws WeiboClientException, IOException {
        StatusService statusService = client.getStatusService();

        justPostStatus = statusService.update("Update status api test");
        Status repostStatus = statusService.repost(id(justPostStatus.getId()), "Repost test");
        System.out.println();
        System.out.println("Just post: " + writeObjectAsString(justPostStatus));
        System.out.println("Repost: " + writeObjectAsString(repostStatus));

        statusService.destroy(id(repostStatus.getId()));

        // Need advanced permission
//        Status uploadedStatusByImageUrl = statusService.uploadImageUrl("Post image test",
//               new URL("https://a248.e.akamai.net/assets.github.com/images/modules/about_page/octocat.png?1306884373")
//        );
//        statusService.destroy(id(uploadedStatusByImageUrl.getId()));
    }

    private void retrieveIds() throws WeiboClientException {
        StatusService statusService = client.getStatusService();

        statusService.show(id(STATUS_ID));

        statusService.queryMid(id(STATUS_ID), MidType.Status);

        List<Id> idList = asList(id(STATUS_ID), id(ANOTHER_STATUS_ID));
        Map<Long, String> midMap = statusService.queryMidList(idList, MidType.Status);
        System.out.println();
        System.out.println("Mid " + STATUS_ID + "=" + midMap.get(STATUS_ID) + ", "
                + ANOTHER_STATUS_ID + "=" + midMap.get(ANOTHER_STATUS_ID));

        statusService.queryId(mid("yfcLPlKKn"), MidType.Message, IsBase62.Yes);

        List<Mid> midList = asList(mid("yfcLPlKKn"), mid("yfd9X6XAx"));

        Map<String, Long> idMap = statusService.queryIdList(midList, MidType.Message, IsBase62.Yes);
        System.out.println();
        System.out.println("Id yfcLPlKKn=" + idMap.get("yfcLPlKKn") + ", yfd9X6XAx=" + idMap.get("yfd9X6XAx"));

        statusService.getStatusesCounts(idList);
    }

    private void retrieveOtherTimeline() throws WeiboClientException {
        StatusService statusService = client.getStatusService();

        statusService.getRepostTimeline(id(STATUS_ID));
        statusService.getRepostTimelineIds(id(STATUS_ID));

        statusService.getRepostByMe();

        statusService.getMentions();
        statusService.getMentionsIds();

        statusService.getBilateralTimeline();
    }

    private void retrieveUserTimeline() throws WeiboClientException, IOException {
        StatusService statusService = client.getStatusService();

        Timeline userTimeline = statusService.getUserTimeline();
        System.out.println();
        System.out.println("User timeline: " + writeObjectAsString(userTimeline));

        Timeline userTimelineTrimUser = statusService.getUserTimeline(TrimUser.No);
        System.out.println();
        System.out.println("User timeline that trim user: " + writeObjectAsString(userTimelineTrimUser));

        statusService.getUserTimeline(ScreenName.EMPTY);
        statusService.getUserTimeline(Uid.EMPTY);
        statusService.getUserTimeline(Paging.EMPTY, TrimUser.Yes);

        Timeline userTimelineFor1834561765 = statusService.getUserTimeline(
                uid(UID), BaseApp.No, Feature.All, TrimUser.No);
        System.out.println();
        System.out.println("User timeline for 1834561765: " + writeObjectAsString(userTimelineFor1834561765));

        statusService.getUserTimelineIds(ScreenName.EMPTY);
        statusService.getUserTimelineIds(Uid.EMPTY);
        statusService.getUserTimelineIds();
    }

    private void retrieveHomeTimeline() throws IOException, WeiboClientException {
        StatusService statusService = client.getStatusService();

        Timeline homeTimeline = statusService.getHomeTimeline();
        System.out.println();
        System.out.println("Home timeline: " + writeObjectAsString(homeTimeline));
    }

    private void retrieveFriendsTimeline() throws WeiboClientException, IOException {
        StatusService statusService = client.getStatusService();

        Timeline friendsTimeline = statusService.getFriendsTimeline();
        System.out.println();
        System.out.println("Friends timeline: " + writeObjectAsString(friendsTimeline));

        TimelineIds friendsTimelineIds = statusService.getFriendsTimelineIds();
        System.out.println();
        System.out.println("Friends timeline ids: " + writeObjectAsString(friendsTimelineIds));
    }

    private void retrievePublicTimeline() throws WeiboClientException, IOException {
        StatusService statusService = client.getStatusService();

        Timeline publicTimeline = statusService.getPublicTimeline();
        System.out.println();
        System.out.println("Public timeline: " + writeObjectAsString(publicTimeline));
    }

    private void retrieveAccountUid() throws WeiboClientException {
        AccountService accountService = client.getAccountService();
        long uid = accountService.getUid();

        System.out.println();
        System.out.println("Got account uid: " + uid);
    }

    private void retrieveAccessToken() throws IOException, WeiboClientException {
        String state = "__MY_STATE__";
        String authorizationCallback = "http://demo.localhost.weiboclient4j.org/callback";
        String url = client.getAuthorizationUrl(ResponseType.Code, DisplayType.Default, state, authorizationCallback);
        System.out.println("Please visit: " + url);

        System.out.print("Input code: ");
        String code = in.readLine();
        String accessTokenCallback = "http://demo.localhost.weiboclient4j.org/callback";
        SinaWeibo2AccessToken accessToken = client.getAccessTokenByCode(code, accessTokenCallback);
        System.out.println();
        System.out.println("Access token: " + accessToken.getToken());
        System.out.println("Uid: " + accessToken.getUid());
        System.out.println("Expires in: " + accessToken.getExpiresIn());
        System.out.println("Remind in: " + accessToken.getRemindIn());

        accessToken = new SinaWeibo2AccessToken(accessToken.getToken());
        client.setAccessToken(accessToken);
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Title.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public class Title extends StringParam {
    public Title(String value) {
        super(value);
    }

    protected String paramKey() {
        return "title";
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParseRepostTimeline.java<|end_filename|>
package weiboclient4j.model;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
import org.junit.Test;
import weiboclient4j.utils.JsonUtils;

public class ParseRepostTimeline extends AbstractParseJsonTest {
    @Test
    public void testParseEmptyRepostTimeline() throws Exception {
        String content = readResource("/weiboclient4j/model/empty_repost_timeline.json");

        RepostTimeline timeline = JsonUtils.readValue(content, RepostTimeline.class);
        assertThat(timeline, is(notNullValue()));
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/IsBatch.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public enum IsBatch implements ParameterAction {
    Yes(1), No(0);

    private int value;

    IsBatch(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void addParameter(Parameters params) {
        if (this == Yes) {
            params.add("is_batch", getValue());
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/Trend.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.type.TypeReference;

import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class Trend {
    public static final TypeReference<List<Trend>> TYPE_TREND_LIST = new TypeReference<List<Trend>>() {
    };

    private long trendId;
    private String hotword;
    private long num;

    public long getTrendId() {
        return trendId;
    }

    public void setTrendId(long trendId) {
        this.trendId = trendId;
    }

    public String getHotword() {
        return hotword;
    }

    public void setHotword(String hotword) {
        this.hotword = hotword;
    }

    public long getNum() {
        return num;
    }

    public void setNum(long num) {
        this.num = num;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/User.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.type.TypeReference;

import java.util.Date;
import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class User {
    public static final TypeReference<List<User>> TYPE_USER_LIST = new TypeReference<List<User>>() {
    };

    private long id;

    private String idstr;

    private String screenName;

    private String name;

    private String province;

    private String city;

    private String location;

    private String description;

    private String url;

    private String profileImageUrl;

    private String profileUrl;

    private String domain;

    private String gender;

    private int followersCount;

    private int friendsCount;

    private int statusesCount;

    private int favouritesCount;

    private Date createdAt;

    private boolean following;

    private boolean followMe;

    private boolean verified;

    private boolean allowAllActMsg;

    private boolean geoEnabled;

    private Status status;

    private String remark;

    private String avatarLarge;

    private String verifiedReason;

    private int verifiedType;


    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getIdstr() {
        return idstr;
    }

    public void setIdstr(String idstr) {
        this.idstr = idstr;
    }

    public String getScreenName() {
        return screenName;
    }

    public void setScreenName(String screenName) {
        this.screenName = screenName;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getProfileImageUrl() {
        return profileImageUrl;
    }

    public void setProfileImageUrl(String profileImageUrl) {
        this.profileImageUrl = profileImageUrl;
    }

    public String getProfileUrl() {
        return profileUrl;
    }

    public void setProfileUrl(String profileUrl) {
        this.profileUrl = profileUrl;
    }

    public String getDomain() {
        return domain;
    }

    public void setDomain(String domain) {
        this.domain = domain;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public int getFollowersCount() {
        return followersCount;
    }

    public void setFollowersCount(int followersCount) {
        this.followersCount = followersCount;
    }

    public int getFriendsCount() {
        return friendsCount;
    }

    public void setFriendsCount(int friendsCount) {
        this.friendsCount = friendsCount;
    }

    public int getStatusesCount() {
        return statusesCount;
    }

    public void setStatusesCount(int statusesCount) {
        this.statusesCount = statusesCount;
    }

    public int getFavouritesCount() {
        return favouritesCount;
    }

    public void setFavouritesCount(int favouritesCount) {
        this.favouritesCount = favouritesCount;
    }

    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    public boolean isFollowing() {
        return following;
    }

    public void setFollowing(boolean following) {
        this.following = following;
    }

    public boolean isFollowMe() {
        return followMe;
    }

    public void setFollowMe(boolean followMe) {
        this.followMe = followMe;
    }

    public boolean isVerified() {
        return verified;
    }

    public void setVerified(boolean verified) {
        this.verified = verified;
    }

    public boolean isAllowAllActMsg() {
        return allowAllActMsg;
    }

    public void setAllowAllActMsg(boolean allowAllActMsg) {
        this.allowAllActMsg = allowAllActMsg;
    }

    public boolean isGeoEnabled() {
        return geoEnabled;
    }

    public void setGeoEnabled(boolean geoEnabled) {
        this.geoEnabled = geoEnabled;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public String getAvatarLarge() {
        return avatarLarge;
    }

    public void setAvatarLarge(String avatarLarge) {
        this.avatarLarge = avatarLarge;
    }

    public String getVerifiedReason() {
        return verifiedReason;
    }

    public void setVerifiedReason(String verifiedReason) {
        this.verifiedReason = verifiedReason;
    }

    public int getVerifiedType() {
        return verifiedType;
    }

    public void setVerifiedType(int verifiedType) {
        this.verifiedType = verifiedType;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/FriendshipInfo.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class FriendshipInfo {
    private long id;
    private String screenName;
    private boolean followedBy;
    private boolean following;
    private boolean notificationsEnabled;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getScreenName() {
        return screenName;
    }

    public void setScreenName(String screenName) {
        this.screenName = screenName;
    }

    public boolean isFollowedBy() {
        return followedBy;
    }

    public void setFollowedBy(boolean followedBy) {
        this.followedBy = followedBy;
    }

    public boolean isFollowing() {
        return following;
    }

    public void setFollowing(boolean following) {
        this.following = following;
    }

    public boolean isNotificationsEnabled() {
        return notificationsEnabled;
    }

    public void setNotificationsEnabled(boolean notificationsEnabled) {
        this.notificationsEnabled = notificationsEnabled;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Parameters.java<|end_filename|>
package weiboclient4j.params;

import org.scribe.model.OAuthRequest;
import org.scribe.model.Verb;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author <NAME>
 */
public final class Parameters {
    private List<Parameter> parameterList = new ArrayList<Parameter>();

    private Parameters() {

    }

    public static Parameters create() {
        return new Parameters();
    }

    public Parameters add(String key, String value) {
        parameterList.add(new Parameter(key, value));

        return this;
    }

    public Parameters add(Paging paging) {
        for (Map.Entry<String, String> entry : paging.buildParameters().entrySet()) {
            add(entry.getKey(), entry.getValue());
        }

        return this;
    }

    public Parameters add(String key, long value) {
        return add(key, String.valueOf(value));
    }

    public Parameters add(String key, boolean value) {
        return add(key, String.valueOf(value));
    }

    public Parameters add(String key, float value) {
        return add(key, String.valueOf(value));
    }

    public Parameters add(String key, long[] valueArray) {
        if (valueArray != null && valueArray.length > 0) {
            StringBuilder result = new StringBuilder(String.valueOf(valueArray[0]));
            for (int i = 1; i < valueArray.length; i++) {
                long value = valueArray[i];
                result.append(',').append(value);
            }

            add(key, result.toString());
        }

        return this;
    }

    public boolean isEmpty() {
        return parameterList.size() == 0;
    }

    public boolean isNotEmpty() {
        return parameterList.size() > 0;
    }

    public String get(String key) {
        for (Parameter parameter : parameterList) {
            if (key.equals(parameter.getKey())) {
                return parameter.getValue();
            }
        }

        return null;
    }

    public int size() {
        return parameterList.size();
    }

    public List<Parameter> getParameterList() {
        return parameterList;
    }

    public void appendTo(OAuthRequest request) {
        if (request.getVerb() == Verb.GET) {
            for (Parameter p : parameterList) {
                request.addQuerystringParameter(p.getKey(), p.getValue());
            }
        } else {
            for (Parameter p : parameterList) {
                request.addBodyParameter(p.getKey(), p.getValue());
            }
        }
    }

    public Parameters addAll(ParameterAction[] actions) {
        for (ParameterAction action : actions) {
            if (action != null) {
                action.addParameter(this);
            }
        }

        return this;
    }

    public static final class Parameter {
        private String key;
        private String value;

        private Parameter(String key, String value) {
            this.key = key;
            this.value = value;
        }

        public String getKey() {
            return key;
        }

        public String getValue() {
            return value;
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/SearchSuggestionUserResult.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.type.TypeReference;

import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class SearchSuggestionUserResult {
    public static final TypeReference<List<SearchSuggestionUserResult>> TYPE_SEARCH_SUGGESTION_USER_RESULT_LIST =
            new TypeReference<List<SearchSuggestionUserResult>>() {
            };

    private long uid;
    private String screenName;
    private long followersCount;

    public long getUid() {
        return uid;
    }

    public void setUid(long uid) {
        this.uid = uid;
    }

    public String getScreenName() {
        return screenName;
    }

    public void setScreenName(String screenName) {
        this.screenName = screenName;
    }

    public long getFollowersCount() {
        return followersCount;
    }

    public void setFollowersCount(long followersCount) {
        this.followersCount = followersCount;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/Geo.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class Geo {
    private String type;
    private double[] coordinates;
    private String longitude;
    private String latitude;
    private String city;
    private String province;
    private String cityName;
    private String provinceName;
    private String address;
    private String pinyin;
    private String more;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public double[] getCoordinates() {
        return coordinates;
    }

    public void setCoordinates(double[] coordinates) {
        this.coordinates = coordinates;
    }

    public String getLongitude() {
        return longitude;
    }

    public void setLongitude(String longitude) {
        this.longitude = longitude;
    }

    public String getLatitude() {
        return latitude;
    }

    public void setLatitude(String latitude) {
        this.latitude = latitude;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCityName() {
        return cityName;
    }

    public void setCityName(String cityName) {
        this.cityName = cityName;
    }

    public String getProvinceName() {
        return provinceName;
    }

    public void setProvinceName(String provinceName) {
        this.provinceName = provinceName;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getPinyin() {
        return pinyin;
    }

    public void setPinyin(String pinyin) {
        this.pinyin = pinyin;
    }

    public String getMore() {
        return more;
    }

    public void setMore(String more) {
        this.more = more;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/OffsetX.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.LocationService;

public class OffsetX extends StringParam implements
        LocationService.GetMapImageParam {

    public OffsetX(String value) {
        super(value);
    }

    protected String paramKey() {
        return "offset_x";
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/CenterCoordinate.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.LocationService;

public class CenterCoordinate extends StringParam implements
        LocationService.GetMapImageParam {

    public CenterCoordinate(String value) {
        super(value);
    }

    public CenterCoordinate(Coordinate coordinate) {
        this(coordinate.toString());
    }

    public CenterCoordinate(Longitude longitude, Latitude latitude) {
        this(new Coordinate(longitude, latitude));
    }

    protected String paramKey() {
        return "center_coordinate";
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/FavoritesIdsItem.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

import java.util.Date;
import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class FavoritesIdsItem {
    private long status;
    private List<Tag> tags;
    private Date favoritedTime;

    public long getStatus() {
        return status;
    }

    public void setStatus(long status) {
        this.status = status;
    }

    public List<Tag> getTags() {
        return tags;
    }

    public void setTags(List<Tag> tags) {
        this.tags = tags;
    }

    public Date getFavoritedTime() {
        return favoritedTime;
    }

    public void setFavoritedTime(Date favoritedTime) {
        this.favoritedTime = favoritedTime;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/UrlReferer.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class UrlReferer {
    private int clicks;
    private String referer;

    public int getClicks() {
        return clicks;
    }

    public void setClicks(int clicks) {
        this.clicks = clicks;
    }

    public String getReferer() {
        return referer;
    }

    public void setReferer(String referer) {
        this.referer = referer;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Uid.java<|end_filename|>
package weiboclient4j.params;

import static weiboclient4j.utils.StringUtils.join;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author <NAME>
 */
public class Uid extends LongParam {
    public static final Uid EMPTY = new Uid(0);

    public Uid(long value) {
        super(value);
    }

    public Uid(String value) {
        super(value);
    }

    protected String paramKey() {
        return "uid";
    }

    public static ParameterAction uidsParam(final Collection<Uid> uids) {
        return new ParameterAction() {
            public void addParameter(Parameters params) {
                if (uids != null && uids.size() > 0) {
                    List<String> idList = new ArrayList<String>();
                    for (Uid uid : uids) {
                        idList.add(String.valueOf(uid.getValue()));
                    }
                    params.add("uids", join(idList, ","));
                }
            }
        };
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Section.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public class Section extends LongParam {
    public Section(long value) {
        super(value);
    }

    protected String paramKey() {
        return "section";
    }
}


<|start_filename|>src/main/java/weiboclient4j/utils/JsonUtils.java<|end_filename|>
package weiboclient4j.utils;

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.type.TypeReference;
import org.scribe.model.Response;
import weiboclient4j.WeiboClientException;
import weiboclient4j.WeiboError;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;

import static weiboclient4j.utils.StringUtils.isNotBlank;

/**
 * @author <NAME>
 */
public final class JsonUtils {

    private static ObjectMapper mapper = new ObjectMapper();

    static {
        mapper.setPropertyNamingStrategy(new SinaJsonNamingStrategy());

        SimpleDateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        mapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);
        mapper.setDateFormat(format);
    }

    private JsonUtils() {
    }

    public static <T> T readValue(String content, Class<T> valueType) throws IOException {
        return mapper.readValue(content, valueType);
    }

    public static <T> T readValue(String content, TypeReference valueTypeRef) throws IOException {
        return mapper.readValue(content, valueTypeRef);
    }

    public static <T> T parseJsonObject(Response response, Class<T> clazz) throws WeiboClientException {
        if (response.isSuccessful()) {
            return parseJsonObject(response.getCode(), response.getBody(), clazz);
        } else {
            throw createException(response);
        }
    }

    public static <T> List<T> parseJsonObject(Response response, TypeReference<List<T>> type)
            throws WeiboClientException {
        if (response.isSuccessful()) {
            return parseJsonObject(response.getCode(), response.getBody(), type);
        } else {
            throw createException(response);
        }
    }

    public static <T> List<T> parseJsonObject(String content, TypeReference<List<T>> type) throws WeiboClientException {
        try {
            return readValue(content, type);
        } catch (IOException e) {
            handleWeiboError(0, content, e);
            return Collections.emptyList();
        }
    }

    private static <T> List<T> parseJsonObject(int code, String body, TypeReference<List<T>> type)
            throws WeiboClientException {
        try {
            return readValue(body, type);
        } catch (IOException e) {
            handleWeiboError(code, body, e);
            return Collections.emptyList();
        }
    }

    public static <T> T parseJsonObject(String content, Class<T> clazz) throws WeiboClientException {
        try {
            return readValue(content, clazz);
        } catch (IOException e) {
            handleWeiboError(0, content, e);
            return null;
        }
    }

    private static <T> T parseJsonObject(int code, String content, Class<T> clazz) throws WeiboClientException {
        try {
            return readValue(content, clazz);
        } catch (IOException e) {
            handleWeiboError(code, content, e);
            return null;
        }
    }

    private static WeiboClientException createException(Response response) {
        String body = response.getBody();
        int code = response.getCode();

        if (isNotBlank(body)) {
            try {
                WeiboError error = readValue(body, WeiboError.class);
                return new WeiboClientException(code, body, error);
            } catch (IOException e) {
                return new WeiboClientException(code, body, e);
            }
        } else {
            return new WeiboClientException(code);
        }
    }

    private static void handleWeiboError(int code, String content, IOException e) throws WeiboClientException {
        try {
            WeiboError error = readValue(content, WeiboError.class);
            throw new WeiboClientException(code, content, error);
        } catch (IOException ioe) {
            throw new WeiboClientException(code, content, e);
        }
    }

    public static String writeObjectAsString(Object obj) throws IOException {
        return mapper.writeValueAsString(obj);
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/LongParam.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public abstract class LongParam implements ParameterAction {
    private long value;

    public LongParam(long value) {
        this.value = value;
    }

    public LongParam(String aLongValue) {
        try {
            this.value = Long.parseLong(aLongValue);
        } catch (NumberFormatException e) {
            throw new NumberFormatException(String.format("%s value [%s] is not a valid long number",
                    getClass().getSimpleName(), aLongValue));
        }
    }

    public long getValue() {
        return value;
    }

    @Override
    public String toString() {
        return String.valueOf(value);
    }

    public boolean isValid() {
        return value > 0;
    }

    protected abstract String paramKey();

    public void addParameter(Parameters params) {
        if (isValid()) {
            params.add(paramKey(), getValue());
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/FavoritesTags.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class FavoritesTags {
    private List<Tag> tags;
    private int totalNumber;

    public List<Tag> getTags() {
        return tags;
    }

    public void setTags(List<Tag> tags) {
        this.tags = tags;
    }

    public int getTotalNumber() {
        return totalNumber;
    }

    public void setTotalNumber(int totalNumber) {
        this.totalNumber = totalNumber;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/StringParam.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.utils.StringUtils;

/**
 * @author <NAME>
 */
public abstract class StringParam implements ParameterAction {
    private String value;

    public StringParam(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    @Override
    public String toString() {
        return value;
    }

    public boolean isValid() {
        return StringUtils.isNotBlank(value);
    }

    protected abstract String paramKey();

    public void addParameter(Parameters params) {
        if (isValid()) {
            params.add(paramKey(), getValue());
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Traffic.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.LocationService;

public class Traffic extends BooleanParam implements
        LocationService.GetMapImageParam {

    public Traffic(boolean value) {
        super(value);
    }

    protected String paramKey() {
        return "traffic";
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/SuggestionUserCategory.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public enum SuggestionUserCategory implements ParameterAction {
    Default("default"),
    Ent("ent"),
    HkFamous("hk_famous"),
    Model("model"),
    Cooking("cooking"),
    Sports("sports"),
    Finance("finance"),
    Tech("tech"),
    Singer("singer"),
    Writer("writer"),
    Moderator("moderator"),
    Medium("medium"),
    StockPlayer("stockplayer");

    private String value;

    SuggestionUserCategory(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public void addParameter(Parameters params) {
        if (this != Default) {
            params.add("category", getValue());
        }
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/UserIdList.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserIdList {
    private List<String> ids;
    private int totalNumber;
    private long nextCursor;
    private long previousCursor;

    public List<String> getIds() {
        return ids;
    }

    public void setIds(List<String> ids) {
        this.ids = ids;
    }

    public int getTotalNumber() {
        return totalNumber;
    }

    public void setTotalNumber(int totalNumber) {
        this.totalNumber = totalNumber;
    }

    public long getNextCursor() {
        return nextCursor;
    }

    public void setNextCursor(long nextCursor) {
        this.nextCursor = nextCursor;
    }

    public long getPreviousCursor() {
        return previousCursor;
    }

    public void setPreviousCursor(long previousCursor) {
        this.previousCursor = previousCursor;
    }
}


<|start_filename|>src/test/java/weiboclient4j/model/ParseUserTest.java<|end_filename|>
package weiboclient4j.model;

import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import static weiboclient4j.utils.JsonUtils.parseJsonObject;

/**
 * @author <NAME>
 */
public class ParseUserTest extends AbstractParseJsonTest {

    @Test
    public void testParseUser() throws Exception {
        String content = readResource("/weiboclient4j/model/users.json");
        User user = parseJsonObject(content, User.class);

        assertNotNull(user.getCreatedAt());
    }

    @Test
    public void testParseUser2() throws Exception {
        String content = readResource("/weiboclient4j/model/user2.json");
        parseJsonObject(content, User.class);
    }

    @Test
    public void testParseUserList() throws Exception {
        String content = readResource("/weiboclient4j/model/user_list.json");
        parseJsonObject(content, User.TYPE_USER_LIST);
    }
}


<|start_filename|>src/test/resources/weiboclient4j/model/error.json<|end_filename|>
{
  "request" : "/statuses/home_timeline.json",
  "error_code" : "20502",
  "error" : "Need you follow uid."
}


<|start_filename|>src/main/java/weiboclient4j/params/StatusParam.java<|end_filename|>
package weiboclient4j.params;

/**
 * @author <NAME>
 */
public class StatusParam extends StringParam {
    public StatusParam(String value) {
        super(value);
    }

    protected String paramKey() {
        return "status";
    }
}


<|start_filename|>src/main/java/weiboclient4j/RemindService.java<|end_filename|>
package weiboclient4j;

import weiboclient4j.model.UnreadCount;
import weiboclient4j.params.CountType;
import weiboclient4j.params.Uid;

/**
 * @author <NAME>
 */
public class RemindService extends AbstractService {
    public RemindService(WeiboClient client) {
        super(client);
    }

    public UnreadCount getUnreadCount() throws WeiboClientException {
        AccountService accountService = getClient().getAccountService();

        Uid uid = new Uid(accountService.getUid());
        return getUnreadCount(uid);
    }

    public UnreadCount getUnreadCount(Uid uid) throws WeiboClientException {
        return doGet("remind/unread_count", withParams(uid), UnreadCount.class);
    }

    public boolean resetCount(CountType type) throws WeiboClientException {
        ResultResponse response = doPost("https://rm.api.weibo.com/2/remind/set_count.json",
                withParams(type), ResultResponse.class);

        return response.isResult();
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/Id.java<|end_filename|>
package weiboclient4j.params;

import static weiboclient4j.utils.StringUtils.join;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author <NAME>
 */
public class Id extends LongParam {

    public static final String ID = "id";
    public static final String IDS = "ids";

    public Id(long value) {
        super(value);
    }

    public Id(String value) {
        super(value);
    }

    protected String paramKey() {
        return ID;
    }

    public static ParameterAction idParam(final Collection<Id> idList) {
        return new ParameterAction() {
            public void addParameter(Parameters params) {
                if (idList != null && idList.size() > 0) {
                    List<String> idStringList = new ArrayList<String>(idList.size());
                    for (Id id : idList) {
                        idStringList.add(String.valueOf(id.getValue()));
                    }
                    params.add(ID, join(idStringList, ","));
                }
            }
        };
    }

    public static ParameterAction idsParam(final Collection<Id> ids) {
        return new ParameterAction() {
            public void addParameter(Parameters params) {
                if (ids != null && ids.size() > 0) {
                    List<String> idStringList = new ArrayList<String>(ids.size());
                    for (Id id : ids) {
                        idStringList.add(String.valueOf(id.getValue()));
                    }
                    String idsString = join(idStringList, ",");
                    params.add(IDS, idsString);
                }
            }
        };
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/UserList.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

import java.util.List;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserList {
    private List<User> users;
    private int nextCursor;
    private int previousCursor;
    private long totalNumber;

    public List<User> getUsers() {
        return users;
    }

    public void setUsers(List<User> users) {
        this.users = users;
    }

    public int getNextCursor() {
        return nextCursor;
    }

    public void setNextCursor(int nextCursor) {
        this.nextCursor = nextCursor;
    }

    public int getPreviousCursor() {
        return previousCursor;
    }

    public void setPreviousCursor(int previousCursor) {
        this.previousCursor = previousCursor;
    }

    public long getTotalNumber() {
        return totalNumber;
    }

    public void setTotalNumber(long totalNumber) {
        this.totalNumber = totalNumber;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/LocationPoiList.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

import java.util.List;

@JsonIgnoreProperties(ignoreUnknown = true)
public class LocationPoiList {
    private String coordinates;
    private List<LocationPoi> pois;
    private long totalNumber;

    public String getCoordinates() {
        return coordinates;
    }

    public void setCoordinates(String coordinates) {
        this.coordinates = coordinates;
    }

    public List<LocationPoi> getPois() {
        return pois;
    }

    public void setPois(List<LocationPoi> pois) {
        this.pois = pois;
    }

    public long getTotalNumber() {
        return totalNumber;
    }

    public void setTotalNumber(long totalNumber) {
        this.totalNumber = totalNumber;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/MidResponse.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

/**
 * @author <NAME>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class MidResponse {
    private String mid;

    public String getMid() {
        return mid;
    }

    public void setMid(String mid) {
        this.mid = mid;
    }
}


<|start_filename|>src/main/java/weiboclient4j/params/StartBirth.java<|end_filename|>
package weiboclient4j.params;

import weiboclient4j.PlaceService;

/**
 * @author <NAME>
 */
public class StartBirth extends LongParam implements
        PlaceService.GetNearbyUsersListParam {
    public StartBirth(long value) {
        super(value);
    }

    protected String paramKey() {
        return "startbirth";
    }
}


<|start_filename|>src/main/java/weiboclient4j/oauth2/SinaWeibo2Api.java<|end_filename|>
package weiboclient4j.oauth2;

import org.scribe.builder.api.DefaultApi20;
import org.scribe.extractors.AccessTokenExtractor;
import org.scribe.model.OAuthConfig;
import org.scribe.model.Verb;
import org.scribe.oauth.OAuthService;
import static weiboclient4j.utils.StringUtils.encodeUrl;

/**
 * @author <NAME>
 */
public class SinaWeibo2Api extends DefaultApi20 {
    private static final String ACCESS_TOKEN_URL =
            "https://api.weibo.com/oauth2/access_token";

    private static final String AUTHORIZE_URL =
            "https://api.weibo.com/oauth2/authorize?"
                    + "client_id=%s"
                    + "&redirect_uri=%s"
                    + "&response_type=%s"
                    + "&state=%s"
                    + "&display=%s"
                    + "&forcelogin=%s";

    private ResponseType responseType = ResponseType.Code;

    private DisplayType displayType = DisplayType.Default;

    private GrantType grantType = GrantType.AuthorizationCode;

    private ForceLogin forceLogin = ForceLogin.No;

    private String state = "";

    public SinaWeibo2Api() {
    }

    public SinaWeibo2Api(GrantType grantType) {
        this.grantType = grantType;
    }

    public SinaWeibo2Api(ResponseType responseType, DisplayType displayType, ForceLogin forceLogin) {
        this.responseType = responseType;
        this.displayType = displayType;
        this.forceLogin = forceLogin;
    }

    @Override
    public AccessTokenExtractor getAccessTokenExtractor() {
        return new SinaWeibo2AccessTokenExtractor();
    }

    @Override
    public Verb getAccessTokenVerb() {
        return Verb.POST;
    }

    @Override
    public String getAccessTokenEndpoint() {
        return ACCESS_TOKEN_URL;
    }

    @Override
    public String getAuthorizationUrl(OAuthConfig config) {
        return String.format(AUTHORIZE_URL,
                config.getApiKey(),
                encodeUrl(config.getCallback()),
                responseType.getType(),
                state,
                displayType.getDisplay(),
                forceLogin.getValue());
    }

    @Override
    public OAuthService createService(OAuthConfig config) {
        return new SinaWeibo2ServiceImpl(this, config);
    }

    public ResponseType getResponseType() {
        return responseType;
    }

    public void setResponseType(ResponseType responseType) {
        this.responseType = responseType;
    }

    public DisplayType getDisplayType() {
        return displayType;
    }

    public void setDisplayType(DisplayType displayType) {
        this.displayType = displayType;
    }

    public GrantType getGrantType() {
        return grantType;
    }

    public void setGrantType(GrantType grantType) {
        this.grantType = grantType;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state == null ? "" : state;
    }
}


<|start_filename|>src/main/java/weiboclient4j/model/TokenInfo.java<|end_filename|>
package weiboclient4j.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class TokenInfo {

    private long uid;

    private String appkey;

    private String scope;

    private long createAt;

    private int expireIn;

    public long getUid() {
        return uid;
    }

    public void setUid(long uid) {
        this.uid = uid;
    }

    public String getAppkey() {
        return appkey;
    }

    public void setAppkey(String appkey) {
        this.appkey = appkey;
    }

    public String getScope() {
        return scope;
    }

    public void setScope(String scope) {
        this.scope = scope;
    }

    public long getCreateAt() {
        return createAt;
    }

    public void setCreateAt(long createAt) {
        this.createAt = createAt;
    }

    public int getExpireIn() {
        return expireIn;
    }

    public void setExpireIn(int expireIn) {
        this.expireIn = expireIn;
    }
}
