text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using Newtonsoft.Json;
using zohobooks.model;
using System.Diagnostics;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.IO;
using zohobooks.util;
using zohobooks.parser;

namespace zohobooks.api
{
    ///
    /// Class InvoicesApi is used to

    ///     Get the list of invoices,invoice payments,credits applied or comments for an invoice,

    ///     Get the details of the invoice,invoice mail content,invoices as pdf,invoice templates or an invoice
    ///     ,

    ///     Update the details,templates,billing and shipping addresses,attachment preferences,comment of the specifed invoice,

    ///     Mark the status as sent,void or draft,

    ///     Reminder to the customer or multiple customers by email,

    ///     Apply creditnote to the invoice,

    ///     Add a comment or attachment to the invoice,

    ///     Delete the invoice,payment made to invoice or comment of the invoice.

    ///
    public class InvoicesApi:Api
    {

        static string baseAddress =baseurl + "/invoices";
        ///
        /// Initializes a new instance of the <see cref="InvoicesApi" /> class.
        ///
        /// <param name="auth_token">The auth_token is used for the authentication purpose.</param>
        /// <param name="organization_Id">The organization_ identifier is used to define the current working organisation.</param>
        public InvoicesApi(string auth_token, string organization_Id)
            : base(auth_token, organization_Id)
        {

        }

        ///
        /// List all invoices with pagination.
        ///
        /// <param name="parameters">The parameters is the Dictionary object which contains the filters in the form of key,value pairs to refine the list.

The possible filters are listed below

        ///

        ///
invoice_number	Search invoices by invoice number.

Variants: invoice_number_startswith and invoice_number_contains

        ///
item_name	Search invoices by item name.

Variants: item_name_startswith and item_name_contains

        ///
item_id	Search invoices by item id.

        ///
item_description	Search invoices by item description.

Variants: item_description_startswith and item_description_contains

        ///
reference_number	Search invoices by invoice reference number (i.e., P.O.#).

Variants: reference_number_startswith and reference_number_contains

        ///
customer_name	Search invoices by customer name.

Variants: customer_name_startswith and customer_name_contains

        ///
recurring_invoice_id	Search invoices by recurring profile id.

        ///
email	Search invoices by customer contact persons email.

        ///
total	Search invoices by invoice total.

Variants: total_less_than, total_less_equals, total_greater_than and total_greater_equals

        ///
balance	Search invoices by invoice total.

Variants: balance_less_than, balance_less_equals, balance_greater_than and balance_greater_equals

        ///
date	Search invoices by invoice date.

Variants: date_start, date_end, date_before and date_after

        ///
due_date	Search invoices by due date.

Variants: due_date_start, due_date_end, due_date_before and due_date_after

        ///
status	Search invoices by invoice status.

Allowed Values: sent, draft, overdue, paid, void, unpaid, partiallypaid and viewed

        ///
customer_id	Search invoices by customer id.

        ///
custom_field	Search invoices by custom fields.

Variants: custom_field_startswith and custom_field_contains

        ///
filter_by	Filter invoices by any status or payment expected date.

Allowed Values: Status.All, Status.Sent, Status.Draft, Status.OverDue, Status.Paid, Status.Void, Status.Unpaid, Status.PartiallyPaid, Status.Viewed and Date.PaymentExpectedDate

        ///
search_text	Search invoices by invoice number or purchase order or customer name.

        ///
sort_column	Sort invoices.

Allowed Values: customer_name, invoice_number, date, due_date, total, balance and created_time

        ///

        /// </param>
        /// <returns>InvoicesList object.</returns>
        public InvoicesList GetInvoices(Dictionary<object, object> parameters)
        {
            string url = baseAddress;
            var responce = ZohoHttpClient.get(url, getQueryParameters(parameters));
            return InvoiceParser.getInvoiceList(responce);
        }

        ///
        /// Get the details of an invoice.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <param name="parameters">The parameters is the dictionary object which contains the following optional parameters in the key,value pair forms.

        ///

        ///
print	Print the exported pdf.

        ///
accept	Get the details of a particular invoice in formats such as json/ pdf/ html. Default format is json.

Allowed Values: json, pdf and html

        ///

        /// </param>
        /// <returns>Invoice object.</returns>
        public Invoice Get(string invoice_id, Dictionary<object, object> parameters)
        {
            string url = baseAddress + "/" + invoice_id;
            var responce = ZohoHttpClient.get(url, getQueryParameters(parameters));
            return InvoiceParser.getInvoice(responce);
        }

        ///
        /// Create an invoice for customer.
        ///
        /// <param name="new_invoice_info">The new_invoice_info is the Invoice object .</param>
        /// <param name="parameters">The parameters is the dictionary object which contains the following optional parameters in the key,value pair forms.

        ///

        ///
send	Send the invoice to the contact person(s) associated with the invoice.

Allowed Values: true and false

        ///
ignore_auto_number_generation	Ignore auto invoice number generation for this invoice. This mandates the invoice number.

Allowed Values: true and false

        ///
</param>
        /// <returns>Invoice object.</returns>
        public Invoice Create(Invoice new_invoice_info, Dictionary<object, object> parameters)
        {
            string url = baseAddress;
            var json = JsonConvert.SerializeObject(new_invoice_info);
            parameters.Add("JSONString", json);
            var responce = ZohoHttpClient.post(url, getQueryParameters(parameters));
            var responceContent = responce.Content.ReadAsStringAsync().Result;
            return InvoiceParser.getInvoice(responce);
        }

        ///
        /// Update an existing invoice. To delete a line item just remove it from the line_items list.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <param name="update_info">The update_info is the Invoice object which contains the update information.</param>
        /// <param name="parameters">The parameters is the dictionary object which contains the following optional parameters in the key,value pair forms.

        ///

        ///
ignore_auto_number_generation	Ignore auto invoice number generation for this invoice. This mandates the invoice number.

Allowed Values: true and false

        ///
</param>
        /// <returns>Invoice object.</returns>
        public Invoice Update(string invoice_id, Invoice update_info, Dictionary<object, object> parameters)
        {
            string url = baseAddress + "/" + invoice_id;
            var json = JsonConvert.SerializeObject(update_info);
            parameters.Add("JSONString", json);
            var responce = ZohoHttpClient.put(url, getQueryParameters(parameters));
            var responceContent = responce.Content.ReadAsStringAsync().Result;
            return InvoiceParser.getInvoice(responce);
        }

        ///
        /// Delete an existing invoice. Invoices which have payment or credits note applied cannot be deleted.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <returns>System.String

 The success message is "The invoice has been deleted."</returns>
        public string Delete(string invoice_id)
        {
            string url = baseAddress + "/" + invoice_id;
            var responce = ZohoHttpClient.delete(url, getQueryParameters());
            return InvoiceParser.getMessage(responce);
        }

        ///
        /// Mark a draft invoice as sent.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <returns>System.String

 The success message is "Invoice status has been changed to Sent."</returns>
        public string MarkAsSent(string invoice_id)
        {
            string url = baseAddress + "/" + invoice_id + "/status/sent";
            var responce = ZohoHttpClient.post(url, getQueryParameters());
            return InvoiceParser.getMessage(responce);
        }

        ///
        /// Mark an invoice status as void. Upon voiding, the payments and credits associated with the invoices will be unassociated and will be under customer credits.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <returns>System.String

 The success message is "Invoice status has been changed to Void."</returns>
        public string MarkAsVoid(string invoice_id)
        {
            string url = baseAddress + "/" + invoice_id + "/status/void";
            var responce = ZohoHttpClient.post(url, getQueryParameters());
            return InvoiceParser.getMessage(responce);
        }

        ///
        ///Mark a voided invoice as draft.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <returns>System.String

 The success message is "Status of invoice changed from void to draft."</returns>
        public string MarkAsDraft(string invoice_id)
        {
            string url = baseAddress + "/" + invoice_id + "/status/draft";
            var responce = ZohoHttpClient.post(url, getQueryParameters());
            return InvoiceParser.getMessage(responce);
        }

        ///
        /// Email an invoice to the customer. Input json string is not mandatory. If input json string is empty, mail will be send with default mail content.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <param name="email_details">The email_details is the EmailNotification object with to_mail_ids as mandatory attribute.</param>
        /// <param name="attachment_paths">The attachment_paths is the file paths which are going to be attached to the mail.</param>
        /// <param name="parameters">The parameters is the dictionary object which contains the following optional parameters in the key,value pair forms.

        ///

        ///
send_customer_statement	Send customer statement pdf a with email.

        ///
send_attachment	Send the invoice attachment a with the email.

        ///

        /// </param>
        /// <returns>System.String

 The success message is "Your invoice has been sent."</returns>
        public string SendEmail(string invoice_id, EmailNotification email_details, string[] attachment_paths, Dictionary<object, object> parameters)
        {
            string url = baseAddress + "/" + invoice_id + "/email";
            var json = JsonConvert.SerializeObject(email_details);
            var jsonString = new Dictionary<object, object>();
            jsonString.Add("JSONString", json);
            var files = new KeyValuePair<string, string[]>("attachments", attachment_paths);
            var responce = ZohoHttpClient.post(url, getQueryParameters(parameters),jsonString,files);
            string responceContent = responce.Content.ReadAsStringAsync().Result;
            return InvoiceParser.getMessage(responce);
        }

        ///
        /// Send invoices to your customers by email. Maximum of 10 invoices can be sent at once.
        ///
        /// <param name="contacts">The contacts is the Contacts object with contact_id as a mandatory attribute.</param>
        /// <param name="parameters">The parameters is the dictionary object which is having the following mandatory parameter in the form of key,value pair.

        ///

invoice_ids	Comma separated invoice ids which are to be emailed.

        /// </param>
        /// <returns>System.String

 The success message is "Mission accomplished! We've sent all the invoices." </returns>
        public string EmailInvoices(Contacts contacts, Dictionary<object, object> parameters)
        {
            string url = baseAddress + "/email";
            var json = JsonConvert.SerializeObject(contacts);
            parameters.Add("JSONString", json);
            var responce = ZohoHttpClient.post(url, getQueryParameters(parameters));
            string responceContent = responce.Content.ReadAsStringAsync().Result;
            return InvoiceParser.getMessage(responce);
        }

        ///
        /// Get the email content of an invoice.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <param name="parameters">The parameters is the dictionary object which contains the optional parameter that will provides the template as key,value pair.

        ///

email_template_id	Get the email content based on a specific email template. If this param is not inputted, then the content will be based on the email template associated with the customer. If no template is associated with the customer, then default template will be used.

        /// </param>
        /// <returns>Email object.</returns>
        public Email GetEmailContent(string invoice_id, Dictionary<object, object> parameters)
        {
            string url = baseAddress + "/" + invoice_id + "/email";
            var responce = ZohoHttpClient.get(url, getQueryParameters(parameters));
            return ContactParser.getEmailContent(responce);
        }

        ///
        /// Remind your customer about an unpaid invoice by email. Reminder will be sent, only for the invoices which are in open or overdue status.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <param name="notify_details">The notify_details is the EmailNotification object with to_mail_ids as mandatory parameter.</param>
        /// <param name="parameters">The parameters is the dictionary object which contains the following optional parameter in the key,value pair format.

        ///

send_customer_statement	Send customer statement pdf a with payment reminder.

        /// </param>
        /// <returns>System.String

 The success message is "Your payment reminder has been sent."</returns>
        public string RemindCustomer(string invoice_id, EmailNotification notify_details, Dictionary<object, object> parameters)
        {
            string url = baseAddress + "/" + invoice_id + "/paymentreminder";
            var json = JsonConvert.SerializeObject(notify_details);
            parameters.Add("JSONString", json);
            var responce = ZohoHttpClient.post(url, getQueryParameters(parameters));
            return InvoiceParser.getMessage(responce);
        }

        ///
        /// Remind your customer about an unpaid invoices by email. Reminder mail will be send, only for the invoices is in open or overdue status. Maximum 10 invoices can be reminded at once.
        ///
        /// <param name="parameters">The parameters is the dictionary object which conatins the following mandatory pameter in the key value pair format.

        ///

invoice_ids*	Array of invoice ids for which the reminder has to be sent.

        /// </param>
        /// <returns>System.String

 The success message is "Success! All reminders have been sent." </returns>
        public string BulkInvoiceReminder(Dictionary<object, object> parameters)
        {
            string url = baseAddress + "/paymentreminder";
            var responce = ZohoHttpClient.post(url, getQueryParameters(parameters));
            return InvoiceParser.getMessage(responce);
        }

        ///
        /// Gets the mail content of the payment reminder.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <returns>Email object.</returns>
        public Email GetPaymentReminder(string invoice_id)
        {
            string url = baseAddress + "/" + invoice_id + "/paymentreminder";
            var responce = ZohoHttpClient.get(url, getQueryParameters());
            return ContactParser.getEmailContent(responce);
        }

        ///
        /// Maximum of 25 invoices can be exported in a single pdf.
        ///
        /// <param name="parameters">The parameters is the dictionary object which conatins the following mandatory pameter in the key value pair format.

        ///

invoice_ids*	Array of invoice ids for which the reminder has to be sent.

        /// </param>
        /// <returns>System.String

 The success message is "the selected invoices are exported "</returns>
        public string BulkExport(Dictionary<object, object> parameters)
        {
            string url = baseAddress + "/pdf";
            ZohoHttpClient.getFile(url, getQueryParameters(parameters));
            return "the selected invoices are exported ";

        }

        ///
        /// Export invoices as pdf and print them. Maximum of 25 invoices can be printed.
        ///
        /// <param name="parameters">The parameters is the dictionary object which conatins the following mandatory pameter in the key value pair format.

        ///

invoice_ids*	Array of invoice ids for which the reminder has to be sent.

        /// </param>
        /// <returns>System.String

 The success message is "the selected invoices are printed "</returns>
        public string BulkPrint(Dictionary<object, object> parameters)
        {
            string url = baseAddress + "/print";
             ZohoHttpClient.getFile(url, getQueryParameters(parameters));
                return "the selected invoices are printed ";
        }

        ///
        /// Disables automated payment reminders for an invoice.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <returns>System.String

 The success message is "Reminders stopped."</returns>
        public string DisablePaymentReminder(string invoice_id)
        {
            string url = baseAddress + "/" + invoice_id + "/paymentreminder/disable";
            var responce = ZohoHttpClient.post(url, getQueryParameters());
            return InvoiceParser.getMessage(responce);
        }

        ///
        /// Enables automated payment reminders for an invoice.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <returns>System.String

 The success message is "Reminders enabled." </returns>
        public string EnablePaymentReminder(string invoice_id)
        {
            string url = baseAddress + "/" + invoice_id + "/paymentreminder/enable";
            var responce = ZohoHttpClient.post(url, getQueryParameters());
            return InvoiceParser.getMessage(responce);
        }

        ///
        /// Write off the invoice balance amount of an invoice.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <returns>System.String

 The success message is "Invoice has been written off."</returns>
        public string WriteoffInvoice(string invoice_id)
        {
            string url = baseAddress + "/" + invoice_id + "/writeoff";
            var responce = ZohoHttpClient.post(url, getQueryParameters());
            return InvoiceParser.getMessage(responce);
        }

        ///
        /// Cancel the write off amount of an invoice.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <returns>System.String

 The success message is "The write off done for this invoice has been cancelled." </returns>
        public string CancelWriteoff(string invoice_id)
        {
            string url = baseAddress + "/" + invoice_id + "/writeoff/cancel";
            var responce = ZohoHttpClient.post(url, getQueryParameters());
            return InvoiceParser.getMessage(responce);
        }

        ///
        /// Updates the billing address for this invoice alone. You can set this address as default billing address for your customer by specifying 'is_update_customer' param as true.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <param name="update_info">The update_info ois the Address object which contains the updation information.</param>
        /// <returns>System.String

 The success message is "Billing address updated"</returns>
        public string UpdateBillingAddress(string invoice_id, Address update_info)
        {
            string url = baseAddress + "/" + invoice_id + "/address/billing";
            var json = JsonConvert.SerializeObject(update_info);
            var jsonstring = new Dictionary<object, object>();
            jsonstring.Add("JSONString", json);
            var responce = ZohoHttpClient.put(url, getQueryParameters(jsonstring));
            return InvoiceParser.getMessage(responce);
        }

        ///
        /// Updates the shipping address for this invoice. You can set this address as default shipping address for your customer by specifying 'is_update_customer' param as true.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <param name="update_info">The update_info ois the Address object which contains the updation information.</param>
        /// <returns>System.String

 The success message is "Shipping address updated"</returns>
        public string UpdateShippingAddress(string invoice_id, Address update_info)
        {
            string url = baseAddress + "/" + invoice_id + "/address/shipping";
            var json = JsonConvert.SerializeObject(update_info);
            var jsonstring = new Dictionary<object, object>();
            jsonstring.Add("JSONString", json);
            var responce = ZohoHttpClient.put(url, getQueryParameters(jsonstring));
            return InvoiceParser.getMessage(responce);
        }

        ///
        /// Get all invoice pdf templates.
        ///
        /// <returns>List of Template objects.</returns>
        public TemplateList GetTemplates()
        {
            string url = baseAddress + "/templates" ;
            var responce = ZohoHttpClient.get(url, getQueryParameters());
            return CreditNoteParser.getTemplateList(responce);
        }

        ///
        /// Update the pdf template associated with the invoice.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <param name="template_id">The template_id is the identifer of the template .</param>
        /// <returns>System.String

 The success message is "Invoice information has been updated." </returns>
        public string UpdateTemplate(string invoice_id, string template_id)
        {
            string url = baseAddress +"/"+ invoice_id+"/templates/"+template_id ;
            var responce = ZohoHttpClient.put(url, getQueryParameters());
            return InvoiceParser.getMessage(responce);
        }
//-------------------------------------------------------------------------------------------------------
        ///
        /// Get the list of payments made for an invoice.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <returns>List of InvoicePayment objects.</returns>
        public PaymentList GetPayments(string invoice_id)
        {
            string url = baseAddress + "/" + invoice_id + "/payments";
            var responce = ZohoHttpClient.get(url, getQueryParameters());
            return InvoiceParser.getPaymentsList(responce);
        }

        ///
        /// Get the list of credits applied for an invoice.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <returns>List of Creditnote objects.</returns>
        public CreditNoteList GetCreditsApplied(string invoice_id)
        {
            string url = baseAddress + "/" + invoice_id + "/creditsapplied";
            var responce = ZohoHttpClient.get(url, getQueryParameters());
            return InvoiceParser.getCredits(responce);
        }

        ///
        /// Apply the customer credits either from credit notes or excess customer payments to an invoice. Multiple credits can be applied at once.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <param name="credits_to_apply">The credits_to_apply is the UseCredits object which contains the credits information to apply.</param>
        /// <returns>UseCredits object.</returns>
        public UseCredits AddCredits(string invoice_id, UseCredits credits_to_apply)
        {
            string url = baseAddress + "/" + invoice_id + "/credits";
            var json = JsonConvert.SerializeObject(credits_to_apply);
            var jsonstring = new Dictionary<object, object>();
            jsonstring.Add("JSONString", json);
            var responce = ZohoHttpClient.post(url, getQueryParameters(jsonstring));
            return InvoiceParser.getUseCredits(responce);
        }

        ///
        /// Deletes a payment made to an invoice.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <param name="payment_id">The payment_id is the identifier of the payment.</param>
        /// <returns>System.String

 The success message is "The payment has been deleted."</returns>
        public string DeletePayment(string invoice_id, string payment_id)
        {
            string url = baseAddress + "/" + invoice_id+"/payments/"+payment_id;
            var responce = ZohoHttpClient.delete(url, getQueryParameters());
            return InvoiceParser.getMessage(responce);
        }

        ///
        /// Deltes the applied credit.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <param name="creditnote_id">The creditnote_id is the identifier of the creditnote which applied for the specified invoice.</param>
        /// <returns>System.String

 The success message is "Credits applied to an invoice have been deleted." </returns>
        public string DelteAppliedCredit(string invoice_id, string creditnote_id)
        {
            string url = baseAddress + "/" + invoice_id + "/creditsapplied/" + creditnote_id;;
            var responce = ZohoHttpClient.delete(url, getQueryParameters());
            return InvoiceParser.getMessage(responce);
        }
//----------------------------------------------------------------------------------------------------------------
        ///
        /// Get the complete history and comments of an invoice.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <returns>List of Comment objects</returns>
        public CommentList GetComments(string invoice_id)
        {
            string url = baseAddress + "/" + invoice_id + "/comments";;
            var responce = ZohoHttpClient.get(url, getQueryParameters());
            return CreditNoteParser.getCommentList(responce);
        }

        ///
        /// Add a comment for an invoice.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <param name="new_comment_info">The new_comment_info is the Comment object which contains the information to add a new comment.</param>
        /// <returns>Comment object.</returns>
        public Comment AddComment(string invoice_id, Comment new_comment_info)
        {
            string url = baseAddress + "/" + invoice_id + "/comments";
            var json = JsonConvert.SerializeObject(new_comment_info);
            var jsonstring = new Dictionary<object, object>();
            jsonstring.Add("JSONString", json);
            var responce = ZohoHttpClient.post(url, getQueryParameters(jsonstring));
            return CreditNoteParser.getComment(responce);
        }

        ///
        /// Update an existing comment of an invoice.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <param name="comment_id">The comment_id is the identifier of the comment of specified invoice.</param>
        /// <param name="update_info">The update_info is the Comment object which contains the updation information.</param>
        /// <returns>Comment object.</returns>
        public Comment UpdateComment(string invoice_id, string comment_id, Comment update_info)
        {
            string url = baseAddress + "/" + invoice_id + "/comments/"+comment_id;
            var json = JsonConvert.SerializeObject(update_info);
            var jsonstring = new Dictionary<object, object>();
            jsonstring.Add("JSONString", json);
            var responce = ZohoHttpClient.put(url, getQueryParameters(jsonstring));
            return CreditNoteParser.getComment(responce);
        }

        ///
        /// Delete an invoice comment.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <param name="comment_id">The comment_id is the identifier of the comment of specified invoice.</param>
        /// <returns>System.String

 The success message is "The comment has been deleted." </returns>
        public string DeleteComment(string invoice_id, string comment_id)
        {
            string url = baseAddress + "/" + invoice_id + "/comments/"+comment_id;
            var responce = ZohoHttpClient.delete(url, getQueryParameters());
            return InvoiceParser.getMessage(responce);
        }
//--------------------------------------------------------------------------------------------
        ///
        /// Returns the file attached to the invoice.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <returns>System.String

 The success message is "the selected expense receipt is saved at home directory" </returns>
        public string GetAttachment(string invoice_id)
        {
            string url = baseAddress + "/" + invoice_id + "/attachment";
            ZohoHttpClient.getFile(url, getQueryParameters());
            return "the selected expense receipt is saved at home directory";
        }

        ///
        /// Attach a file to an invoice.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <param name="attachment_Path">The attachment_ path is the file information which is going to be attached to thr invoice.</param>
        /// <param name="parameters">The parameters is the Dictionary object which contains the following optional parameter in the form of key,value pair.

        ///

can_send_in_mail	True to send the attachment with the invoice when emailed.

        /// </param>
        /// <returns>System.String

 The success message is "Your file has been successfully attached to the invoice." </returns>
        public string AddAttachment(string invoice_id, string attachment_Path, Dictionary<object, object> parameters)
        {
            string url = baseAddress + "/" + invoice_id + "/attachment";
            var attachment = new string[] { attachment_Path };
            var file = new KeyValuePair<string, string[]>("attachment", attachment);
            var responce = ZohoHttpClient.post(url, getQueryParameters(parameters),null, file);
            return InvoiceParser.getMessage(responce);
        }

        ///
        /// Set whether you want to send the attached file while emailing the invoice.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <param name="parameters">The parameters is the Dictionary object which contains the following mandatory parameter in the form of key,value pair.

        ///

can_send_in_mail*	True to send the attachment with the invoice when emailed.

        /// </param>
        /// <returns>System.String

 The success message is "Invoice information has been updated." </returns>
        public string UpdateAttachment(string invoice_id, Dictionary<object, object> parameters)
        {
            string url = baseAddress + "/" + invoice_id + "/attachment";
            var responce = ZohoHttpClient.put(url, getQueryParameters(parameters));
            return InvoiceParser.getMessage(responce);
        }

        ///
        /// Delete the file attached to the invoice.
        ///
        /// <param name="invoice_id">The invoice_id is the identifier of the invoice.</param>
        /// <returns>System.String

 The success message is "Your file is no longer attached to the invoice." </returns>
        public string DeleteAttachment(string invoice_id)
        {
            string url = baseAddress + "/" + invoice_id + "/attachment";
            var responce = ZohoHttpClient.delete(url, getQueryParameters());
            return InvoiceParser.getMessage(responce);
        }

        ///
        /// Delete the expense receipts attached to an invoice which is raised from an expense.
        ///
        /// <param name="expense_id">The expense_id is the identifier of the expense.</param>
        /// <returns>System.String

 The success message is "The attached expense receipt has been deleted."</returns>
        public string DeleteExpenseReceipt(string expense_id)
        {
            string url = baseAddress + "/expenses/" + expense_id + "/receipt";
            var responce = ZohoHttpClient.delete(url, getQueryParameters());
            return InvoiceParser.getMessage(responce);
        }
    }
}


text:
def get_version():
    return 1

redpajama_set_name: RedPajamaGithub


text:
namespace GlobalcachingApplication.Plugins.GoogleEarth
{
    partial class MapForm
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MapForm));
            this.SuspendLayout();
            //
            // MapForm
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(506, 402);
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
            this.Name = "MapForm";
            this.Text = "MapForm";
            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MapForm_FormClosing);
            this.LocationChanged += new System.EventHandler(this.MapForm_LocationChanged);
            this.SizeChanged += new System.EventHandler(this.MapForm_SizeChanged);
            this.ResumeLayout(false);

        }

        #endregion

    }
}


text:
FOUNDATION_EXPORT double Pods_GCAppirater_TestsVersionNumber;
FOUNDATION_EXPORT const unsigned char Pods_GCAppirater_TestsVersionString[];


text:
package in.zaidi.engineering.auctions;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = BidResourceTest.class, value= "local.server.port=8888")
@WebAppConfiguration
public class BidResourceTest {

	@Test
	public void test() {
		//fail("Not yet implemented");
	}

}


text:
package org.ojai.tests.json;

import static org.junit.Assert.assertEquals;

import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.sql.Date;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.Test;
import org.ojai.Document;
import org.ojai.DocumentReader;
import org.ojai.DocumentReader.EventType;
import org.ojai.Value.Type;
import org.ojai.json.Json;
import org.ojai.util.Values;

public class TestJsonDocument {

  @Test
  public void testAllTypes() {
    Document rec = Json.newDocument();
    rec.set("map.field1", (byte) 100);
    rec.set("map.field2", (short) 10000);
    rec.set("map.longfield2verylongverylong", 12.345678);
    rec.set("FIELD2", "VERY LONG STRING IS THIS YOU KNOW");

    rec.set("map2.field1", (byte) 100);
    rec.set("map2.field2", (short) 10000);
    rec.set("map2.longfield2verylongverylong", 12.345678);
    rec.set("FIELD3", "VERY LONG STRING IS THIS YOU KNOW");
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("Name", "Anurag");
    map.put("Age", 20);
    rec.set("newmap.map", map);

    rec.set("map.boolean", false);
    rec.set("map.string", "string");
    rec.set("map.byte", (byte) 100);
    rec.set("map.short", (short) 10000);
    rec.set("map.int", 50000);
    rec.set("map.long", 12345678999L);
    rec.set("map.float", 10.1234f);
    rec.set("map.double", 10.12345678910d);
    // rec.set("map.interval", new Interval(1000, 2000));
    rec.set("map.decimal", new BigDecimal("1000000000.11111111111111111111"));
    byte[] bytes = new byte[5];
    for (int i = 0; i < bytes.length; ++i) {
      bytes[i] = (byte) i;
    }
    rec.set("map.binary1", bytes);
    rec.set("map.binary2", bytes, 1, 3);
    ByteBuffer bbuf = ByteBuffer.allocate(100);
    for (int i = 0; i < bbuf.capacity(); ++i) {
      bbuf.put((byte) i);
    }
    rec.set("map.binary3", bbuf);

    map = new HashMap<String, Object>();
    map.put("Name", "Anurag");
    map.put("Age", 20);
    List<Integer> scores = new ArrayList<Integer>();
    scores.add(100);
    scores.add(200);
    scores.add(300);
    scores.add(400);
    // map.put("Score", scores);
    rec.set("map.map", map);

    List<Object> values = new ArrayList<Object>();
    values.add("Field1");
    values.add(new Integer(500));
    values.add(new Double(5555.5555));
    rec.set("map.list", values);

    assertEquals(rec.getValue("map").getType(), Type.MAP);
    assertEquals(rec.getBoolean("map.boolean"), false);
    assertEquals(rec.getString("map.string"), "string");
    assertEquals(rec.getByte("map.byte"), (byte) 100);
    assertEquals(rec.getShort("map.short"), (short) 10000);
    assertEquals(rec.getInt("map.int"), 50000);
    assertEquals(rec.getLong("map.long"), 12345678999L);
    assertEquals(rec.getFloat("map.float"), (float) 10.1234, 0.0);
    assertEquals(rec.getDouble("map.double"), 10.12345678910d, 0.0);
    // assertEquals(rec.getInterval("map.interval"), new Interval(1000, 2000));
    assertEquals(rec.getDecimal("map.decimal"), new BigDecimal(
        "1000000000.11111111111111111111"));

    java.nio.ByteBuffer readBuf;
    readBuf = rec.getBinary("map.binary1");
    for (int i = 0; i < bytes.length; ++i) {
      assertEquals(readBuf.get(i), bytes[i]);
    }

    readBuf = rec.getBinary("map.binary2");
    for (int i = 0; i < 3; ++i) {
      assertEquals(readBuf.get(), bytes[1 + i]);
    }
    readBuf = rec.getBinary("map.binary3");
    assertEquals(readBuf, bbuf);

    try {
      List<Object> l = rec.getValue("map.list").getList();
      assertEquals(values, l);
    } catch (Exception e) {
      System.out.println("Exception from list test " + e.getMessage());
    }
  }

  @Test
  public void testAsReaderFull() {
    Document document = Json.newDocument();
    document.set("map.byte", (byte)127);
    document.set("map.long", 123456789);
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("first","John");
    map.put("first", "Doe");
    document.set("map.name", map);
    List<Object> mylist = new ArrayList<Object>();
    mylist.add(true);
    mylist.add("string");
    mylist.add(123.456);
    document.set("map.array", mylist);

    DocumentReader myReader = document.asReader();
    EventType et ;
    String fieldName = null;
    while ((et = myReader.next()) != null) {
      if (et == EventType.FIELD_NAME) {
        fieldName = myReader.getFieldName();
      }
      if ((et == EventType.BYTE) && (fieldName.equals("byte"))) {

        assertEquals((byte)127, myReader.getByte());
      }
      if ((et == EventType.STRING) && (fieldName.equals("array"))) {

        assertEquals("string", myReader.getString());
      }
    }
  }

  @Test
  public void testAsReaderPartial() {
    Document document = Json.newDocument();
    document.set("map.byte", (byte)127);
    document.set("map.num", 12345);
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("first","John");
    map.put("last", "Doe");
    map.put("id", (long)123456789);
    document.set("map.name", map);
    List<Object> mylist = new ArrayList<Object>();
    mylist.add(true);
    mylist.add("string");
    mylist.add(123.456);
    document.set("map.array", mylist);
    DocumentReader myReader = document.asReader("map.name");
    EventType event;
    String fieldName = null;
    while ((event = myReader.next()) != null) {
      if (event == EventType.FIELD_NAME) {
        fieldName = myReader.getFieldName();
      }

      if (event == EventType.LONG) {
        assertEquals("id", fieldName);
        assertEquals(123456789, myReader.getLong());
      }
    }
  }

  /*
   * Unit test for asReader created on a leaf node of DOM tree.
   */
  @Test
  public void testAsReaderLeaf() {
    Document document = Json.newDocument();
    document.set("map.byte", (byte)127);
    document.set("map.num", 12345);
    Map<String, Object> m = new HashMap<String, Object>();
    m.put("first", "John");
    m.put("last", "Doe");
    m.put("age", (short)45);
    document.set("map.info", m);
    DocumentReader myReader = document.asReader("map.info.age");
    EventType event;
    int numtokens = 0;
    while ((event = myReader.next()) != null) {
      if (event == EventType.SHORT) {
        numtokens++;
        assertEquals((short)45, myReader.getShort());
      }
    }
    assertEquals(1, numtokens);
  }

  @Test
  public void testGetMap() {
    Document document = Json.newDocument();
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("a", 1);
    map.put("b", "A");
    document.set("map", map);
    assertEquals(map, document.getMap("map"));
  }

  @Test
  public void testSetBooleanArray() {
    Document document = Json.newDocument();
    document.set("map.int", 111);
    boolean[] boolArray = new boolean[3];
    boolArray[0] = true;
    boolArray[1] = false;
    boolArray[2] = true;
    document.setArray("map.boolarray", boolArray);

    assertEquals(false, document.getBoolean("map.boolarray[1]"));
    assertEquals(true, document.getBoolean("map.boolarray[2]"));
  }

  @Test
  public void testDateWithLongMaxMin() {
    Document doc = Json.newDocument();
    Date d1 = new Date(Long.MAX_VALUE);
    Date d2 = new Date(Long.MIN_VALUE);
    doc.set("maxdate", d1);
    doc.set("boolean", false);
    doc.set("mindate", d2);

    System.out.println(d1.getTime());
    System.out.println(doc.getDate("maxdate").getTime());

    assertEquals(true, doc.getValue("maxdate").equals(d1));
    assertEquals(true, doc.getValue("mindate").equals(d2));
  }

  @Test
  public void testDate() {
    Document doc = Json.newDocument();
    doc.set("d1", Values.parseDate("2005-06-22"));
    Date d = new Date(new java.util.Date().getTime());
    doc.set("d2", d);
    System.out.println(doc.getDate("d1"));
    System.out.println(doc.getDate("d2"));

    assertEquals(true, doc.getDate("d1").toString().equals("2005-06-22"));
    assertEquals(true, doc.getDate("d2").toString().equals(d.toString()));
  }

}


text:
var url = params.url;
if (url.indexOf("https://") < 0) {
    url = 'https://' + url;
}
var username = params.username;
var password = params.password;
var proxy = params.proxy || false;
var COOKIE_PREFIX = 'RSA_SA_LICENSE=true; JSESSIONID=';

function FailedRequestError(message, url, query, reqBody, resBody) {
    return {
        message: message,
        url: url,
        query: query,
        reqBody: reqBody,
        resBody: resBody,
        toString: function() {
            var error = [
                message,
                'Request url: ' + url,
            ];

            if (query) {
                error.push('Request query: ' + JSON.stringify(query));
            }
            if (reqBody) {
                error.push('Request body:' + JSON.stringify(reqBody));
            }

            error.push('Response: ' + resBody);

            return error.join('\n');
        }
    };
}

function escapeRegExp(str) {
    return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}

function replaceAll(str, find, replace) {
    return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}

function login(url, username, password) {
    var fullUrl = url + '/j_spring_security_check';
    var res = http(
        fullUrl,
        {
            Method: 'POST',
            Headers: {
                'Origin': [url],
                'Content-Type': ['application/x-www-form-urlencoded'],
                'Referer': [url + '/login']
            },
            Body: 'j_username=' + username + '&j_password=' + password
        },
        true,
        proxy,
        true
    );

    if (res.StatusCode !== 302) {
        throw 'Failed to login with status [' + res.StatusCode + ']. Expected status 302. Check username or password. \nOriginal error: ' + res.Body;
    }

    var sessionId = null;
    res.Cookies.forEach(function(cookie) {
        if (cookie.Name === 'JSESSIONID') {
            sessionId = cookie.Value;
        }
    });

    try {
        getAvailableAssignees(sessionId);
    } catch(err) {
        throw 'Failed to login! Check username or password. Error: ' + err;
    }

    return sessionId;
}

function logout(url, sessionId) {
    var fullUrl = url + '/j_spring_security_logout';

    var res = http(
        fullUrl,
        {
            Method: 'GET',
            Headers: {
                'Origin': [url],
                'Content-Type': ['application/x-www-form-urlencoded'],
                'Cookie': [COOKIE_PREFIX + sessionId]
            }
        },
        true,
        proxy,
        true
    );

    if (res.StatusCode !== 302) {
        throw 'Failed to logout with status [' + res.StatusCode + ']. Expected status 302.\nOriginal error: ' + res.Body;
    }
}

function createQuery(args, defaultQuery) {
    args = args || {};
    defaultQuery = defaultQuery || {};
    var query = {};

    if (args.page || defaultQuery.page) {
        query.page = args.page || defaultQuery.page;
    }

    if (args.start || defaultQuery.start) {
        query.start = args.start || defaultQuery.start;
    }

    if (args.limit || defaultQuery.limit) {
        query.limit = args.limit || defaultQuery.limit;
    }

    if (args.sort || defaultQuery.sort) {
        query.sort = args.sort || defaultQuery.sort;
    }

    if (args.filter || defaultQuery.filter) {
        query.filter = args.filter || defaultQuery.filter;
    }

    return query;
}

function createQueryFromString(q) {
    if (!q.match(/(.*=.*&)*(.*=.*)/)) {
        throw 'invalid query. query must be of structure: key1=value1&key2=value2&keyN=valueN';
    }
    var query = replaceAll(q, '\"', '"')
        .split('&')
        .reduce(function(qArgs, nextArg) {
            var na = nextArg.split('=');
            var argKey = na[0];
            var argValue = na[1];
            qArgs[argKey] = argValue;
            return qArgs;
        }, {});

    return query;
}

var defaultIncidentFilter = {
    page: 1,
    start: 0,
    limit: 50,
    sort: JSON.stringify([
        {
            property:'created',
            direction: 'DESC'
        }
    ]),
    filter: JSON.stringify([
        {
            property: 'created',
            value: [
                851171984031, // year 1996
                new Date().getTime()
            ]
        }
    ])
};

function listIncidents(sessionId, args, incidentManagementId) {
    var fullUrl = url + '/ajax/incidents/' + incidentManagementId;
    var query = {};
    if (args.query) {
        query = createQueryFromString(args.query);
    } else {
        query = createQuery(args, defaultIncidentFilter);
    }

    fullUrl += encodeToURLQuery(query);

    var res = http(
        fullUrl,
        {
            Method: 'GET',
            Headers: {
                'Cookie': [COOKIE_PREFIX + sessionId]
            }
        },
        true,
        proxy
    );

    if (res.StatusCode < 200 || res.StatusCode >= 300) {
        throw 'Failed to fetch incidents with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body;
    }

    try {
        incidentsRes = JSON.parse(res.Body);
        if (incidentsRes.success) {
            var incidents = incidentsRes.data;
            if (!args.loadAlerts) {
                return incidents;
            }

            // loading all the alerts which related to incident
            // we load the alerts and original alerts which contains the original events which the alert created from
            // this has performance impact
            for (var i = 0; i < incidents.length; i++) {
                var alerts = filterAlerts(sessionId, {
                    filter: JSON.stringify([
                        {
                            property: 'incidentId',
                            value: incidents[i].id
                        }
                    ])
                })
                incidents[i].alerts = [];
                alerts.forEach(function(alert) {
                    var originalAlert = getOriginalAlertById(sessionId, { alertId: alert.id });
                    incidents[i].alerts.push({
                        alert: alert,
                        orignalAlert: originalAlert
                    });
                });
            }

            return incidents;
        } else {
            throw FailedRequestError('Fetch incidents failed.', fullUrl, query, null, incidentsRes).toString();
        }
    } catch (err) {
        throw FailedRequestError('Unexpected error while fetching incidents. \nOriginal error: ' + err, fullUrl, query, null, res.Body).toString();
    }
}

function fetchIncidents(sessionId, args, incidentManagementId) {
    var now = new Date().getTime();
    var lastRun = getLastRun().lastRun || now - 1*60*1000; // last minute
    var lastRunNext = lastRun;

    var tillNow = now;
    var query = {
        loadAlerts: true,
        page: 1,
        start: 0,
        limit: 50,
        filter: JSON.stringify([{
            property: 'created',
            value: [
                lastRun,
                tillNow
            ]
        }])
    };

    // TODO handle paging. If number of incidents are more than 50, then we need to
    // fetch the next pages too.
    var lastIncidents = listIncidents(sessionId, query, incidentManagementId);
    var convertedIncidents = [];
    for (var i = 0; i < lastIncidents.length; i++) {
        var inc = lastIncidents[i];
        if (inc.created > lastRunNext) {
            // we get the last incident which created
            lastRunNext = inc.created + 1;
        }

        convertedIncidents.push({
            name: inc.id,
            occurred: new Date(inc.firstAlertTime),
            owner: inc.assignee ? inc.assignee.login : '',
            reason: inc.name,
            rawJSON: JSON.stringify(inc)
        });
    }

    setLastRun({ lastRun: lastRunNext });
    return JSON.stringify(convertedIncidents);
}

function getIncidentById(sessionId, args, incidentManagementId) {
    var fullUrl = [
        url,
        'ajax/incident',
        incidentManagementId,
        args.incidentId
    ].join('/');

    var res = http(
        fullUrl,
        {
            Method: 'GET',
            Headers: {
                'Cookie': [COOKIE_PREFIX + sessionId]
            }
        },
        true,
        proxy
    );

    if (res.StatusCode < 200 || res.StatusCode >= 300) {
        throw 'Failed to get incident by id with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body;
    }

    try {
        incident = JSON.parse(res.Body);
        if (incident.success) {
            return incident.data;
        } else {
            throw FailedRequestError('Fetch incident by id failed.', fullUrl, null, null, incident).toString();
        }
    } catch (err) {
        throw FailedRequestError('Unexpected error while fetching incident by id. \nOriginal error: ' + err, fullUrl, null, null, res.Body).toString();
    }
}

var defaultComponentFilter = {
    page: 1,
    start: 0,
    limit: 1000,
    sort: replaceAll(JSON.stringify([
        {
            property: 'displayName',
            direction: 'ASC'
        }
    ]), '\"', '"')
};

function getComponents(sessionId, argz, types) {
    var fullUrl = url + '/common/devices';
    var query = {};
    if (argz.query) {
        query = createQueryFromString(argz.query);
    } else {
        query = createQuery(argz, defaultComponentFilter);
    }
    fullUrl += types ? '/types/' + types.join('/') : '';
    fullUrl += encodeToURLQuery(query);

    var res = http(
        fullUrl,
        {
            Method: 'GET',
            Headers: {
                'Cookie': [COOKIE_PREFIX + sessionId]
            }
        },
        true,
        proxy
    );

    if (res.StatusCode < 200 || res.StatusCode >= 300) {
        throw 'Failed to fetch components with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body;
    }

    try {
        components = JSON.parse(res.Body);
        if (components.success) {
            return components.data;
        } else {
            throw FailedRequestError('Fetch components failed.', fullUrl, query, null, components).toString();
        }
    } catch (err) {
        throw FailedRequestError('Unexpected error when fetching components. \nOriginal error: ' + err, fullUrl, query, null, res.Body).toString();
    }
}

function getIncidentManagementId(sessionId) {
    var incidentManagement = getComponents(sessionId, {}, ['INCIDENT_MANAGEMENT']);

    if (!incidentManagement || incidentManagement.length === 0) {
        throw 'Failed to find RSA NetWitness INCIDENT_MANAGEMENT component/device: ' + JSON.stringify(incidentManagement);
    }

    return incidentManagement[0].id;
}

function createEventsQuery(args, predicateIds) {
    args = args || {};
    var query = {};

    query.deviceId = args.deviceId;
    query.collectionName = args.collectionName || '';
    query.predicateIds = predicateIds ? predicateIds.join(',') : '';
    query.timeRangeType = args.timeRangeType;
    query.startDate = args.startDate || '';
    query.endDate = args.endDate || '';
    query.lastCollectionTime = args.lastCollectionTime || '';
    query.mid1 = args.mid1 || 0;
    query.mid2 = args.mid2 || 0;
    query.investigationToken = args.investigationToken || '';
    query.page = args.page || 1;
    query.start = args.start || 0;
    query.limit = args.limit || 25;
    query.sort = args.sort
        ? replaceAll(args.sort, '\"', '"')
        : JSON.stringify([
            {
                property: 'id',
                direction: 'ASC'
            }
        ]);

    return query;
}
function getEvents(sessionId, args) {
    var predicateIds = [];
    if (args.filter) {
        var eventsViewHTML = getEventsViewHtml(sessionId);
        var csrfToken = extractCsrfTokenFromHTML(eventsViewHTML);
        var filters = args.filter.split(',');
        for (var i = 0; i < filters.length; i++) {
            var predicate = postEventsTransient(sessionId, filters[i], csrfToken);
            predicateIds.push(predicate);
        }
    }
    var query = createEventsQuery(args, predicateIds);
    var fullUrl = url + '/ajax/investigation/events' + encodeToURLQuery(query);

    var res = http(
        fullUrl,
        {
            Method: 'GET',
            Headers: {
                'Cookie': [COOKIE_PREFIX + sessionId]
            }
        },
        true,
        proxy
    );

    if (res.StatusCode < 200 || res.StatusCode >= 300) {
        throw 'Failed to fetch events with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body;
    }

    try {
        events = JSON.parse(res.Body);
        if (events.success) {
            return events.data;
        } else {
            throw FailedRequestError('Fetch events failed.', fullUrl, query, null, events).toString();
        }
    } catch (err) {
        throw FailedRequestError('Unexpected while fetching events. \nOriginal error: ' + err, fullUrl, query, null, res.Body).toString();
    }
}
function postEventsTransient(sessionId, query, ctoken) {
    var fullUrl = url + '/predicates/transient';
    var body = {
        name: query,
        query: query,
        ctoken: ctoken
    };
    var res = http(
        fullUrl,
        {
            Method: 'POST',
            Headers: {
                'Cookie': [COOKIE_PREFIX + sessionId],
                'Content-Type': ['application/x-www-form-urlencoded']
            },
            Body: encodeToURLQuery(body).replace(/^\?/, '')
        },
        true,
        proxy
    );

    if (res.StatusCode < 200 || res.StatusCode >= 300) {
        throw 'Failed to fetch events with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body;
    }

    try {
        transient = JSON.parse(res.Body);
        if (transient.success) {
            return transient.object;
        } else {
            throw FailedRequestError('Posting transient for events failed.', fullUrl, null, body, transient).toString();
        }
    } catch (err) {
        throw FailedRequestError('Unexpected while posting transient for events. \nOriginal error: ' + err, fullUrl, null, body, res.Body).toString();
    }
}

function getEventDetails(sessionId, args) {
    var fullUrl = url + '/investigation/reconstruct/event';
    var eventsViewHTML = getEventsViewHtml(sessionId);
    var csrfToken = extractCsrfTokenFromHTML(eventsViewHTML);

    var body = {
        deviceId: args.deviceId,
        collectionName: args.collectionName || '',
        eventId: args.eventId,
        contentType: 'AUTO',
        contentSide: 'REQUEST_AND_RESPONSE',
        contentLayout: 'TOP_TO_BOTTOM',
        packetOverride: -1,
        ctoken: csrfToken
    };
    var res = http(
        fullUrl,
        {
            Method: 'POST',
            Headers: {
                'Cookie': [COOKIE_PREFIX + sessionId],
                'Content-Type': ['application/x-www-form-urlencoded']
            },
            Body: encodeToURLQuery(body).replace(/^\?/, '')
        },
        true,
        proxy
    );

    if (res.StatusCode < 200 || res.StatusCode >= 300) {
        throw 'Failed to fetch event with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body;
    }

    try {
        event = JSON.parse(res.Body);
        if (event.success) {
            var content = getEventContent(sessionId, event.data.uri);
            return {data: event.data, content: content};
        } else {
            throw FailedRequestError('Fetching event details', fullUrl, null, body, event).toString();
        }
    } catch (err) {
        throw FailedRequestError('Unexpected while fetching event details. \nOriginal error: ' + err, fullUrl, null, body, res.Body).toString();
    }
}

// Returns events/session data content.
function getEventContent(sessionId, urlSuffix) {
    var fullUrl = url + urlSuffix;
    var res = http(
        fullUrl,
        {
            Method: 'GET',
            Headers: {
                'Cookie': [COOKIE_PREFIX + sessionId]
            }
        },
        true,
        proxy
    );

    if (res.StatusCode < 200 || res.StatusCode >= 300) {
        throw 'Failed to fetch event data (recontruction) with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body;
    }

    try {
        return res.Body;
    } catch (err) {
        throw FailedRequestError('Unexpected while fetching event data (recontruction). \nOriginal error: ' + err, fullUrl, query, null, res.Body).toString();
    }
}

var defaultAlertQuery = {
    page: 1,
    start: 0,
    limit: 100,
    sort: JSON.stringify([
        {
            property:'alert.timestamp',
            direction: 'DESC'
        }
    ]),
    filter: JSON.stringify([
        {
            property: 'alert.timestamp',
            value: [
                851171984031, // year 1996
                new Date().getTime()
            ]
        }
    ])
};
function filterAlerts(sessionId, args) {
    var query = createQuery(args, defaultAlertQuery);
    var fullUrl = [
        url,
        '/ajax/alerts/',
        incidentManagementId,
        encodeToURLQuery(query)
    ].join('');

    var res = http(
        fullUrl,
        {
            Method: 'GET',
            Headers: {
                'Cookie': [COOKIE_PREFIX + sessionId]
            }
        },
        true,
        proxy
    );

    if (res.StatusCode < 200 || res.StatusCode >= 300) {
        throw 'Failed to fetch alerts with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body;
    }

    try {
        alerts = JSON.parse(res.Body);
        if (alerts.success) {
            return alerts.data;
        } else {
            throw FailedRequestError('Fetch alerts failed.', fullUrl, query, null, alerts).toString();
        }
    } catch (err) {
        throw FailedRequestError('Unexpected while fetching alerts. Original error:' + err, fullUrl, query, null, res.Body).toString();
    }
}

function getAlertById(sessionId, args) {
    var fullUrl = [
        url,
        'ajax/alerts',
        incidentManagementId,
        args.alertId
    ].join('/');

    var res = http(
        fullUrl,
        {
            Method: 'GET',
            Headers: {
                'Cookie': [COOKIE_PREFIX + sessionId]
            }
        },
        true,
        proxy
    );

    if (res.StatusCode < 200 || res.StatusCode >= 300) {
        throw 'Failed to get events of alert with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body;
    }

    try {
        alert = JSON.parse(res.Body);
        if (alert.success) {
            return alert.data;
        } else {
            throw FailedRequestError('Fetch alert details failed.', fullUrl, query, null, alert).toString();
        }
    } catch (err) {
        throw FailedRequestError('Unexpected while fetching alert details. \nOriginal error: ' + err, fullUrl, null, null, res.Body).toString();
    }
}

function getOriginalAlertById(sessionId, args) {
    var fullUrl = [
        url,
        'ajax/alerts/originalalert',
        incidentManagementId,
        args.alertId
    ].join('/');

    var res = http(
        fullUrl,
        {
            Method: 'GET',
            Headers: {
                'Cookie': [COOKIE_PREFIX + sessionId]
            }
        },
        true,
        proxy
    );

    if (res.StatusCode < 200 || res.StatusCode >= 300) {
        throw 'Failed to get events of alert with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body;
    }

    try {
        alert = JSON.parse(res.Body);
        if (alert.success) {
            return alert.data;
        } else {
            throw FailedRequestError('Fetch alert details failed.', fullUrl, query, null, alert).toString();
        }
    } catch (err) {
        throw FailedRequestError('Unexpected while fetching alert details. \nOriginal error: ' + err, fullUrl, null, null, res.Body).toString();
    }
}

function getAvailableAssignees(sessionId) {
    var fullUrl = url + '/ajax/incident/user/availableAssignees';

    var res = http(
        fullUrl,
        {
            Method: 'GET',
            Headers: {
                'Cookie': ['RSA_SA_LICENSE=true; SaneID=10.64.49.14-1456516139492605; s_pers=%20s_fid%3D0D47AAAFD2A1592B-3436DC4A7A7EB300%7C1531522908438%3B%20gpv_pn%3DMYTOOLSSTATIC%252FTOOLS%252FTHE%2520SQUARE%7C1468452708438%3B%20s_lv%3D1468450908454%7C1563058908454%3B%20s_lv_s%3DLess%2520than%25201%2520day%7C1468452708454%3B; s_vi=[CS]v1|2B6795DE050118E9-40001608C00050FA[CE]; s_fid=3D8DF632622AC544-1283F8DF4BA4E8DC; JSESSIONID=' + sessionId]
            }
        },
        true,
        proxy
    );

    if (res.StatusCode < 200 || res.StatusCode >= 300) {
        throw 'Failed to fetch availabe assignees with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body;
    }

    try {
        availableAssignees = JSON.parse(res.Body);
        if (availableAssignees.success) {
            return availableAssignees.data;
        } else {
            throw FailedRequestError('Fetch available assignees failed.', fullUrl, null, null, availableAssignees).toString();
        }
    } catch (err) {
        throw FailedRequestError('Unexpected error while fetching available assignees. \nOriginal error: ' + err, fullUrl, null, null, res.Body).toString();
    }
}

function getEventsViewHtml(sessionId) {
    var fullUrl = url + '/investigation/events';

    var res = http(
        fullUrl,
        {
            Method: 'GET',
            Headers: {
                'Cookie': [COOKIE_PREFIX + sessionId]
            }
        },
        true,
        proxy
    );

    if (res.StatusCode < 200 || res.StatusCode >= 300) {
        throw 'Failed to fetch CSRF token with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body;
    }

    return res.Body;
}

function extractCsrfTokenFromHTML(html) {
    var matched = html.match(/<meta name="csrf-token" content=".*"/);
    if (!matched) {
        throw 'CSRF token not found! Internal error in NetWitness. Response  body: \n' + html;
    }

    var csrfToken = replaceAll(matched[0].replace('<meta name="csrf-token" content=', ''), '"', '');
    return csrfToken;
}

function extractLoggedUserFromHTML(html) {
    var matchedLoggedUser = html.match(/name: Ext\.htmlDecode\(.*\)/);
    if (!matchedLoggedUser) {
        throw 'Failed to determine logged in user. Html: ' + html;
    }

    var name = matchedLoggedUser[0].replace('name: Ext.htmlDecode(\'', '').replace('\')', '');
    var user = {
        name: name
    };

    return user;
}

var DEFAULT_SEVERITY = "50";
function createAlert(sessionId, args, incidentManagementId, createdUser, csrfToken) {
    var eventListString = replaceAll(args.eventList, ' ', '');
    var fullUrl = [
        url,
        'ajax/alert/create',
        args.deviceId,
        eventListString,
        incidentManagementId + '',
        '?ctoken=' + csrfToken
    ].join('/');

    var body = {
        alertSummary: args.alertSummary,
        event_id_list: eventListString.split(','),
        severity: args.severity ? args.severity + '' : DEFAULT_SEVERITY,
        create_by_user: createdUser.name
    };

    var res = http(
        fullUrl,
        {
            Method: 'POST',
            Headers: {
                'Cookie': [COOKIE_PREFIX + sessionId],
                'Content-Type': ['application/json']
            },
            Body: JSON.stringify(body)
        },
        true,
        proxy
    );

    if (res.StatusCode < 200 || res.StatusCode >= 300) {
        throw 'Failed to create new alert with status [' + res.StatusCode + ']. \nOriginal error: ' + res.Body;
    }

    try {
        var alertRes = JSON.parse(res.Body);
        if (alertRes.success) {
            return alertRes.data;
        } else {
            throw FailedRequestError('Failed to create alert.', fullUrl, null, body, alertRes).toString();
        }
    } catch (err) {
        throw FailedRequestError('Unexpected error while creating alert. \nOriginal error: ' + err, fullUrl, null, body, res.Body).toString();
    }
}

function createIncident(sessionId, args, incidentManagementId, availableAssignees) {
    var eventsViewHTML = getEventsViewHtml(sessionId);
    var csrfToken = extractCsrfTokenFromHTML(eventsViewHTML);
    var loggedUser = extractLoggedUserFromHTML(eventsViewHTML);
    // currently we extract only the name of the logged in user. But the all the user object is exist in the html.
    // it just will take more development time.
    // that is why we look for the user in availableAssigness
    availableAssignees.forEach(function(user) {
        if (user.name === loggedUser.name) {
            loggedUser = user;
        }
    });

    var newAlert = createAlert(sessionId, args, incidentManagementId, loggedUser, csrfToken);

    var fullUrl = [
        url,
        'ajax/incident/create',
        incidentManagementId + '',
        '?ctoken=' + csrfToken
    ].join('/');

    var newIncident = {
        name: args.name,
        summary: args.summary || '',
        priority: args.priority,
        createdBy: loggedUser.name,
        alert_id_list: [
            newAlert.id
        ]
    };

    var res = http(
        fullUrl,
        {
            Method: 'POST',
            Headers: {
                'Cookie': [COOKIE_PREFIX + sessionId],
                'Content-Type': ['application/json']
            },
            Body: JSON.stringify(newIncident)
        },
        true,
        proxy
    );

    if (res.StatusCode < 200 || res.StatusCode >= 300) {
        throw 'Failed to create incident with status [' + res.StatusCode + ']\n.'
            + 'Request Body: ' + JSON.stringify(body) + '\n. Response Body: ' + res.Body;
    }

    try {
        var newIncidentRes = JSON.parse(res.Body);
        if (newIncidentRes.success) {
            newIncident.id = newIncidentRes.data.id;
            return newIncident;
        } else {
            throw FailedRequestError('Failed to create incident.', fullUrl, null, body, newIncidentRes).toString();
        }
    } catch (err) {
        throw FailedRequestError('Unexpected error while creating incident. \nOriginal error: ' + err, fullUrl, null, body, res.Body).toString();
    }
}

function addEventsToIncident(sessionId, args, incidentManagementId, availableAssignees) {
    var eventsViewHTML = getEventsViewHtml(sessionId);
    var csrfToken = extractCsrfTokenFromHTML(eventsViewHTML);
    var loggedUser = extractLoggedUserFromHTML(eventsViewHTML);
    // currently we extract only the name of the logged in user. But the all the user object is exist in the html.
    // it just will take more development time.
    // that is why we look for the user in availableAssigness
    availableAssignees.forEach(function(user) {
        if (user.name === loggedUser.name) {
            loggedUser = user;
        }
    });

    var newAlert = createAlert(sessionId, args, incidentManagementId, loggedUser, csrfToken);

    var fullUrl = [
        url,
        'ajax/incident/addToIncident',
        incidentManagementId + '',
        '?ctoken=' + csrfToken
    ].join('/');

    var reqBody = {
        alertIds: [
            newAlert.id
        ],
        incidentId: args.incidentId
    };

    var res = http(
        fullUrl,
        {
            Method: 'POST',
            Headers: {
                'Cookie': [COOKIE_PREFIX + sessionId],
                'Content-Type': ['application/json']
            },
            Body: JSON.stringify(reqBody)
        },
        true,
        proxy
    );

    if (res.StatusCode < 200 || res.StatusCode >= 300) {
        throw 'Failed to add events to incident with status [' + res.StatusCode + ']\n.'
            + 'Request Body: ' + JSON.stringify(body) + '\n. Response Body: ' + res.Body;
    }

    try {
        var resObject = JSON.parse(res.Body);
        if (resObject.success) {
            return true;
        } else {
            throw FailedRequestError('Failed to add events to incident.', fullUrl, null, body, newIncidentRes).toString();
        }
    } catch (err) {
        throw FailedRequestError('Unexpected error while adding new events to incident. \nOriginal error: ' + err, fullUrl, null, body, res.Body).toString();
    }
}

function updateIncident(sessionId, args, incidentManagementId, availableAssignees) {
    var eventsViewHTML = getEventsViewHtml(sessionId);
    var csrfToken = extractCsrfTokenFromHTML(eventsViewHTML);
    var loggedUser = extractLoggedUserFromHTML(eventsViewHTML);
    // currently we extract only the name of the logged in user. But the all the user object is exist in the html.
    // it just will take more development time.
    // that is why we look for the user in availableAssigness
    availableAssignees.forEach(function(user) {
        if (user.name === loggedUser.name) {
            loggedUser = user;
        }
    });

    var fullUrl = [
        url,
        'ajax/incidents/update',
        incidentManagementId + '',
        '?ctoken=' + csrfToken
    ].join('/');

    var updatedIncident = {
        id_list: replaceAll(args.idList, ' ', '').split(','),
        attribute_map: {
            lastUpdatedByUser: loggedUser
        },
        benign_domain_list: []
    };
    if (args.name) {
        updatedIncident.attribute_map.name = args.name;
    }
    if (args.priority) {
        updatedIncident.attribute_map.priority = args.priority;
    }
    if (args.status) {
        updatedIncident.attribute_map.status = args.status;
    }
    if (args.summary) {
        updatedIncident.attribute_map.summary = args.summary;
    }
    if (args.comment) {
        updatedIncident.attribute_map.comment = args.comment;
    }
    if (args.assignee) {
        var assigneeUser = null;
        availableAssignees.forEach(function(user) {
            if (user.login === args.assignee) {
                assigneeUser = user;
            }
        });
        if (!assigneeUser) {
            throw 'assignee argument is invalid. No such [' + args.assignee + '] available assignee user exist';
        }
        updatedIncident.attribute_map.assignee = assigneeUser;
    }
    if (args.categories) {
        updatedIncident.attribute_map.categories = args.categories;
    }

    var res = http(
        fullUrl,
        {
            Method: 'POST',
            Headers: {
                'Cookie': [COOKIE_PREFIX + sessionId],
                'Content-Type': ['application/json']
            },
            Body: JSON.stringify(updatedIncident)
        },
        true,
        proxy
    );

    if (res.StatusCode < 200 || res.StatusCode >= 300) {
        throw 'Failed to create incident with status [' + res.StatusCode + ']\n.'
            + 'Request Body: ' + JSON.stringify(updatedIncident) + '\n. Response Body: ' + res.Body;
    }

    try {
        var updateRes = JSON.parse(res.Body);
        if (updateRes.success) {
            return updateRes;
        } else {
            throw FailedRequestError('Failed to update incident.', fullUrl, null, updatedIncident, updateRes).toString();
        }
    } catch (err) {
        throw FailedRequestError('Failed to update incident.', fullUrl, null, updatedIncident, res.Body).toString();
    }
}

function makeUpperCase (o) {
    for (var key in o ) {
        if(o.hasOwnProperty(key)) {
            var newKey = key.charAt(0).toUpperCase() + key.slice(1);
            o[newKey] = o[key];
            delete o[key];
        }
    }
    return o;
}

function getIncidentObject(e) {
    return {
        "Id": e.id,
        "Name": e.name,
        "Status": e.status,
        "Priority": e.priority,
        "Summary": e.summary,
        "Assignee": e.assignee ? e.assignee.name : "",
        "CreatedBy": e.createdBy,
        "Created": convertTimestampToString(e.created),
        "FirstAlertTime": convertTimestampToString(e.firstAlertTime),
        "LastUpdatedByUserName": e.lastUpdatedByUserName,
        "RiskScore": e.riskScore,
        "AverageAlertRiskScore": e.averageAlertRiskScore,
        "Categories": e.categories,
        "AlertCount": e.alertCount
    };
}

function getAlert (alert) {
    return {
        "Id": alert.id,
        "Name": alert.name,
        "IncidentId": alert.incidentId,
        "Timestamp": convertTimestampToString(alert.timestamp),
        "HostSummary": alert.host_summary,
        "SignatureId": alert.signature_id,
        "Source": alert.source,
        "Type": alert.type,
        "RiskScore": alert.risk_score,
        "SourceCountry": alert.groupby_source_country,
        "DestinationCountry": alert.groupby_destination_country,
        "NumEvents": alert.numEvents,
        "SourceIp": alert.groupby_source_ip,
        "DestonationIp": alert.groupby_destination_ip,
        "DestonationPort": alert.groupby_destination_port
    };
}
function buildRetValListIncidents (incidets) {
    var md = [];
    var ctx = {"Netwitness.Incident":[]}
    if (!Array.isArray(incidets)) {
        incidets = [incidets]
    }
    incidets.forEach(function (e) {
        var toPush = getIncidentObject(e);
        md.push(toPush);
        ctx["Netwitness.Incident"].push(toPush);
    })
    return {Type: entryTypes.note, Contents: incidets, ContentsFormat: formats.json, HumanReadable: tableToMarkdown(command, md), ReadableContentsFormat: formats.markdown, EntryContext: ctx};
}

function buildRetValGetIncidentDetails (incident) {
    var md = [];
    var ctx = {"Netwitness.Incident":[]}
    var toPush = getIncidentObject(incident);
    md.push(toPush);
    ctx["Netwitness.Incident"].push(toPush);
    return {Type: entryTypes.note, Contents: incident, ContentsFormat: formats.json, HumanReadable: tableToMarkdown(command, md), ReadableContentsFormat: formats.markdown, EntryContext: ctx};
}

function buildRetValGetComponents (components) {
    var md = [];
    var ctx = {"Netwitness.Component":[]}
    if (!Array.isArray(components)) {
        components = [components]
    }
    components.forEach(function (e) {
        var toPush = {
            "Id": e.id,
            "DisplayName": e.displayName,
            "DeviceVersion": e.deviceVersion,
            "DisplayType": e.deviceType,
            "Host": e.host,
            "Port": e.port,
            "Validated": e.validated,
            "Licensed": e.licensed,
            "Username": e.username,
            "EnableSSL": e.enableSSL
        };
        md.push(toPush)
        ctx["Netwitness.Component"].push(toPush);
    })
    return {Type: entryTypes.note, Contents: components, ContentsFormat: formats.json, HumanReadable: tableToMarkdown(command, md), ReadableContentsFormat: formats.markdown, EntryContext:  ctx};
}

function buildRetValGetEvents (events) {
    var md = [];
    var ctx = {"Netwitness.Event":[]}
    if (!Array.isArray(events)) {
        events = [events]
    }
    events.forEach(function (event) {
        var toPush = {
            "Id": event.id,
            "Medium": event.medium,
            "Service": event.service,
            "Size": event.size
        }
        event["meta"].forEach(function (meta) {
            toPush["meta." + meta.name] = meta.value
        });
        md.push(toPush);
    });
    return {Type: entryTypes.note, Contents: events, ContentsFormat: formats.json, HumanReadable: tableToMarkdown(command, md), ReadableContentsFormat: formats.markdown};
}

function buildRetValGetEventDetails (event) {
    var md = [];
    var ctx = {"Netwitness.Event":[]};
    var data = event.data;
    var content = event.content;
    var toPush = {
        "EventId": data.eventId,
        "DeviceId": data.deviceId,
        "ReconstructedContentType": data.reconstructedContentType,
        "PacketsTotal": data.stats ? data.stats.packetsTotal : "",
        "PacketsProcessed": data.stats ? data.stats.packetsProcessed : ""
    };
    data.summaryAttributes.forEach(function (e) {
        toPush[e.name] = e.value
    });
    md.push(toPush);
    ctx["Netwitness.Event"].push(toPush);
    return {Type: entryTypes.note, Contents: event, ContentsFormat: formats.json, HumanReadable: tableToMarkdown(command, md), ReadableContentsFormat: formats.markdown, EntryContext:  ctx};
}

function buildRetValGetAlerts (alerts) {
    var md = [];
    var ctx = {"Netwitness.Alert":[]}
    if (!Array.isArray(alerts)) {
        alerts = [alerts]
    }
    alerts.forEach(function (e) {
        var toPush = getAlert(e);
        md.push(toPush);
        ctx["Netwitness.Alert"].push(toPush);
    })
    return {Type: entryTypes.note, Contents: alerts, ContentsFormat: formats.json, HumanReadable: tableToMarkdown(command, md), ReadableContentsFormat: formats.markdown, EntryContext: ctx};
}

function buildRetValGetAlert (alert) {
    var ctx = {"Netwitness.Alert":[]}
    var alertValue = getAlert(alert);
    var eventValue = [];
    alert.events.forEach(function (evnt) {
        eventValue.push(treeToFlattenObject(evnt));
    });
    var relatedLinksValue = alert.related_links;
    var hr = tableToMarkdown('Alerts',alertValue)  + tableToMarkdown('Events', eventValue)  + tableToMarkdown('Related Links', relatedLinksValue);
    ctx["Netwitness.Alert"].push(alertValue);
    return {Type: entryTypes.note, Contents: alert, ContentsFormat: formats.json, HumanReadable: hr, ReadableContentsFormat: formats.markdown, EntryContext: ctx};
}

function buildRetValGetAlertOrig (alertOrig) {
    var md = [];
    var ctx = {"Netwitness.Event": []}
    if(!alertOrig.events) {
        return {"ContentsFormat": formats["markdown"], "Type": entryTypes["error"], "Contents": "Received an error from NetWitness Please ensure that the referred alert Id exist in NetWitness"};
    }
    alertOrig.events.forEach(function (evnt) {
        for (var key in evnt) {
            if (key === 'time') {
                evnt[key] = convertTimestampToString(evnt[key]);
            }
        }
    });
    md = alertOrig.events;
    ctx["Netwitness.Event"] = alertOrig.events;
    return {Type: entryTypes.note, Contents: alertOrig, ContentsFormat: formats.json, HumanReadable: tableToMarkdown(command, md), ReadableContentsFormat: formats.markdown, EntryContext: ctx};
}

function buildRetValAvailableAssignees(availableAssignees) {
    var md = [];
    var ctx = {"Netwitness.Account":[]}
    if (!Array.isArray(availableAssignees)) {
        availableAssignees = [availableAssignees]
    }
    availableAssignees.forEach(function (e) {
        var toPush ={
            "Id": e.id,
            "Name": e.name,
            "Login": e.login,
            "EmailAddress": e.emailAddress
        };
        md.push(toPush);
        ctx["Netwitness.Account"].push(toPush);
    })
    return {Type: entryTypes.note, Contents: availableAssignees, ContentsFormat: formats.json, HumanReadable: tableToMarkdown(command, md), ReadableContentsFormat: formats.markdown, EntryContext:  ctx};
}

function buildRetValCreateIncident (newIncident) {
    var md = [];
    var ctx = {"Netwitness.Incident":[]}
    var toPush = {
        "Id": newIncident.id,
        "Name": newIncident.name,
        "Priority": newIncident.priority,
        "CreatedBy": newIncident.createdBy,
        "AlertIDList": newIncident.alertIdList
    };
    md.push(toPush);
    ctx["Netwitness.Incident"].push(toPush)
    results = {Type: entryTypes.note, Contents: newIncident, ContentsFormat: formats.json, HumanReadable: tableToMarkdown(command, md), ReadableContentsFormat: formats.markdown, EntryContext:  ctx};
}

// The command input arg holds the command sent from the user.
var sessionId = login(url, username, password);
var incidentManagementId = args.incidentManagementId || getIncidentManagementId(sessionId);
var results = false;
switch (command) {
    case 'fetch-incidents':
        results = fetchIncidents(sessionId, args, incidentManagementId);
        break;
    case 'test-module':
        results = 'ok';
        break;
    case 'nw-login':
        results = sessionId;
        break;
    case 'netwitness-im-list-incidents':
        var incidents = listIncidents(sessionId, args, incidentManagementId);
        results = buildRetValListIncidents(incidents);
        break;
    case 'netwitness-im-get-incident-details':
        var incident = getIncidentById(sessionId, args, incidentManagementId);
        results = buildRetValGetIncidentDetails(incident);
        break;
    case 'netwitness-im-get-components':
        var components = getComponents(sessionId, args);
        results = buildRetValGetComponents(components);
        break;
    case 'netwitness-im-get-events':
        var events = getEvents(sessionId, args);
        results = buildRetValGetEvents(events);
        break;
    case 'netwitness-im-get-event-details':
        event = getEventDetails(sessionId, args);
        results = buildRetValGetEventDetails(event);
        break;
    case 'netwitness-im-get-alerts':
        var alerts = filterAlerts(sessionId, args);
        results = buildRetValGetAlerts(alerts);
        break;
    case 'netwitness-im-get-alert-details':
        var alert = getAlertById(sessionId, args);
        results = buildRetValGetAlert(alert);
        break;
    case 'netwitness-im-get-alert-original':
        var alert = getOriginalAlertById(sessionId, args);
        results = buildRetValGetAlertOrig(alert);
        break;
    case 'netwitness-im-get-available-assignees':
        var availableAssignees = getAvailableAssignees(sessionId);
        results = buildRetValAvailableAssignees(availableAssignees);
        break;
    case 'netwitness-im-create-incident':
        var availableAssignees = getAvailableAssignees(sessionId);
        var newIncident = createIncident(sessionId, args, incidentManagementId, availableAssignees);
        results = buildRetValCreateIncident(newIncident);
        break;
    case 'netwitness-im-add-events-to-incident':
        var md = [];
        var availableAssignees = getAvailableAssignees(sessionId, args);
        var isSuccess = addEventsToIncident(sessionId, args, incidentManagementId, availableAssignees);
        md.push({ success: isSuccess })
        results = {Type: entryTypes.note, Contents: { success: isSuccess }, ContentsFormat: formats.json, HumanReadable: tableToMarkdown(command, md), ReadableContentsFormat: formats.markdown};
        break;
    case 'netwitness-im-update-incident':
        var availableAssignees = getAvailableAssignees(sessionId, args);
        var update_incident = updateIncident(sessionId, args, incidentManagementId, availableAssignees);
        if( update_incident.success != true) {
            results = {"ContentsFormat": formats["markdown"], "Type": entryTypes["error"], "Contents": "Didn't succed to update incident.\n" + tableToMarkdown("Data returned:", update_incident)};
        }
        else if (update_incident.success == true && update_incident.data < 1) {
            results = {"ContentsFormat": formats["markdown"], "Type": entryTypes["error"], "Contents": "Received an error from NetWitness Please ensure that the referred incidents exist in NetWitness.  Incidents count = " + update_incident.data};
        }
        else {
            results = {
                "ContentsFormat": formats["text"],
                "Type": entryTypes["note"],
                "Contents": "Incident updated successfully."
            };
        }
        break;
    default:
        // You can use args[argName] or args.argName to get a specific arg. args are strings.
        // You can use params[paramName] or params.paramName to get a specific params.
        // Params are of the type given in the integration page creation.
}

logout(url, sessionId);
return results;


text:
module.exports = function() {
	this._cache = {};
	for (var index = 0; index < 100; index++) {
		this._cache['Key ' + index] = 'Value' + index;
	}

	this.isCacheEmpty = function() {
		return (Object.keys(this._cache).length === 0);
	};
};


text:
package org.http4s.server.blaze

import org.http4s.blaze.pipeline.MidStage
import org.http4s.blaze.util.Execution._
import org.http4s.util
import scala.concurrent.{Future, Promise}
import scala.util.{Failure, Success}
import java.net.ProtocolException
import org.http4s.server.blaze.WSFrameAggregator.Accumulator
import org.http4s.websocket.WebSocketFrame
import org.http4s.websocket.WebSocketFrame._
import scala.annotation.tailrec
import scala.collection.mutable
import scodec.bits.ByteVector

private class WSFrameAggregator extends MidStage[WebSocketFrame, WebSocketFrame] {

  def name: String = "WebSocket Frame Aggregator"

  private[this] val accumulator = new Accumulator

  def readRequest(size: Int): Future[WebSocketFrame] = {
    val p = Promise[WebSocketFrame]
    channelRead(size).onComplete {
      case Success(f) => readLoop(f, p)
      case Failure(t) => p.failure(t)
    }(directec)
    p.future
  }

  private def readLoop(frame: WebSocketFrame, p: Promise[WebSocketFrame]): Unit = frame match {
    case _: Text => handleHead(frame, p)
    case _: Binary => handleHead(frame, p)

    case c: Continuation =>
      if (accumulator.isEmpty) {
        val e = new ProtocolException(
          "Invalid state: Received a Continuation frame without accumulated state.")
        logger.error(e)("Invalid state")
        p.failure(e)
        ()
      } else {
        accumulator.append(frame)
        if (c.last) {
          // We are finished with the segment, accumulate
          p.success(accumulator.take())
          ()
        } else
          channelRead().onComplete {
            case Success(f) =>
              readLoop(f, p)
            case Failure(t) =>
              p.failure(t)
              ()
          }(trampoline)
      }

    case f =>
      // Must be a control frame, send it out
      p.success(f)
      ()
  }

  private def handleHead(frame: WebSocketFrame, p: Promise[WebSocketFrame]): Unit =
    if (!accumulator.isEmpty) {
      val e = new ProtocolException(s"Invalid state: Received a head frame with accumulated state")
      accumulator.clear()
      p.failure(e)
      ()
    } else if (frame.last) {
      // Head frame that is complete
      p.success(frame)
      ()
    } else {
      // Need to start aggregating
      accumulator.append(frame)
      channelRead().onComplete {
        case Success(f) =>
          readLoop(f, p)
        case Failure(t) =>
          p.failure(t)
          ()
      }(directec)
    }

  // Just forward write requests
  def writeRequest(data: WebSocketFrame): Future[Unit] = channelWrite(data)
  override def writeRequest(data: collection.Seq[WebSocketFrame]): Future[Unit] = channelWrite(data)
}

private object WSFrameAggregator {
  private final class Accumulator {
    private[this] val queue = new mutable.Queue[WebSocketFrame]
    private[this] var size = 0

    def isEmpty: Boolean = queue.isEmpty

    def append(frame: WebSocketFrame): Unit = {
      // The first frame needs to not be a continuation
      if (queue.isEmpty) frame match {
        case _: Text | _: Binary => // nop
        case f =>
          throw util.bug(s"Shouldn't get here. Wrong type: ${f.getClass.getName}")
      }
      size += frame.length
      queue += frame
      ()
    }

    def take(): WebSocketFrame = {
      val isText = queue.head match {
        case _: Text => true
        case _: Binary => false
        case f =>
          // shouldn't happen as it's guarded for in `append`
          val e = util.bug(s"Shouldn't get here. Wrong type: ${f.getClass.getName}")
          throw e
      }

      var out = ByteVector.empty
      @tailrec
      def go(): Unit =
        if (!queue.isEmpty) {
          val frame = queue.dequeue().data
          out ++= frame
          go()
        }
      go()

      size = 0
      if (isText) Text(out) else Binary(out)
    }

    def clear(): Unit = {
      size = 0
      queue.clear()
    }
  }
}


text:
require 'spec_helper'

RSpec.describe 'Zg integration specs' do
  let(:client) { Cryptoexchange::Client.new }
  let(:btc_usdt_pair) { Cryptoexchange::Models::MarketPair.new(base: 'BTC', target: 'USDT', market: 'zg') }

  it 'fetch pairs' do
    pairs = client.pairs('zg')
    expect(pairs).not_to be_empty

    pair = pairs.first
    expect(pair.base).to_not be nil
    expect(pair.target).to_not be nil
    expect(pair.market).to eq 'zg'
  end

  it 'give trade url' do
    trade_page_url = client.trade_page_url 'zg', base: btc_usdt_pair.base, target: btc_usdt_pair.target
    expect(trade_page_url).to eq "https://www.zg.com/exchange/737/BTC/USDT"
  end

  it 'fetch ticker' do
    ticker = client.ticker(btc_usdt_pair)

    expect(ticker.base).to eq 'BTC'
    expect(ticker.target).to eq 'USDT'
    expect(ticker.market).to eq 'zg'
    expect(ticker.last).to be_a Numeric
    expect(ticker.low).to be_a Numeric
    expect(ticker.high).to be_a Numeric
    expect(ticker.volume).to be_a Numeric
    expect(ticker.timestamp).to be nil

    expect(ticker.payload).to_not be nil
  end
end