def works(self, ids = None, query = None, filter = None, offset = None,
              limit = None, sample = None, sort = None,
              order = None, facet = None, select = None, cursor = None,
              cursor_max = 5000, **kwargs):
        '''
        Search Crossref works

        :param ids: [Array] DOIs (digital object identifier) or other identifiers
        :param query: [String] A query string
        :param filter: [Hash] Filter options. See examples for usage.
            Accepts a dict, with filter names and their values. For repeating filter names
            pass in a list of the values to that filter name, e.g.,
            `{'award_funder': ['10.13039/100004440', '10.13039/100000861']}`.
            See https://github.com/CrossRef/rest-api-doc#filter-names
            for filter names and their descriptions and :func:`~habanero.Crossref.filter_names`
            and :func:`~habanero.Crossref.filter_details`
        :param offset: [Fixnum] Number of record to start at, from 1 to 10000
        :param limit: [Fixnum] Number of results to return. Not relavant when searching with specific dois.
            Default: 20. Max: 1000
        :param sample: [Fixnum] Number of random results to return. when you use the sample parameter,
            the limit and offset parameters are ignored. Max: 100
        :param sort: [String] Field to sort on. Note: If the API call includes a query, then the sort
            order will be by the relevance score. If no query is included, then the sort order
            will be by DOI update date. See sorting_ for possible values.
        :param order: [String] Sort order, one of 'asc' or 'desc'
        :param facet: [Boolean/String] Set to `true` to include facet results (default: false).
            Optionally, pass a query string, e.g., `facet=type-name:*` or `facet=license=*`.
            See Facets_ for options.
        :param select: [String/list(Strings)] Crossref metadata records can be
            quite large. Sometimes you just want a few elements from the schema. You can "select"
            a subset of elements to return. This can make your API calls much more efficient. Not
            clear yet which fields are allowed here.
        :param cursor: [String] Cursor character string to do deep paging. Default is None.
            Pass in '*' to start deep paging. Any combination of query, filters and facets may be
            used with deep paging cursors. While rows may be specified along with cursor, offset
            and sample cannot be used.
            See https://github.com/CrossRef/rest-api-doc/blob/master/rest_api.md#deep-paging-with-cursors
        :param cursor_max: [Fixnum] Max records to retrieve. Only used when cursor param used. Because
            deep paging can result in continuous requests until all are retrieved, use this
            parameter to set a maximum number of records. Of course, if there are less records
            found than this value, you will get only those found.
        :param kwargs: additional named arguments passed on to `requests.get`, e.g., field
            queries (see examples and FieldQueries_) 

        :return: A dict

        Usage::

            from habanero import Crossref
            cr = Crossref()
            cr.works()
            cr.works(ids = '10.1371/journal.pone.0033693')
            dois = ['10.1371/journal.pone.0033693', ]
            cr.works(ids = dois)
            x = cr.works(query = "ecology")
            x['status']
            x['message-type']
            x['message-version']
            x['message']
            x['message']['total-results']
            x['message']['items-per-page']
            x['message']['query']
            x['message']['items']

            # Get full text links
            x = cr.works(filter = {'has_full_text': True})
            x

            # Parse output to various data pieces
            x = cr.works(filter = {'has_full_text': True})
            ## get doi for each item
            [ z['DOI'] for z in x['message']['items'] ]
            ## get doi and url for each item
            [ {"doi": z['DOI'], "url": z['URL']} for z in x['message']['items'] ]
            ### print every doi
            for i in x['message']['items']:
                 print i['DOI']

            # filters - pass in as a dict
            ## see https://github.com/CrossRef/rest-api-doc#filter-names
            cr.works(filter = {'has_full_text': True})
            cr.works(filter = {'has_funder': True, 'has_full_text': True})
            cr.works(filter = {'award_number': 'CBET-0756451', 'award_funder': '10.13039/100000001'})
            ## to repeat a filter name, pass in a list
            x = cr.works(filter = {'award_funder': ['10.13039/100004440', '10.13039/100000861']}, limit = 100)
            map(lambda z:z['funder'][0]['DOI'], x['message']['items'])

            # Deep paging, using the cursor parameter
            ## this search should lead to only ~215 results
            cr.works(query = "widget", cursor = "*", cursor_max = 100)
            ## this search should lead to only ~2500 results, in chunks of 500
            res = cr.works(query = "octopus", cursor = "*", limit = 500)
            sum([ len(z['message']['items']) for z in res ])
            ## about 167 results
            res = cr.works(query = "extravagant", cursor = "*", limit = 50, cursor_max = 500)
            sum([ len(z['message']['items']) for z in res ])
            ## cursor_max to get back only a maximum set of results
            res = cr.works(query = "widget", cursor = "*", cursor_max = 100)
            sum([ len(z['message']['items']) for z in res ])
            ## cursor_max - especially useful when a request could be very large
            ### e.g., "ecology" results in ~275K records, lets max at 10,000
            ###   with 1000 at a time
            res = cr.works(query = "ecology", cursor = "*", cursor_max = 10000, limit = 1000)
            sum([ len(z['message']['items']) for z in res ])
            items = [ z['message']['items'] for z in res ]
            items = [ item for sublist in items for item in sublist ]
            [ z['DOI'] for z in items ][0:50]

            # field queries
            res = cr.works(query = "ecology", query_author = 'carl boettiger')
            [ x['author'][0]['family'] for x in res['message']['items'] ]

            # select certain fields to return
            ## as a comma separated string
            cr.works(query = "ecology", select = "DOI,title")
            ## or as a list
            cr.works(query = "ecology", select = ["DOI","title"])
        '''
        if ids.__class__.__name__ != 'NoneType':
            return request(self.mailto, self.base_url, "/works/", ids,
                query, filter, offset, limit, sample, sort,
                order, facet, select, None, None, None, None, **kwargs)
        else:
            return Request(self.mailto, self.base_url, "/works/",
              query, filter, offset, limit, sample, sort,
              order, facet, select, cursor, cursor_max, None, **kwargs).do_request()
Search Crossref works

        :param ids: [Array] DOIs (digital object identifier) or other identifiers
        :param query: [String] A query string
        :param filter: [Hash] Filter options. See examples for usage.
            Accepts a dict, with filter names and their values. For repeating filter names
            pass in a list of the values to that filter name, e.g.,
            `{'award_funder': ['10.13039/100004440', '10.13039/100000861']}`.
            See https://github.com/CrossRef/rest-api-doc#filter-names
            for filter names and their descriptions and :func:`~habanero.Crossref.filter_names`
            and :func:`~habanero.Crossref.filter_details`
        :param offset: [Fixnum] Number of record to start at, from 1 to 10000
        :param limit: [Fixnum] Number of results to return. Not relavant when searching with specific dois.
            Default: 20. Max: 1000
        :param sample: [Fixnum] Number of random results to return. when you use the sample parameter,
            the limit and offset parameters are ignored. Max: 100
        :param sort: [String] Field to sort on. Note: If the API call includes a query, then the sort
            order will be by the relevance score. If no query is included, then the sort order
            will be by DOI update date. See sorting_ for possible values.
        :param order: [String] Sort order, one of 'asc' or 'desc'
        :param facet: [Boolean/String] Set to `true` to include facet results (default: false).
            Optionally, pass a query string, e.g., `facet=type-name:*` or `facet=license=*`.
            See Facets_ for options.
        :param select: [String/list(Strings)] Crossref metadata records can be
            quite large. Sometimes you just want a few elements from the schema. You can "select"
            a subset of elements to return. This can make your API calls much more efficient. Not
            clear yet which fields are allowed here.
        :param cursor: [String] Cursor character string to do deep paging. Default is None.
            Pass in '*' to start deep paging. Any combination of query, filters and facets may be
            used with deep paging cursors. While rows may be specified along with cursor, offset
            and sample cannot be used.
            See https://github.com/CrossRef/rest-api-doc/blob/master/rest_api.md#deep-paging-with-cursors
        :param cursor_max: [Fixnum] Max records to retrieve. Only used when cursor param used. Because
            deep paging can result in continuous requests until all are retrieved, use this
            parameter to set a maximum number of records. Of course, if there are less records
            found than this value, you will get only those found.
        :param kwargs: additional named arguments passed on to `requests.get`, e.g., field
            queries (see examples and FieldQueries_) 

        :return: A dict

        Usage::

            from habanero import Crossref
            cr = Crossref()
            cr.works()
            cr.works(ids = '10.1371/journal.pone.0033693')
            dois = ['10.1371/journal.pone.0033693', ]
            cr.works(ids = dois)
            x = cr.works(query = "ecology")
            x['status']
            x['message-type']
            x['message-version']
            x['message']
            x['message']['total-results']
            x['message']['items-per-page']
            x['message']['query']
            x['message']['items']

            # Get full text links
            x = cr.works(filter = {'has_full_text': True})
            x

            # Parse output to various data pieces
            x = cr.works(filter = {'has_full_text': True})
            ## get doi for each item
            [ z['DOI'] for z in x['message']['items'] ]
            ## get doi and url for each item
            [ {"doi": z['DOI'], "url": z['URL']} for z in x['message']['items'] ]
            ### print every doi
            for i in x['message']['items']:
                 print i['DOI']

            # filters - pass in as a dict
            ## see https://github.com/CrossRef/rest-api-doc#filter-names
            cr.works(filter = {'has_full_text': True})
            cr.works(filter = {'has_funder': True, 'has_full_text': True})
            cr.works(filter = {'award_number': 'CBET-0756451', 'award_funder': '10.13039/100000001'})
            ## to repeat a filter name, pass in a list
            x = cr.works(filter = {'award_funder': ['10.13039/100004440', '10.13039/100000861']}, limit = 100)
            map(lambda z:z['funder'][0]['DOI'], x['message']['items'])

            # Deep paging, using the cursor parameter
            ## this search should lead to only ~215 results
            cr.works(query = "widget", cursor = "*", cursor_max = 100)
            ## this search should lead to only ~2500 results, in chunks of 500
            res = cr.works(query = "octopus", cursor = "*", limit = 500)
            sum([ len(z['message']['items']) for z in res ])
            ## about 167 results
            res = cr.works(query = "extravagant", cursor = "*", limit = 50, cursor_max = 500)
            sum([ len(z['message']['items']) for z in res ])
            ## cursor_max to get back only a maximum set of results
            res = cr.works(query = "widget", cursor = "*", cursor_max = 100)
            sum([ len(z['message']['items']) for z in res ])
            ## cursor_max - especially useful when a request could be very large
            ### e.g., "ecology" results in ~275K records, lets max at 10,000
            ###   with 1000 at a time
            res = cr.works(query = "ecology", cursor = "*", cursor_max = 10000, limit = 1000)
            sum([ len(z['message']['items']) for z in res ])
            items = [ z['message']['items'] for z in res ]
            items = [ item for sublist in items for item in sublist ]
            [ z['DOI'] for z in items ][0:50]

            # field queries
            res = cr.works(query = "ecology", query_author = 'carl boettiger')
            [ x['author'][0]['family'] for x in res['message']['items'] ]

            # select certain fields to return
            ## as a comma separated string
            cr.works(query = "ecology", select = "DOI,title")
            ## or as a list
            cr.works(query = "ecology", select = ["DOI","title"])