text:
package scanner

import (
	"encoding/json"
	"io"
	"net/url"
)

// scanJobChild represents any URL found on an html page (ex html, img, css, js etc.
type scanJobChild struct {
	URL     *url.URL `json:"url"`     // The URL found.
	URLType string   `json:"urlType"` // The URL type ex: html, img, css, js etc.
}

// scanJob is a transport packet that represents URL that needs processing.
type scanJob struct {
	Stat     *Stats          `json:"stat"`     // Stats from the scan.
	Body     io.ReadCloser   `json:"body"`     // Body returned from the scan.
	Children []*scanJobChild `json:"children"` // Child URLs found on the page.
}

// scanJobNew is a factory for creating a new job instance.
func scanJobNew(u *url.URL, ut string, p *url.URL) *scanJob {
	return &scanJob{
		Stat:     StatsNew(u, ut, p),
		Children: []*scanJobChild{},
	}
}

// String is an implentation of the Stringer interface so the structure is returned as a
// string to fmt.Print() etc.
func (s *scanJob) String() string {
	j, _ := json.Marshal(s)
	return string(j)
}


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Prop Unlimiter: Member List</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

Prop Unlimiter

LitJson.IJsonWrapper Member List

This is the complete list of members for LitJson.IJsonWrapper, including all inherited members.

GetBoolean() (defined in LitJson.IJsonWrapper)	LitJson.IJsonWrapper

GetDouble() (defined in LitJson.IJsonWrapper)	LitJson.IJsonWrapper

GetInt() (defined in LitJson.IJsonWrapper)	LitJson.IJsonWrapper

GetJsonType() (defined in LitJson.IJsonWrapper)	LitJson.IJsonWrapper

GetLong() (defined in LitJson.IJsonWrapper)	LitJson.IJsonWrapper

GetString() (defined in LitJson.IJsonWrapper)	LitJson.IJsonWrapper

IsArray (defined in LitJson.IJsonWrapper)	LitJson.IJsonWrapper

IsBoolean (defined in LitJson.IJsonWrapper)	LitJson.IJsonWrapper

IsDouble (defined in LitJson.IJsonWrapper)	LitJson.IJsonWrapper

IsInt (defined in LitJson.IJsonWrapper)	LitJson.IJsonWrapper

IsLong (defined in LitJson.IJsonWrapper)	LitJson.IJsonWrapper

IsObject (defined in LitJson.IJsonWrapper)	LitJson.IJsonWrapper

IsString (defined in LitJson.IJsonWrapper)	LitJson.IJsonWrapper

SetBoolean(bool val) (defined in LitJson.IJsonWrapper)	LitJson.IJsonWrapper

SetDouble(double val) (defined in LitJson.IJsonWrapper)	LitJson.IJsonWrapper

SetInt(int val) (defined in LitJson.IJsonWrapper)	LitJson.IJsonWrapper

SetJsonType(JsonType type) (defined in LitJson.IJsonWrapper)	LitJson.IJsonWrapper

SetLong(long val) (defined in LitJson.IJsonWrapper)	LitJson.IJsonWrapper

SetString(string val) (defined in LitJson.IJsonWrapper)	LitJson.IJsonWrapper

ToJson() (defined in LitJson.IJsonWrapper)	LitJson.IJsonWrapper

ToJson(JsonWriter writer) (defined in LitJson.IJsonWrapper)	LitJson.IJsonWrapper

Generated by

     1.8.13

redpajama_set_name: RedPajamaGithub


text:
void gdb_print(const char* name);

#endif


text:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.social.com.view.ui">

    <application
        android:name="com.social.com.AndroidApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_circle"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".signup.SignupActivity"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".tutorial.TutorialActivity"
            android:screenOrientation="portrait"/>
        <activity
            android:name=".home.HomeActivity"
            android:screenOrientation="portrait" />
    </application>

</manifest>


text:
import React from 'react';
import {Link} from 'react-router';
import {shallow} from 'enzyme';
import Footer from '../../../../../client/common/components/footer';

describe('Footer', function() {
  describe('rendering', () => {
    it('should be a footer el', () => {
      const wrapper = shallow(<Footer/>);
      expect(wrapper.type()).to.equal('footer');
    });

    describe('the copyright', () => {
      it('should have the right text', () => {
        const wrapper = shallow(<Footer/>);
        const copyright = wrapper.find('.footer-copyright');
        expect(copyright.text()).to.equal('Copyright © Moolah 2016. All rights reserved.');
      });
    });

    describe('the nav', () => {
      it('should render a nav el', () => {
        const wrapper = shallow(<Footer/>);
        expect(wrapper.find('nav')).to.have.length(1);
      });

      it('should have the right links', () => {
        const wrapper = shallow(<Footer/>);
        const links = wrapper.find(Link);
        expect(links).to.have.length(4);
        expect(links.at(0).prop('to')).to.equal('/terms');
        expect(links.at(1).prop('to')).to.equal('/privacy');
        expect(links.at(2).prop('to')).to.equal('/about');
        expect(links.at(3).prop('to')).to.equal('/contact');
      });
    });
  });
});


text:
package dk.itu.lusa.run;

import com.anji.util.Properties;
import dk.itu.ejuuragr.domain.Simulator;
import dk.itu.ejuuragr.turing.TuringMachine;
import dk.itu.lusa.domain.blockpuzzle.BlockPuzzleInitializer;
import dk.itu.lusa.domain.blockpuzzle.Utilities;
import dk.itu.lusa.fitness.FitnessEvaluatorRepeater;
import dk.itu.lusa.turing.TuringControllerRepeater;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Random;

/**
 * Our version of the ANJI evolver which will
 * calculate the number of stimulus and response
 * neurons in the ANN based on the domain and TM
 * defined in properties.
 *
 * @author Rasmus
 *
 */
public class Evolver {

	public static void main(String[] args) throws Throwable {
		try {
			java.util.Properties p1 = new java.util.Properties();
			p1.load(ClassLoader.getSystemResourceAsStream(args[0]));
			String seedFromStdIn = (args.length < 2) ? null : args[1];
			if (!p1.containsKey("random.seed")) {
				String seed;
				if (seedFromStdIn == null) {
					System.out.println("Properties contain no random seed!");
					System.out.println("Enter desired random seed:");
					BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
					seed = br.readLine();
				} else {
					System.out.println("Loaded seed from std in: " + seedFromStdIn);
					seed = seedFromStdIn.toString();
				}
				p1.setProperty("random.seed", seed);
				p1.setProperty("log4j.appender.A1.File", "./db/log" + seed + ".txt");
				p1.setProperty("persistence.base.dir", "./db" + seed);
			}
			Properties props = new Properties(p1);

			Utilities.InitializeStaticVariables(props);
			BlockPuzzleInitializer.InitializeStaticData();

			com.anji.neat.Evolver evolver = new com.anji.neat.Evolver();
			TuringControllerRepeater controller = FitnessEvaluatorRepeater.loadController(props);
			Simulator sim = controller.getSimulator();
			TuringMachine tm = controller.getTuringMachine();
			props.setProperty("stimulus.size", String.valueOf(tm.getOutputCount() + sim.getOutputCount() + 1)); //Plus a bias input that is always 1
			props.setProperty("response.size", String.valueOf(tm.getInputCount() + sim.getInputCount()));

			if (props.getIntProperty("random.seed", -1) == -1) {
				props.setProperty("random.seed", String.valueOf(new Random().nextInt()));
			}

			evolver.init(props);
			evolver.run();
			System.exit(0);
		}catch(Exception e)
		{
			Utilities.WriteToFile("Exception has been thrown.");
			throw new Exception(e);
		}
	}

}


text:
'''
Hubble Nova plugin for running arbitrary commands and checking the output of
those commands

This module is deprecated, and must be explicitly enabled in pillar/minion
config via the hubblestack:nova:enable_command_module (should be set to True
to enable this module). This allows nova to run arbitrary commands via yaml
profiles.

:maintainer: HubbleStack / basepi
:maturity: 2016.7.0
:platform: All
:requires: SaltStack

Sample YAML data, with inline comments:

# Top level key lets the module know it should look at this data
command:
  # Unique ID for this set of audits
  nodev:
    data:
      # 'osfinger' grain, for multiplatform support
      'Red Hat Enterprise Linux Server-6':
        # tag is required
        tag: CIS-1.1.10
        # `commands` is a list of commands with individual flags
        commands:
          # Command to be run
          - 'grep "[[:space:]]/home[[:space:]]" /etc/fstab':
              # Check the output for this pattern
              # If match_output not provided, any output will be a match
              match_output: nodev
              # Use regex when matching the output (default False)
              match_output_regex: False
              # Invert the success criteria. If True, a match will cause failure (default False)
              fail_if_matched: False
          - 'mount | grep /home':
              match_output: nodev
              match_output_regex: False
              # Match each line of the output against our pattern
              # Any that don't match will make the audit fail (default False)
              match_output_by_line: True
          - ?
              |
                echo 'this is a multi-line'
                echo 'bash script'
                echo 'note the special ? syntax'
            :
              # Shell through which the script will be run, must be abs path
              shell: /bin/bash
              match_output: this
        # Aggregation strategy for multiple commands. Defaults to 'and', other option is 'or'
        aggregation: 'and'
      # Catch-all, if no other osfinger match was found
      '*':
        tag: generic_tag
        commands:
          - 'grep "[[:space:]]/home[[:space:]]" /etc/fstab':
              match_output: nodev
              match_output_regex: False
              fail_if_matched: False
          - 'mount | grep /home':
              match_output: nodev
              match_output_regex: False
              match_output_by_line: True
        aggregation: 'and'
    # Description will be output with the results
    description: '/home should be nodev'
'''
from __future__ import absolute_import
import logging

import fnmatch
import yaml
import os
import copy
import re
import salt.utils

log = logging.getLogger(__name__)

def __virtual__():
    if salt.utils.is_windows():
        return False, 'This audit module only runs on linux'
    return True

def audit(data_list, tags, debug=False):
    '''
    Run the command audits contained in the data_list
    '''
    __data__ = {}
    for profile, data in data_list:
        _merge_yaml(__data__, data, profile)
    __tags__ = _get_tags(__data__)

    if debug:
        log.debug('command audit __data__:')
        log.debug(__data__)
        log.debug('command audit __tags__:')
        log.debug(__tags__)

    ret = {'Success': [], 'Failure': [], 'Controlled': []}

    if __tags__ and not __salt__['config.get']('hubblestack:nova:enable_command_module',
                                               False):
        ret['Error'] = ['command module has not been explicitly enabled in '
                        'config. Please set hubblestack:nova:enable_command_module '
                        'to True in pillar or minion config to allow this module.']
        return ret

    for tag in __tags__:
        if fnmatch.fnmatch(tag, tags):
            for tag_data in __tags__[tag]:
                if 'control' in tag_data:
                    ret['Controlled'].append(tag_data)
                    continue
                if 'commands' not in tag_data:
                    continue
                command_results = []
                for command_data in tag_data['commands']:
                    for command, command_args in command_data.iteritems():
                        if 'shell' in command_args:
                            cmd_ret = __salt__['cmd.run'](command,
                                                          python_shell=True,
                                                          shell=command_args['shell'])
                        else:
                            cmd_ret = __salt__['cmd.run'](command,
                                                          python_shell=True)

                        found = False
                        if cmd_ret:
                            found = True

                        if 'match_output' in command_args:

                            if command_args.get('match_output_by_line'):
                                cmd_ret_lines = cmd_ret.splitlines()
                            else:
                                cmd_ret_lines = [cmd_ret]

                            for line in cmd_ret_lines:
                                if command_args.get('match_output_regex'):
                                    if not re.match(command_args['match_output'], line):
                                        found = False
                                else:  # match without regex
                                    if command_args['match_output'] not in line:
                                        found = False

                        if command_args.get('fail_if_matched'):
                            found = not found

                        command_results.append(found)

                aggregation = tag_data.get('aggregation', 'and')

                if aggregation.lower() == 'or':
                    if any(command_results):
                        ret['Success'].append(tag_data)
                    else:
                        ret['Failure'].append(tag_data)
                else:  # assume 'and' if it's not 'or'
                    if all(command_results):
                        ret['Success'].append(tag_data)
                    else:
                        ret['Failure'].append(tag_data)

    return ret

def _merge_yaml(ret, data, profile=None):
    '''
    Merge two yaml dicts together at the command level
    '''
    if 'command' not in ret:
        ret['command'] = []
    if 'command' in data:
        for key, val in data['command'].iteritems():
            if profile and isinstance(val, dict):
                val['nova_profile'] = profile
            ret['command'].append({key: val})
    return ret

def _get_tags(data):
    '''
    Retrieve all the tags for this distro from the yaml
    '''
    ret = {}
    distro = __grains__.get('osfinger')
    for audit_dict in data.get('command', []):
        # command:0
        for audit_id, audit_data in audit_dict.iteritems():
            # command:0:nodev
            tags_dict = audit_data.get('data', {})
            # command:0:nodev:data
            tags = None
            for osfinger in tags_dict:
                if osfinger == '*':
                    continue
                osfinger_list = [finger.strip() for finger in osfinger.split(',')]
                for osfinger_glob in osfinger_list:
                    if fnmatch.fnmatch(distro, osfinger_glob):
                        tags = tags_dict.get(osfinger)
                        break
                if tags is not None:
                    break
            # If we didn't find a match, check for a '*'
            if tags is None:
                tags = tags_dict.get('*', {})
            # command:0:nodev:data:Debian-8
            if 'tag' not in tags:
                tags['tag'] = ''
            tag = tags['tag']
            if tag not in ret:
                ret[tag] = []
            formatted_data = {'tag': tag,
                              'module': 'command'}
            formatted_data.update(audit_data)
            formatted_data.update(tags)
            formatted_data.pop('data')
            ret[tag].append(formatted_data)
    return ret


text:
package org.wso2.carbon.identity.query.saml.validation;

import org.opensaml.saml.saml2.core.RequestAbstractType;
import org.wso2.carbon.identity.query.saml.dto.InvalidItemDTO;
import org.wso2.carbon.identity.query.saml.exception.IdentitySAML2QueryException;

import java.util.List;

/**
 * SAMLQueryValidator interface has multiple implementations for validating different
 * request message types.Each message has different elements to validate and return assertions
 * according to the requirement.
 */
public interface SAMLQueryValidator {

    /**
     * This method is used to validate any type of request message
     *
     * @param request      any type of request message in RequestAbstractType
     * @param invalidItems List of invalid items
     * @return Boolean true, if request message contain no validation errors
     * @throws  IdentitySAML2QueryException If unable to validate Request messages
     */
    boolean validate(List<InvalidItemDTO> invalidItems, RequestAbstractType request) throws IdentitySAML2QueryException;

}


text:
import { NgModule } from '@angular/core';
import { HttpModule } from '@angular/http';
import { RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { FinancesPageContainer } from './containers/finances-page/finances-page.container';
import { CommonLogicModule } from '../common/index';

@NgModule({
    imports: [FormsModule, RouterModule, CommonModule, CommonLogicModule, HttpModule],
    declarations: [FinancesPageContainer],
    exports: [FinancesPageContainer],
    providers: []
})
export class FinancesModule {
}


text:
package com.cezarykluczynski.stapi.model.throttle.dto;

import lombok.Data;

@Data
public class ThrottleStatistics {

	private boolean decremented;

	private Integer total;

	private Integer remaining;

}


text:
/*
 * MinIO Cloud Storage, (C) 2018 MinIO, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package policy

import (
	"encoding/json"
	"reflect"
	"testing"
)

func TestResourceIsBucketPattern(t *testing.T) {
	testCases := []struct {
		resource       Resource
		expectedResult bool
	}{
		{NewResource("*", ""), true},
		{NewResource("mybucket", ""), true},
		{NewResource("mybucket*", ""), true},
		{NewResource("mybucket?0", ""), true},
		{NewResource("", "*"), false},
		{NewResource("*", "*"), false},
		{NewResource("mybucket", "*"), false},
		{NewResource("mybucket*", "/myobject"), false},
		{NewResource("mybucket?0", "/2010/photos/*"), false},
	}

	for i, testCase := range testCases {
		result := testCase.resource.isBucketPattern()

		if result != testCase.expectedResult {
			t.Fatalf("case %v: expected: %v, got: %v", i+1, testCase.expectedResult, result)
		}
	}
}

func TestResourceIsObjectPattern(t *testing.T) {
	testCases := []struct {
		resource       Resource
		expectedResult bool
	}{
		{NewResource("*", ""), true},
		{NewResource("mybucket*", ""), true},
		{NewResource("", "*"), true},
		{NewResource("*", "*"), true},
		{NewResource("mybucket", "*"), true},
		{NewResource("mybucket*", "/myobject"), true},
		{NewResource("mybucket?0", "/2010/photos/*"), true},
		{NewResource("mybucket", ""), false},
		{NewResource("mybucket?0", ""), false},
	}

	for i, testCase := range testCases {
		result := testCase.resource.isObjectPattern()

		if result != testCase.expectedResult {
			t.Fatalf("case %v: expected: %v, got: %v", i+1, testCase.expectedResult, result)
		}
	}
}

func TestResourceIsValid(t *testing.T) {
	testCases := []struct {
		resource       Resource
		expectedResult bool
	}{
		{NewResource("*", ""), true},
		{NewResource("mybucket*", ""), true},
		{NewResource("*", "*"), true},
		{NewResource("mybucket", "*"), true},
		{NewResource("mybucket*", "/myobject"), true},
		{NewResource("mybucket?0", "/2010/photos/*"), true},
		{NewResource("mybucket", ""), true},
		{NewResource("mybucket?0", ""), true},
		{NewResource("", ""), false},
		{NewResource("", "*"), false},
	}

	for i, testCase := range testCases {
		result := testCase.resource.IsValid()

		if result != testCase.expectedResult {
			t.Fatalf("case %v: expected: %v, got: %v", i+1, testCase.expectedResult, result)
		}
	}
}

func TestResourceMatch(t *testing.T) {
	testCases := []struct {
		resource       Resource
		objectName     string
		expectedResult bool
	}{
		{NewResource("*", ""), "mybucket", true},
		{NewResource("*", ""), "mybucket/myobject", true},
		{NewResource("mybucket*", ""), "mybucket", true},
		{NewResource("mybucket*", ""), "mybucket/myobject", true},
		{NewResource("", "*"), "/myobject", true},
		{NewResource("*", "*"), "mybucket/myobject", true},
		{NewResource("mybucket", "*"), "mybucket/myobject", true},
		{NewResource("mybucket*", "/myobject"), "mybucket/myobject", true},
		{NewResource("mybucket*", "/myobject"), "mybucket100/myobject", true},
		{NewResource("mybucket?0", "/2010/photos/*"), "mybucket20/2010/photos/1.jpg", true},
		{NewResource("mybucket", ""), "mybucket", true},
		{NewResource("mybucket?0", ""), "mybucket30", true},
		{NewResource("", "*"), "mybucket/myobject", false},
		{NewResource("*", "*"), "mybucket", false},
		{NewResource("mybucket", "*"), "mybucket10/myobject", false},
		{NewResource("mybucket?0", "/2010/photos/*"), "mybucket0/2010/photos/1.jpg", false},
		{NewResource("mybucket", ""), "mybucket/myobject", false},
	}

	for i, testCase := range testCases {
		result := testCase.resource.Match(testCase.objectName, nil)

		if result != testCase.expectedResult {
			t.Fatalf("case %v: expected: %v, got: %v", i+1, testCase.expectedResult, result)
		}
	}
}

func TestResourceMarshalJSON(t *testing.T) {
	testCases := []struct {
		resource       Resource
		expectedResult []byte
		expectErr      bool
	}{
		{NewResource("*", ""), []byte(`"arn:aws:s3:::*"`), false},
		{NewResource("mybucket*", ""), []byte(`"arn:aws:s3:::mybucket*"`), false},
		{NewResource("mybucket", ""), []byte(`"arn:aws:s3:::mybucket"`), false},
		{NewResource("*", "*"), []byte(`"arn:aws:s3:::*/*"`), false},
		{NewResource("mybucket", "*"), []byte(`"arn:aws:s3:::mybucket/*"`), false},
		{NewResource("mybucket*", "myobject"), []byte(`"arn:aws:s3:::mybucket*/myobject"`), false},
		{NewResource("mybucket?0", "/2010/photos/*"), []byte(`"arn:aws:s3:::mybucket?0/2010/photos/*"`), false},
		{Resource{}, nil, true},
		{NewResource("", "*"), nil, true},
	}

	for i, testCase := range testCases {
		result, err := json.Marshal(testCase.resource)
		expectErr := (err != nil)

		if expectErr != testCase.expectErr {
			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
		}

		if !testCase.expectErr {
			if !reflect.DeepEqual(result, testCase.expectedResult) {
				t.Fatalf("case %v: result: expected: %v, got: %v", i+1, string(testCase.expectedResult), string(result))
			}
		}
	}
}

func TestResourceUnmarshalJSON(t *testing.T) {
	testCases := []struct {
		data           []byte
		expectedResult Resource
		expectErr      bool
	}{
		{[]byte(`"arn:aws:s3:::*"`), NewResource("*", ""), false},
		{[]byte(`"arn:aws:s3:::mybucket*"`), NewResource("mybucket*", ""), false},
		{[]byte(`"arn:aws:s3:::mybucket"`), NewResource("mybucket", ""), false},
		{[]byte(`"arn:aws:s3:::*/*"`), NewResource("*", "*"), false},
		{[]byte(`"arn:aws:s3:::mybucket/*"`), NewResource("mybucket", "*"), false},
		{[]byte(`"arn:aws:s3:::mybucket*/myobject"`), NewResource("mybucket*", "myobject"), false},
		{[]byte(`"arn:aws:s3:::mybucket?0/2010/photos/*"`), NewResource("mybucket?0", "/2010/photos/*"), false},
		{[]byte(`"mybucket/myobject*"`), Resource{}, true},
		{[]byte(`"arn:aws:s3:::/*"`), Resource{}, true},
	}

	for i, testCase := range testCases {
		var result Resource
		err := json.Unmarshal(testCase.data, &result)
		expectErr := (err != nil)

		if expectErr != testCase.expectErr {
			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
		}

		if !testCase.expectErr {
			if !reflect.DeepEqual(result, testCase.expectedResult) {
				t.Fatalf("case %v: result: expected: %v, got: %v", i+1, testCase.expectedResult, result)
			}
		}
	}
}

func TestResourceValidate(t *testing.T) {
	testCases := []struct {
		resource   Resource
		bucketName string
		expectErr  bool
	}{
		{NewResource("mybucket", "/myobject*"), "mybucket", false},
		{NewResource("", "/myobject*"), "yourbucket", true},
		{NewResource("mybucket", "/myobject*"), "yourbucket", true},
	}

	for i, testCase := range testCases {
		err := testCase.resource.Validate(testCase.bucketName)
		expectErr := (err != nil)

		if expectErr != testCase.expectErr {
			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
		}
	}
}


text:
package com.ehensin.tunnel.server.profile;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlType
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "codec")
public class CodecProfile {
	@XmlAttribute(name="msg_format")
	 private String msgFormat;
	@XmlAttribute(name="codec_class")
	 private String codecClass;
	public String getMsgFormat() {
		return msgFormat;
	}
	public void setMsgFormat(String msgFormat) {
		this.msgFormat = msgFormat;
	}
	public String getCodecClass() {
		return codecClass;
	}
	public void setCodecClass(String codecClass) {
		this.codecClass = codecClass;
	}

}


text:
#if !defined(FUSION_END_04052005_1141)
#define FUSION_END_04052005_1141

#include <lslboost/blank.hpp>
#include <lslboost/utility/enable_if.hpp>
#include <lslboost/mpl/if.hpp>
#include <lslboost/fusion/sequence/intrinsic_fwd.hpp>
#include <lslboost/fusion/support/tag_of.hpp>
#include <lslboost/fusion/support/is_sequence.hpp>
#include <lslboost/fusion/support/is_segmented.hpp>
#include <lslboost/fusion/sequence/intrinsic/detail/segmented_end.hpp>

namespace lslboost { namespace fusion
{
    // Special tags:
    struct sequence_facade_tag;
    struct lslboost_tuple_tag; // lslboost::tuples::tuple tag
    struct lslboost_array_tag; // lslboost::array tag
    struct mpl_sequence_tag; // mpl sequence tag
    struct std_pair_tag; // std::pair tag

    namespace extension
    {
        template <typename Tag>
        struct end_impl
        {
            template <typename Sequence>
            struct apply
              : mpl::if_<
                    traits::is_segmented<Sequence>
                  , detail::segmented_end<Sequence>
                  , blank
                >::type
            {};
        };

        template <>
        struct end_impl<sequence_facade_tag>
        {
            template <typename Sequence>
            struct apply : Sequence::template end<Sequence> {};
        };

        template <>
        struct end_impl<lslboost_tuple_tag>;

        template <>
        struct end_impl<lslboost_array_tag>;

        template <>
        struct end_impl<mpl_sequence_tag>;

        template <>
        struct end_impl<std_pair_tag>;
    }

    namespace result_of
    {
        template <typename Sequence>
        struct end
            : extension::end_impl<typename detail::tag_of<Sequence>::type>::
                template apply<Sequence>
        {};
    }

    template <typename Sequence>
    inline typename
        lazy_enable_if<
            traits::is_sequence<Sequence>
          , result_of::end<Sequence>
        >::type const
    end(Sequence& seq)
    {
        return result_of::end<Sequence>::call(seq);
    }

    template <typename Sequence>
    inline typename
        lazy_enable_if<
            traits::is_sequence<Sequence>
          , result_of::end<Sequence const>
        >::type const
    end(Sequence const& seq)
    {
        return result_of::end<Sequence const>::call(seq);
    }
}}

#endif


text:
class CFX_Graphics;
class CFWL_Widget;

class CFWL_Event {
 public:
  enum class Type {
    CheckStateChanged,
    CheckWord,
    Click,
    Close,
    EditChanged,
    Mouse,
    PostDropDown,
    PreDropDown,
    Scroll,
    SelectChanged,
    TextChanged,
    TextFull,
    Validate
  };

  explicit CFWL_Event(Type type);
  CFWL_Event(Type type, CFWL_Widget* pSrcTarget);
  CFWL_Event(Type type, CFWL_Widget* pSrcTarget, CFWL_Widget* pDstTarget);
  virtual ~CFWL_Event();

  Type GetType() const { return m_type; }

  CFWL_Widget* m_pSrcTarget;
  CFWL_Widget* m_pDstTarget;

 private:
  Type m_type;
};

#endif  // XFA_FWL_CFWL_EVENT_H_


text:
from typing import Union, Optional

from requests_oauthlib import OAuth1
from dateparser import parse
from datetime import timedelta
from CommonServerPython import *
import urllib3
urllib3.disable_warnings()

''' GLOBALS/PARAMS '''
BASE_URL = demisto.getParam('url').rstrip('/') + '/'
API_TOKEN = demisto.getParam('APItoken') or (demisto.getParam('credentials') or {}).get('password')
USERNAME = demisto.getParam('username')
PASSWORD = demisto.getParam('password')
COMMAND_NOT_IMPELEMENTED_MSG = 'Command not implemented'

HEADERS = {
    'Content-Type': 'application/json',
}
JIRA_INCIDENT_TYPE_NAME = 'Jira Incident'
ISSUE_INCIDENT_FIELDS = {'issueId': 'The ID of the issue to edit',
                         'summary': 'The summary of the issue.',
                         'description': 'The description of the issue.',
                         'labels': 'A CSV list of labels.',
                         'priority': 'A priority name, for example "High" or "Medium".',
                         'dueDate': 'The due date for the issue (in the format 2018-03-11).',
                         'assignee': 'The name of the assignee.',
                         'status': 'The name of the status.',
                         'assignee_id': 'The account ID of the assignee. Use'
                                        ' the jira-get-id-by-attribute command to get the user\'s Account ID.'
                         }
BASIC_AUTH_ERROR_MSG = "For cloud users: As of June 2019, Basic authentication with passwords for Jira is no" \
                       " longer supported, please use an API Token or OAuth 1.0"
JIRA_RESOLVE_REASON = 'Issue was marked as "Done"'
USE_SSL = not demisto.params().get('insecure', False)

def jira_req(
        method: str,
        resource_url: str,
        body: str = '',
        link: bool = False,
        resp_type: str = 'text',
        headers: Optional[dict] = None,
        files: Optional[dict] = None
):
    url = resource_url if link else (BASE_URL + resource_url)
    AUTH = get_auth()
    if headers and HEADERS.get('Authorization'):
        headers['Authorization'] = HEADERS.get('Authorization')
    try:
        result = requests.request(
            method=method,
            url=url,
            data=body,
            auth=AUTH,
            headers=headers if headers else HEADERS,
            verify=USE_SSL,
            files=files
        )
    except ValueError:
        raise ValueError("Could not deserialize privateKey")

    if not result.ok:
        demisto.debug(result.text)
        try:
            rj = result.json()
            if rj.get('errorMessages'):
                raise DemistoException(f'Status code: {result.status_code}\nMessage: {",".join(rj["errorMessages"])}')
            elif rj.get('errors'):
                raise DemistoException(f'Status code: {result.status_code}\nMessage: {",".join(rj["errors"].values())}')
            else:
                raise DemistoException(f'Status code: {result.status_code}\nError text: {result.text}')
        except ValueError as ve:
            demisto.debug(str(ve))
            if result.status_code == 401:
                raise DemistoException('Unauthorized request, please check authentication related parameters.'
                                       f'{BASIC_AUTH_ERROR_MSG}')
            elif result.status_code == 404:
                raise DemistoException("Could not connect to the Jira server. Verify that the server URL is correct.")
            elif result.status_code == 500 and files:
                raise DemistoException(f"Failed to execute request, status code: 500\nBody: {result.text}"
                                       f"\nMake sure file name doesn't contain any special characters")
            else:
                raise DemistoException(
                    f"Failed reaching the server. status code: {result.status_code}")

    if resp_type == 'json':
        return result.json()
    return result

def generate_oauth1():
    oauth = OAuth1(
        client_key=demisto.getParam('consumerKey'),
        rsa_key=demisto.getParam('privateKey'),
        signature_method='RSA-SHA1',
        resource_owner_key=demisto.getParam('accessToken'),
    )
    return oauth

def generate_basic_oauth():
    return USERNAME, (API_TOKEN or PASSWORD)

def get_auth():
    access_token = demisto.getParam('accessToken')
    is_basic = USERNAME and (PASSWORD or API_TOKEN)
    is_oauth1 = demisto.getParam('consumerKey') and access_token and demisto.getParam('privateKey')
    is_bearer = access_token and not is_oauth1

    if is_basic:
        return generate_basic_oauth()

    elif is_oauth1:
        HEADERS.update({'X-Atlassian-Token': 'nocheck'})
        return generate_oauth1()

    elif is_bearer:
        # Personal Access Token Authentication
        HEADERS.update({'Authorization': f'Bearer {access_token}'})
        return

    return_error(
        'Please provide the required Authorization information:'
        '- Basic Authentication requires user name and password or API token'
        '- OAuth 1.0 requires ConsumerKey, AccessToken and PrivateKey'
        '- Personal Access Tokens requires AccessToken'
    )

def get_custom_field_names():
    """
    This function returns all custom fields.
    :return: dict of custom fields: id as key and name as value.
    """
    custom_id_name_mapping = {}
    HEADERS['Accept'] = "application/json"
    try:
        res = requests.request(
            method='GET',
            url=BASE_URL + 'rest/api/latest/field',
            headers=HEADERS,
            verify=USE_SSL,
            auth=get_auth(),
        )
    except Exception as e:
        demisto.error(f'Could not get custom fields because got the next exception: {e}')
    else:
        if res.ok:
            custom_fields_list = res.json()
            custom_id_name_mapping = {field.get('id'): field.get('name') for field in custom_fields_list}
        else:
            demisto.error(f'Could not get custom fields. status code: {res.status_code}. reason: {res.reason}')
    finally:
        return custom_id_name_mapping

def run_query(query, start_at='', max_results=None, extra_fields=None, nofields=None):
    # EXAMPLE
    """
    request = {
        "jql": "project = HSP",
        "startAt": 0,
        "maxResults": 15,
        "fields": [    <-- not supported yet, but easily attainable
            "summary",
            "status",
            "assignee"
        ]
    }
    """
    demisto.debug(f'querying with: {query}')
    url = BASE_URL + 'rest/api/latest/search/'
    query_params = {
        'jql': query,
        "startAt": start_at,
        "maxResults": max_results,
    }
    if extra_fields:
        fields = extra_fields.split(",")
        fields_mapping_name_id = {k.lower(): v.lower() for k, v in get_custom_field_names().items()}
        query_params['fields'] = [k for y in fields for k, v in fields_mapping_name_id.items() if v == y.lower()]
        nofields.update(
            {fieldextra for fieldextra in fields if fieldextra.lower() not in fields_mapping_name_id.values()})
    if nofields:
        if len(nofields) > 1:
            return_warning(f'{",".join(nofields)} do not exist')
        else:
            return_warning(f'{",".join(nofields)} does not exist')
    try:
        result = requests.get(
            url=url,
            headers=HEADERS,
            verify=USE_SSL,
            params=query_params,
            auth=get_auth(),
        )
    except ValueError:
        raise ValueError("Could not deserialize privateKey")

    try:
        rj = result.json()
        if rj.get('issues'):
            return rj

        errors = ",".join(rj.get("errorMessages", ['could not fetch any issues, please check your query']))
        if 'could not fetch any issues, please check your query' in errors:
            return {}
        raise Exception(f'No issues were found, error message from Jira: {errors}')

    except ValueError as ve:
        demisto.debug(str(ve))
        raise Exception(f'Failed to send request, reason: {result.reason}')

def get_id_offset():
    """
    gets the ID Offset, i.e., the first issue id. used to fetch correctly all issues
    """
    query = "ORDER BY created ASC"
    j_res = run_query(query=query, max_results=1)
    first_issue_id = j_res.get('issues')[0].get('id')
    return_outputs(
        readable_output=f"ID Offset: {first_issue_id}",
        outputs={'Ticket.idOffSet': first_issue_id},
    )

def get_custom_fields():
    """
    This function returns all custom fields.
    :return: dict of custom fields: id as key and description as value.
    """
    custom_id_description_mapping = {}
    HEADERS['Accept'] = "application/json"
    try:
        res = requests.request(
            method='GET',
            url=BASE_URL + 'rest/api/latest/field',
            headers=HEADERS,
            verify=USE_SSL,
            auth=get_auth(),
        )
    except Exception as e:
        demisto.error(f'Could not get custom fields because got the next exception: {e}')
    else:
        if res.status_code == 200:
            custom_fields_list = res.json()
            custom_id_description_mapping = {field.get('id'): field.get('description') for field in custom_fields_list}
        else:
            demisto.error(f'Could not get custom fields. status code: {res.status_code}. reason: {res.reason}')
    finally:
        return custom_id_description_mapping

def expand_urls(data, depth=0):
    if isinstance(data, dict) and depth < 10:
        for key, value in data.items():
            if key in ['_links', 'watchers', 'sla', 'request participants']:
                # dictionary of links
                if isinstance(value, dict):
                    for link_key, link_url in value.items():
                        value[link_key + '_expended'] = json.dumps(
                            jira_req(method='GET', resource_url=link_url, link=True, resp_type='json'))
                # link
                else:
                    data[key + '_expended'] = json.dumps(jira_req(method='GET', resource_url=value,
                                                                  link=True, resp_type='json'))
            # search deeper
            else:
                if isinstance(value, dict):
                    return expand_urls(value, depth + 1)

def search_user(query: str, max_results: str = '50', is_jirav2api: bool = False):
    """
        Search for user by name or email address.
    Args:
        query: A query string that is matched against user attributes ( displayName, and emailAddress) to find relevant users.
        max_results (str): The maximum number of items to return. default by the server: 50
        is_jirav2api (bool): if the instance is connecting to a Jira Server that supports only the v2 REST API. default as False

    Returns:
        List of users.
    """

    if is_jirav2api:
        """
        override user identifier for Jira v2 API
        https://docs.atlassian.com/software/jira/docs/api/REST/8.13.15/#user-findUsers
        """
        url = f"rest/api/latest/user/search?username={query}&maxResults={max_results}"
    else:
        url = f"rest/api/latest/user/search?query={query}&maxResults={max_results}"

    res = jira_req('GET', url, resp_type='json')
    return res

def get_account_id_from_attribute(
        attribute: str,
        max_results: str = '50',
        is_jirav2api: str = 'false') -> Union[CommandResults, str]:
    """
    https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-user-search/#api-rest-api-3-user-search-get

    Args:
        attribute (str): Username or Email address of a user.
        max_results (str): The maximum number of items to return. default by the server: 50
        is_jirav2api (str): if the instance is connecting to a Jira Server that supports only the v2 REST API. default as false
    """

    if is_jirav2api == 'true':
        """
        override user identifier for Jira v2 API
        https://docs.atlassian.com/software/jira/docs/api/REST/8.13.15/#user-findUsers
        """
        users = list(search_user(attribute, max_results, is_jirav2api=True))
        account_ids = {
            user.get('name') for user in users if (attribute.lower() in [user.get('displayName', '').lower(),
                                                                         user.get('emailAddress', '').lower()])}
    else:
        users = list(search_user(attribute, max_results))
        account_ids = {
            user.get('accountId') for user in users if (attribute.lower() in [user.get('displayName', '').lower(),
                                                                              user.get('emailAddress', '').lower()])}

    if not account_ids:
        # The email address is a private account field and sometimes is blank. If there is only one result,
        # then it is the one. If there are more results for the query, the user should try "DisplayName" attribute.
        if not users:
            return f'No Account ID was found for attribute: {attribute}.'
        if len(users) == 1:
            account_ids = {users[0].get('name')} if is_jirav2api == 'true' else {users[0].get('accountId')}
        else:
            demisto.debug(f'Multiple account IDs found, but it was not possible to resolve which one of them is most '
                          f'relevant to attribute \"{attribute}\". Account ids: {account_ids}')
            return f'Multiple account IDs found, but it was not possible to resolve which one of them is most ' \
                   f'relevant to attribute \"{attribute}\".Please try to provide the "DisplayName" attribute.'

    if len(account_ids) > 1:
        return f'Multiple account IDs were found for attribute: {attribute}.\n' \
               f'Please try to provide the other attribute available - Email or DisplayName.'

    account_id = next(iter(account_ids))
    outputs = {
        'Attribute': attribute,
        'AccountID': account_id
    }

    return CommandResults(
        outputs_prefix='Jira.User',
        outputs_key_field='AccountID',
        readable_output=f'Account ID for attribute: {attribute} is: {account_id}',
        outputs=outputs,
    )

def generate_md_context_get_issue(data, customfields=None, nofields=None, extra_fields=None):
    get_issue_obj: dict = {"md": [], "context": []}
    if not isinstance(data, list):
        data = [data]

    for element in data:
        md_obj, context_obj = {}, {}

        context_obj['Id'] = md_obj['id'] = demisto.get(element, 'id')
        context_obj['Key'] = md_obj['key'] = demisto.get(element, 'key')
        context_obj['Summary'] = md_obj['summary'] = demisto.get(element, 'fields.summary')
        context_obj['Status'] = md_obj['status'] = demisto.get(element, 'fields.status.name')
        context_obj['Priority'] = md_obj['priority'] = demisto.get(element, 'fields.priority.name')
        context_obj['ProjectName'] = md_obj['project'] = demisto.get(element, 'fields.project.name')
        context_obj['DueDate'] = md_obj['duedate'] = demisto.get(element, 'fields.duedate')
        context_obj['Created'] = md_obj['created'] = demisto.get(element, 'fields.created')
        context_obj['Description'] = md_obj['description'] = demisto.get(element, 'fields.description')

        # Parse custom fields into their original names
        custom_fields = [i for i in demisto.get(element, "fields") if "custom" in i]
        if extra_fields:
            custom_fields = extra_fields
        if (custom_fields and customfields and not nofields) or extra_fields:
            field_mappings = get_custom_field_names()
            for field_returned in custom_fields:
                readable_field_name = field_mappings.get(field_returned)
                if readable_field_name:
                    context_obj[readable_field_name] = md_obj[readable_field_name] = \
                        demisto.get(element, f"fields.{field_returned}")

        assignee = demisto.get(element, 'fields.assignee')
        context_obj['Assignee'] = md_obj['assignee'] = "{name}({email})".format(
            name=assignee.get('displayName', 'null'),
            email=assignee.get('emailAddress', 'null')
        ) if assignee else 'null(null)'

        creator = demisto.get(element, 'fields.creator')
        context_obj['Creator'] = md_obj['creator'] = "{name}({email})".format(
            name=creator.get('displayName', 'null'),
            email=creator.get('emailAddress', 'null')
        ) if creator else 'null(null)'

        reporter = demisto.get(element, 'fields.reporter')
        md_obj['reporter'] = "{name}({email})".format(
            name=reporter.get('displayName', 'null'),
            email=reporter.get('emailAddress', 'null')
        ) if reporter else 'null(null)'

        context_obj.update({
            'LastSeen': demisto.get(element, 'fields.lastViewed'),
            'LastUpdate': demisto.get(element, 'fields.updated'),
        })

        md_obj.update({
            'issueType': f"{demisto.get(element, 'fields.issuetype.name')} "
                         f"({demisto.get(element, 'fields.issuetype.description')})",
            'labels': demisto.get(element, 'fields.labels'),
            'description': demisto.get(element, 'fields.description'),
            'ticket_link': demisto.get(element, 'self'),
        })
        attachments = demisto.get(element, 'fields.attachment')
        if isinstance(attachments, list):
            md_obj['attachment'] = ','.join(attach.get('filename') for attach in attachments)
            context_obj['attachment'] = ','.join(attach.get('filename') for attach in attachments)

        get_issue_obj['md'].append(md_obj)
        get_issue_obj['context'].append(context_obj)

    return get_issue_obj

def generate_md_context_create_issue(data, project_name=None, project_key=None):
    create_issue_obj = {"md": [], "context": {"Ticket": []}}  # type: ignore
    if project_name:
        data["projectName"] = project_name

    if project_key:
        data["projectKey"] = project_key

    elif demisto.getParam('projectKey'):
        data["projectKey"] = demisto.getParam('projectKey')

    create_issue_obj['md'].append(data)  # type: ignore
    create_issue_obj['context']['Ticket'].append(  # type: ignore
        {"Id": demisto.get(data, 'id'), "Key": demisto.get(data, 'key')})  # type: ignore
    return create_issue_obj

def generate_md_upload_issue(data, issue_id):
    upload_md = []
    if not isinstance(data, list):
        data = [data]

    for element in data:
        md_obj = {
            'id': demisto.get(element, 'id'),
            'issueId': issue_id,
            'attachment_name': demisto.get(element, 'filename'),
            'attachment_link': demisto.get(element, 'self')
        }
        upload_md.append(md_obj)

    return upload_md

def get_mirror_type(should_mirror_in, should_mirror_out):
    """
    This function return the type of mirror to perform on a Jira incident.
    NOTE: in order to not mirror an incident, the type should be None.
    :param should_mirror_in: demisto.params().get("incoming_mirror")
    :param should_mirror_out: demisto.params().get('outgoing_mirror')
    :return: The mirror type
    """
    # Adding mirroring details
    mirror_type = None
    if should_mirror_in and should_mirror_out:
        mirror_type = 'Both'
    elif should_mirror_in:
        mirror_type = 'In'
    elif should_mirror_out:
        mirror_type = 'Out'
    return mirror_type

def create_incident_from_ticket(issue, should_get_attachments, should_get_comments, should_mirror_in, should_mirror_out,
                                comment_tag, attachment_tag):
    labels = [
        {'type': 'issue', 'value': json.dumps(issue)}, {'type': 'id', 'value': str(issue.get('id'))},
        {'type': 'lastViewed', 'value': str(demisto.get(issue, 'fields.lastViewed'))},
        {'type': 'priority', 'value': str(demisto.get(issue, 'fields.priority.name'))},
        {'type': 'status', 'value': str(demisto.get(issue, 'fields.status.name'))},
        {'type': 'project', 'value': str(demisto.get(issue, 'fields.project.name'))},
        {'type': 'updated', 'value': str(demisto.get(issue, 'fields.updated'))},
        {'type': 'reportername', 'value': str(demisto.get(issue, 'fields.reporter.displayName'))},
        {'type': 'reporteremail', 'value': str(demisto.get(issue, 'fields.reporter.emailAddress'))},
        {'type': 'created', 'value': str(demisto.get(issue, 'fields.created'))},
        {'type': 'summary', 'value': str(demisto.get(issue, 'fields.summary'))},
        {'type': 'description', 'value': str(demisto.get(issue, 'fields.description'))},

    ]

    name = demisto.get(issue, 'fields.summary')
    if name:
        name = f"Jira issue: {issue.get('id')}"

    severity = 0
    if demisto.get(issue, 'fields.priority') and demisto.get(issue, 'fields.priority.name'):
        if demisto.get(issue, 'fields.priority.name') == 'Highest':
            severity = 4
        elif demisto.get(issue, 'fields.priority.name') == 'High':
            severity = 3
        elif demisto.get(issue, 'fields.priority.name') == 'Medium':
            severity = 2
        elif demisto.get(issue, 'fields.priority.name') == 'Low':
            severity = 1

    file_names = []
    if should_get_attachments:
        for file_result in get_entries_for_fetched_incident(issue.get('id'), False, True)['attachments']:
            if file_result['Type'] != entryTypes['error']:
                file_names.append({
                    'path': file_result.get('FileID', ''),
                    'name': file_result.get('File', '')
                })

    if should_get_comments:
        labels.append({'type': 'comments', 'value': str(get_entries_for_fetched_incident(issue.get('id'), True, False)
                                                        ['comments'])})
    else:
        labels.append({'type': 'comments', 'value': '[]'})

    issue['mirror_direction'] = get_mirror_type(should_mirror_in, should_mirror_out)

    issue['mirror_tags'] = [
        comment_tag,
        attachment_tag
    ]
    issue['mirror_instance'] = demisto.integrationInstance()

    return {
        "name": name,
        "labels": labels,
        "details": demisto.get(issue, "fields.description"),
        "severity": severity,
        "attachment": file_names,
        "rawJSON": json.dumps(issue)
    }

def get_project_id(project_key='', project_name=''):
    if not project_key and not project_name:
        return_error('You must provide at least one of the following: project_key or project_name')

    result: dict = {}

    try:
        result = jira_req('GET', 'rest/api/latest/issue/createmeta', resp_type='json')
    except DemistoException as de:

        if de.message != 'Status code: 404\nMessage: Issue Does Not Exist':
            raise de

        demisto.debug(f'Could not find expected Jira endpoint: {BASE_URL}/api/latest/issue/createmeta.'
                      f'Trying another endpoint: {BASE_URL}/api/latest/project.')

        # a new endpoint for Jira version 9.0.0 and above, so we execute another api call
        result = jira_req('GET', 'rest/api/latest/project', resp_type='json')

        # Jira's response changed to a list of projects from version 9.0.0
        projects_lst = list(filter(
            lambda x: x.get('key').lower() == project_key.lower() or x.get('name').lower() == project_name.lower(),
            result))

        # Filtering should give us a list with one project, only one project should match the filter's conditions
        if projects_lst:
            return projects_lst[0].get('id')

    # Jira used to respond with a dictionary with the 'projects' key until version 9.0.0
    if isinstance(result, dict):
        for project in result.get('projects', []):
            if project_key.lower() == project.get('key').lower() or project_name.lower() == project.get('name').lower():
                return project.get('id')

    return_error('Project not found')

def get_issue_fields(issue_creating=False, mirroring=False, **issue_args):
    """
    refactor issues's argument as received from demisto into jira acceptable format, and back.
    :param issue_creating: flag that indicates this function is called when creating an issue
    :param issue_args: issue argument
    """
    issue = {}  # type: dict
    if 'issue_json' in issue_args:
        try:
            issue = json.loads(issue_args['issue_json'], strict=False)
        except TypeError as te:
            demisto.debug(str(te))
            return_error("issueJson must be in a valid json format")
    elif 'issueJson' in issue_args:
        try:
            issue = json.loads(issue_args['issueJson'], strict=False)
        except TypeError as te:
            demisto.debug(str(te))
            return_error("issueJson must be in a valid json format")

    if not issue.get('fields'):
        issue['fields'] = {}

    if mirroring:
        for field_name in issue_args:
            if field_name and field_name.startswith('customfield'):
                issue['fields'][field_name] = issue_args[field_name]

    if not issue['fields'].get('issuetype') and issue_creating:
        issue['fields']['issuetype'] = {}

    if issue_args.get('summary'):
        issue['fields']['summary'] = issue_args['summary']

    if not issue['fields'].get('project') and (issue_args.get('projectKey') or issue_args.get('projectName')):
        issue['fields']['project'] = {}

    if issue_args.get('projectKey'):
        issue['fields']['project']['key'] = issue_args.get('projectKey', '')
    if issue_args.get('projectName'):
        issue['fields']['project']['name'] = issue_args.get('projectName', '')

    if issue_creating:
        # make sure the key & name are right, and get the corresponding project id & key
        project_id = get_project_id(issue['fields'].get('project', {}).get('key', ''),
                                    issue['fields'].get('project', {}).get('name', ''))
        issue['fields']['project']['id'] = project_id

    if issue_args.get('issueTypeName'):
        issue['fields']['issuetype']['name'] = issue_args['issueTypeName']

    if issue_args.get('issueTypeId'):
        issue['fields']['issuetype']['id'] = issue_args['issueTypeId']

    if issue_args.get('parentIssueId'):
        if not issue['fields'].get('parent'):
            issue['fields']['parent'] = {}
        issue['fields']['parent']['id'] = issue_args['parentIssueId']

    if issue_args.get('parentIssueKey'):
        if not issue['fields'].get('parent'):
            issue['fields']['parent'] = {}
        issue['fields']['parent']['key'] = issue_args['parentIssueKey']

    if issue_args.get('description'):
        issue['fields']['description'] = issue_args['description']

    if issue_args.get('components'):
        components = [{"name": comp} for comp in argToList(issue_args["components"])]
        issue['fields']['components'] = components

    if issue_args.get('security'):
        issue['fields']['security'] = {"name": issue_args['security']}

    if issue_args.get('environment'):
        issue['fields']['environment'] = issue_args['environment']

    if issue_args.get('labels') and isinstance(issue_args.get('labels'), str):
        issue['fields']['labels'] = issue_args['labels'].split(",")

    if issue_args.get('labels') and isinstance(issue_args.get('labels'), list):
        issue['fields']['labels'] = issue_args['labels']

    if issue_args.get('priority'):
        if not issue['fields'].get('priority'):
            issue['fields']['priority'] = {}
        issue['fields']['priority']['name'] = issue_args['priority']

    duedate = issue_args.get('duedate') or issue_args.get('dueDate')
    if duedate:
        issue['fields']['duedate'] = duedate

    if issue_args.get('assignee'):
        if not issue['fields'].get('assignee'):
            issue['fields']['assignee'] = {}
        issue['fields']['assignee']['name'] = issue_args['assignee']

    if issue_args.get('assignee_id'):
        if not issue['fields'].get('assignee'):
            issue['fields']['assignee'] = {}
        issue['fields']['assignee']['accountId'] = issue_args['assignee_id']

    if issue_args.get('reporter_id'):
        if not issue['fields'].get('reporter'):
            issue['fields']['reporter'] = {}
        issue['fields']['reporter']['accountId'] = issue_args['reporter_id']

    if issue_args.get('reporter'):
        if not issue['fields'].get('reporter'):
            issue['fields']['reporter'] = {}
        issue['fields']['reporter']['name'] = issue_args['reporter']

    return issue

def get_issue(issue_id, headers=None, expand_links=False, is_update=False, get_attachments=False, extra_fields=None):
    j_res = jira_req('GET', f'rest/api/latest/issue/{issue_id}', resp_type='json')
    if expand_links == "true":
        expand_urls(j_res)

    attachments = demisto.get(j_res, 'fields.attachment')  # list of all attachments
    # handle issues were we allowed incorrect values of true
    if get_attachments == "true" or get_attachments == "\"true\"":
        get_attachments = True
    else:
        get_attachments = False

    if get_attachments and attachments:
        for attachment in attachments:
            filename, attachments_zip = get_attachment_data(attachment)
            demisto.results(fileResult(filename=filename, data=attachments_zip))

    md_and_context = generate_md_context_get_issue(j_res, extra_fields=extra_fields)
    human_readable = tableToMarkdown(demisto.command(), md_and_context['md'], argToList(headers))
    if is_update:
        human_readable += f'Issue #{issue_id} was updated successfully'

    contents = j_res
    outputs = {'Ticket(val.Id == obj.Id)': md_and_context['context']}

    return human_readable, outputs, contents

def issue_query_command(query, start_at='', max_results=None, headers='', extra_fields=None):
    nofields: set = set()

    j_res = run_query(query, start_at, max_results, extra_fields, nofields)
    if not j_res:
        outputs = contents = {}
        human_readable = 'No issues matched the query.'
    else:
        issues = demisto.get(j_res, 'issues')
        md_and_context = generate_md_context_get_issue(issues, extra_fields, nofields)
        human_readable = tableToMarkdown(demisto.command(), t=md_and_context['md'], headers=argToList(headers))
        contents = j_res
        outputs = {'Ticket(val.Id == obj.Id)': md_and_context['context']}

    return human_readable, outputs, contents

def create_issue_command():
    url = 'rest/api/latest/issue'
    issue = get_issue_fields(issue_creating=True, **demisto.args())
    j_res = jira_req('POST', url, json.dumps(issue), resp_type='json')

    md_and_context = generate_md_context_create_issue(j_res, project_key=demisto.getArg('projectKey'),
                                                      project_name=demisto.getArg('projectName'))
    human_readable = tableToMarkdown(demisto.command(), md_and_context['md'], "")
    contents = j_res
    outputs = md_and_context['context']
    return_outputs(readable_output=human_readable, outputs=outputs, raw_response=contents)

def edit_issue_command(issue_id, mirroring=False, headers=None, status=None, transition=None, **kwargs):
    issue = get_issue_fields(mirroring=mirroring, **kwargs)
    if status and transition:
        return_error("Please provide only status or transition, but not both.")
    elif status:
        edit_status(issue_id, status, issue)
    elif transition:
        edit_transition(issue_id, transition, issue)
    else:
        url = f'rest/api/latest/issue/{issue_id}/'
        jira_req('PUT', url, json.dumps(issue))
    return get_issue(issue_id, headers, is_update=True)

def append_to_field_command(issue_id, field_json, headers=None):
    issue = jira_req('GET', f'rest/api/latest/issue/{issue_id}', resp_type='json')
    fields = json.loads(field_json, strict=False)
    new_data = {}
    for field in fields:
        field_type = __get_field_type(field)
        if not field_type:
            raise DemistoException(f"field {field} could not be updated.")

        if field_type == 'Field Not Found':
            raise DemistoException(f'Could not identify field {field}. Make sure it was entered with correct field ID.')

        current_data_in_field = issue.get('fields', {}).get(field)
        if not current_data_in_field:
            new_data[field] = __create_value_by_type(field_type, fields[field])
        else:
            new_data[field] = __add_value_by_type(field_type, current_data_in_field, fields[field])

    _update_fields(issue_id, new_data)

    return get_issue(issue_id, headers, is_update=True)

def _update_fields(issue_id, new_data):
    url = f'rest/api/latest/issue/{issue_id}/'
    if new_data:
        jira_req('PUT', url, json.dumps({'fields': new_data}))

def get_field_command(issue_id, field):
    fields = argToList(field)
    return get_issue(issue_id, extra_fields=fields, is_update=False)

def __get_field_type(field_id):
    fields = jira_req('GET', 'rest/api/2/field')
    field_data_filter = filter(lambda x: x.get('id') == field_id, fields.json())
    try:
        field_data = next(field_data_filter)
        return field_data.get('schema', {}).get('type')
    except StopIteration:
        return 'Field Not Found'

def __add_value_by_type(type, current_value, new_value):
    if type == 'string':
        new_val = current_value + "," + new_value
    elif type == 'array':
        new_val = current_value + [new_value]
    else:
        raise DemistoException(f"Command only support string or array-typed fields. Field given is typed {type}")
    return new_val

def __create_value_by_type(type, value):
    if type == 'string':
        return str(value)
    elif type == 'array':
        return [value]
    else:
        raise DemistoException(f"Command only support string or array-typed fields. Field given is typed {type}")

def edit_status(issue_id, status, issue):
    # check for all authorized transitions available for this user
    # if the requested transition is available, execute it.
    if not issue:
        issue = {}
    j_res = list_transitions_data_for_issue(issue_id)
    transitions = [transition.get('name') for transition in j_res.get('transitions')]
    for i, transition in enumerate(transitions):
        if transition.lower() == status.lower():
            url = f'rest/api/latest/issue/{issue_id}/transitions?expand=transitions.fields'
            issue['transition'] = {"id": str(j_res.get('transitions')[i].get('id'))}
            return jira_req('POST', url, json.dumps(issue))

    return_error(f'Status "{status}" not found. \nValid transitions are: {transitions} \n')

def list_transitions_data_for_issue(issue_id):
    """
    This function performs the API call for getting a list of all possible transitions for a given issue.
    :param issue_id: The ID of the issue.
    :return: API raw response.
    """
    url = f'rest/api/2/issue/{issue_id}/transitions'
    return jira_req('GET', url, resp_type='json')

def edit_transition(issue_id, transition_name, issue):
    """
    This function changes a transition for a given issue.
    :param issue_id: The ID of the issue.
    :param transition_name: The name of the new transition.
    :return: None
    """
    if issue is None:
        issue = {}
    j_res = list_transitions_data_for_issue(issue_id)
    transitions_data = j_res.get('transitions')
    for transition in transitions_data:
        if transition.get('name') == transition_name:
            url = f'rest/api/latest/issue/{issue_id}/transitions?expand=transitions.fields'
            issue['transition'] = {"id": transition.get("id")}
            return jira_req('POST', url, json.dumps(issue))

    return_error(f'Transitions "{transition_name}" not found. \nValid transitions are: {transitions_data} \n')

def list_transitions_command(args):
    """
    This command list all possible transitions for a given issue.
    :param args: args['issueId']: The ID of the issue.
    :return: CommandResults object with the list of transitions
    """
    issue_id = args.get('issueId')
    transitions_data_list = list_transitions_data_for_issue(issue_id)
    transitions_names = [transition.get('name') for transition in transitions_data_list.get('transitions')]
    readable_output = tableToMarkdown(
        'List Transitions:', transitions_names, headers=['Transition Name']
    )
    outputs = {'ticketId': issue_id,
               'transitions': transitions_names
               }
    return CommandResults(raw_response=transitions_names, readable_output=readable_output,
                          outputs_prefix="Ticket.Transitions", outputs_key_field="ticketId", outputs=outputs)

def get_comments_command(issue_id):
    url = f'rest/api/latest/issue/{issue_id}/comment'
    body = jira_req('GET', url, resp_type='json')
    comments = []
    if body.get("comments"):
        for comment in body.get("comments"):
            comments.append({
                'Comment': comment.get("body"),
                'User': demisto.get(comment, 'updateAuthor.name'),
                'Created': comment.get("created")
            })

        human_readable = tableToMarkdown("Comments", comments)
        contents = body
        outputs = {'Ticket(val.Id == obj.Id)': {'Id': issue_id, "Comment": comments}}
        return human_readable, outputs, contents

    else:
        return 'No comments were found in the ticket', None, None

def add_comment(issue_id, comment, visibility=''):
    url = f'rest/api/latest/issue/{issue_id}/comment'
    comment = {
        "body": comment
    }
    if visibility:
        comment["visibility"] = {
            "type": "role",
            "value": visibility
        }
    return jira_req('POST', url, json.dumps(comment), resp_type='json')

def add_comment_command(issue_id, comment, visibility=''):
    data = add_comment(issue_id, comment, visibility)
    md_list = []
    if not isinstance(data, list):
        data = [data]
    for element in data:
        md_obj = {
            'id': demisto.get(element, 'id'),
            'key': demisto.get(element, 'updateAuthor.key'),
            'comment': demisto.get(element, 'body'),
            'ticket_link': demisto.get(element, 'self')
        }
        md_list.append(md_obj)

    human_readable = tableToMarkdown(demisto.command(), md_list, "")
    contents = data
    return_outputs(readable_output=human_readable, outputs={}, raw_response=contents)

def issue_upload_command(issue_id, upload, attachment_name=None):
    j_res = upload_file(upload, issue_id, attachment_name)
    md = generate_md_upload_issue(j_res, issue_id)
    human_readable = tableToMarkdown(demisto.command(), md, "")
    contents = j_res
    return_outputs(readable_output=human_readable, outputs={}, raw_response=contents)

def upload_file(entry_id, issue_id, attachment_name=None):
    file_name, file_bytes = get_file(entry_id)
    return jira_req(
        method='POST',
        resource_url=f'rest/api/latest/issue/{issue_id}/attachments',
        headers={
            'X-Atlassian-Token': 'no-check'
        },
        files={'file': (attachment_name or file_name, file_bytes)},
        resp_type='json'
    )

def get_file(entry_id):
    get_file_path_res = demisto.getFilePath(entry_id)
    file_path = get_file_path_res["path"]
    file_name = get_file_path_res["name"]
    with open(file_path, 'rb') as f:
        file_bytes = f.read()
    return file_name, file_bytes

def add_link_command(issue_id, title, url, summary=None, global_id=None, relationship=None,
                     application_type=None, application_name=None):
    req_url = f'rest/api/latest/issue/{issue_id}/remotelink'
    link = {
        "object": {
            "url": url,
            "title": title
        }
    }

    if summary:
        link['summary'] = summary
    if global_id:
        link['globalId'] = global_id
    if relationship:
        link['relationship'] = relationship
    if application_type or application_name:
        link['application'] = {}
    if application_type:
        link['application']['type'] = application_type
    if application_name:
        link['application']['name'] = application_name

    data = jira_req('POST', req_url, json.dumps(link), resp_type='json')
    md_list = []
    if not isinstance(data, list):
        data = [data]
    for element in data:
        md_obj = {
            'id': demisto.get(element, 'id'),
            'key': demisto.get(element, 'updateAuthor.key'),
            'comment': demisto.get(element, 'body'),
            'ticket_link': demisto.get(element, 'self')
        }
        md_list.append(md_obj)
    human_readable = tableToMarkdown(demisto.command(), md_list, "", removeNull=True)

    return_outputs(readable_output=human_readable, outputs={}, raw_response=data)

def delete_issue_command(issue_id_or_key):
    url = f'rest/api/latest/issue/{issue_id_or_key}'
    issue = get_issue_fields(**demisto.args())
    result = jira_req('DELETE', url, json.dumps(issue))
    if result.status_code == 204:
        demisto.results('Issue deleted successfully.')
    else:
        demisto.results('Failed to delete issue.')

def test_module() -> str:
    """
    Performs basic get request to get item samples
    """
    user_data = jira_req('GET', 'rest/api/latest/myself', resp_type='json')
    if demisto.params().get('isFetch'):
        run_query(demisto.getParam('query'), '', max_results=1)

    if not user_data.get('active'):
        raise Exception(f'Test module for Jira failed for the configured parameters.'
                        f'please Validate that the user is active. Response: {str(user_data)}')
    outgoing_mirror = demisto.params().get('outgoing_mirror')
    if outgoing_mirror:
        try:
            custom_fields = get_custom_fields()
            if custom_fields is None:
                return_warning("Test module has finished successfully!."
                               "Please Note: There was a problem getting the list of custom fields for mirror "
                               "outgoing incidents.")
        except Exception as e:
            return_warning("Test module has finished successfully!."
                           f" Please Note: There was a problem getting the list of custom fields for mirror outgoing "
                           f"incidents.\n The error is:{e}.")

    return 'ok'

def get_entries_for_fetched_incident(ticket_id, should_get_comments, should_get_attachments):
    """
    Get entries for incident
    :param ticket_id: the remote system id of the ticket
    :param should_get_comments: if 'True', return ticket's comments
    :param should_get_attachments: if 'True', return ticket's attachments
    :return: incident's entries.
    """
    entries: dict = {'comments': [], 'attachments': []}
    try:
        _, _, raw_response = get_issue(issue_id=ticket_id)
        entries = get_incident_entries(raw_response, '', False, should_get_comments, should_get_attachments)
    except Exception as e:
        demisto.debug(f'could not get attachments for {ticket_id} while fetch this incident because: {str(e)}')
    finally:
        return entries

def fetch_incidents(query, id_offset, should_get_attachments, should_get_comments, should_mirror_in, should_mirror_out,
                    comment_tag, attachment_tag, fetch_by_created=None):
    last_run = demisto.getLastRun()
    demisto.debug(f'last_run: {last_run}' if last_run else 'last_run is empty')
    last_created_time = ''
    if last_run:
        id_offset = last_run.get('idOffset') or ''
        last_created_time = last_run.get('lastCreatedTime') or ''
    if not id_offset:
        id_offset = 0

    incidents, max_results = [], 50
    if fetch_by_created and last_created_time:
        last_issue_time = parse(last_created_time)
        assert last_issue_time is not None, f'could not parse {last_created_time}'
        minute_to_fetch = last_issue_time - timedelta(minutes=2)
        formatted_minute_to_fetch = minute_to_fetch.strftime('%Y-%m-%d %H:%M')
        query = f'{query} AND created>=\"{formatted_minute_to_fetch}\"'
    else:
        if id_offset:
            query = f'{query} AND id >= {id_offset} ORDER BY id ASC'
        if fetch_by_created:
            query = f'{query} AND created>-1m'

    res = run_query(query, '', max_results)
    if res:
        curr_id = int(id_offset)
        for ticket in res.get('issues'):
            ticket_id = int(ticket.get('id'))
            ticket_created = ticket.get('fields', {}).get('created', '')
            if ticket_id <= curr_id:
                continue
            if ticket_id > int(id_offset):
                id_offset = ticket_id
                last_created_time = ticket_created
            incidents.append(create_incident_from_ticket(ticket, should_get_attachments, should_get_comments,
                                                         should_mirror_in, should_mirror_out, comment_tag,
                                                         attachment_tag))

    demisto.setLastRun({'idOffset': id_offset, 'lastCreatedTime': last_created_time})
    return incidents

def get_attachment_data(attachment):
    """
    Get attachments content
    :param attachment: attachment metadata
    :return: attachment name and content
    """
    attachment_url = attachment.get('content')
    filename = attachment.get('filename')
    attachments_zip = jira_req(method='GET', resource_url=attachment_url, link=True).content

    return filename, attachments_zip

def get_attachments(attachments, incident_modified_date, only_new=True):
    """
    Get incident attachments as fileResults objects
    :param attachments: the issue's attachments
    :param incident_modified_date: the date the incident was last updated
    :param only_new: if 'True', getting only attachments that was added after the incident_modified_date
    :return: a list of fileResults
    """
    file_results = []
    # list of all attachments
    if attachments:
        if not only_new:
            for attachment in attachments:
                filename, attachments_zip = get_attachment_data(attachment)
                file_results.append(fileResult(filename=filename, data=attachments_zip))
        else:
            for attachment in attachments:
                attachment_modified_date: datetime = \
                    parse(dict_safe_get(attachment, ['created'], "", str))  # type: ignore
                if incident_modified_date < attachment_modified_date:
                    filename, attachments_zip = get_attachment_data(attachment)
                    file_results.append(fileResult(filename=filename, data=attachments_zip))
    return file_results

def get_comments(comments, incident_modified_date, only_new=True):
    """
    Get issue's comments
    :param comments: the issue's comments
    :param incident_modified_date: the date the incident was last updated
    :param only_new: if 'True', getting only comments that was added after the incident_modified_date
    :return: a list of comments
    """
    if not only_new:
        return comments
    else:
        returned_comments = []
        for comment in comments:
            comment_modified_date: datetime = parse(dict_safe_get(comment, ['updated'], "", str))  # type: ignore
            if incident_modified_date < comment_modified_date:
                returned_comments.append(comment)
        return returned_comments

def get_incident_entries(issue, incident_modified_date, only_new=True, should_get_comments=True,
                         should_get_attachments=True):
    """
    This function get comments and attachments from Jira Ticket, if specified, for a Jira incident.
    :param issue: the incident to get its entries
    :param incident_modified_date: when the incident was last modified
    :param only_new: if 'True' it gets only entries that were added after the incident was last modified
    :param should_get_comments: if 'True', the returned entries will contain comments
    :param should_get_attachments: if 'True' the returned entries will contain attachments
    :return: the incident's comments and attachments
    """
    entries: dict = {'comments': [], 'attachments': []}
    if should_get_comments:
        _, _, comments_content = get_comments_command(issue['id'])
        if comments_content:
            raw_comments_content = comments_content
            commands = get_comments(raw_comments_content.get('comments', []), incident_modified_date, only_new)
            entries['comments'] = commands
    if should_get_attachments:
        attachments = demisto.get(issue, 'fields.attachment')
        if attachments:
            file_results = get_attachments(attachments, incident_modified_date, only_new)
            if file_results:
                entries['attachments'] = file_results
    return entries

def get_mapping_fields_command() -> GetMappingFieldsResponse:
    """
     this command pulls the remote schema for the different incident types, and their associated incident fields,
     from the remote system.
    :return: A list of keys you want to map
    """
    jira_incident_type_scheme = SchemeTypeMapping(type_name=JIRA_INCIDENT_TYPE_NAME)
    custom_fields = get_custom_fields()
    ISSUE_INCIDENT_FIELDS.update(custom_fields)
    for argument, description in ISSUE_INCIDENT_FIELDS.items():
        jira_incident_type_scheme.add_field(name=argument, description=description)

    mapping_response = GetMappingFieldsResponse()
    mapping_response.add_scheme_type(jira_incident_type_scheme)

    return mapping_response

def handle_incoming_closing_incident(incident_data):
    """
    This function creates an object for issues with status 'Done' in order to close its incident when getting remote
     data
    :param incident_data: the data of an incident
    :return: the object using to close the incident in Demito
    """
    closing_entry: dict = {}
    if incident_data.get('fields').get('status').get('name') == 'Done':
        demisto.debug(f"Closing Jira issue {incident_data.get('id')}")
        closing_entry = {
            'Type': EntryType.NOTE,
            'Contents': {
                'dbotIncidentClose': True,
                'closeReason': JIRA_RESOLVE_REASON,
            },
            'ContentsFormat': EntryFormat.JSON
        }
    return closing_entry

def update_remote_system_command(args):
    """ Mirror-out data that is in Demito into Jira issue

    Notes:
        1. Documentation on mirroring - https://xsoar.pan.dev/docs/integrations/mirroring_integration

    Args:
        args: A dictionary contains the next data regarding a modified incident: data, entries, incident_changed,
         remote_incident_id, inc_status, delta

    Returns: The incident id that was modified.
    """
    remote_args = UpdateRemoteSystemArgs(args)
    entries = remote_args.entries
    remote_id = remote_args.remote_incident_id
    demisto.debug(
        f'Update remote system check if need to update: remoteId: {remote_id}, incidentChanged: '
        f'{remote_args.incident_changed}, data:'
        f' {remote_args.data}, entries: {entries}')
    try:
        if remote_args.delta and remote_args.incident_changed:
            demisto.debug(f'Got the following delta keys {str(list(remote_args.delta.keys()))} to update Jira '
                          f'incident {remote_id}')
            # take the val from data as it's the updated value
            delta = {k: remote_args.data[k] for k in remote_args.delta.keys()}
            edit_issue_command(remote_id, mirroring=True, **delta)

        else:
            demisto.debug(f'Skipping updating remote incident fields [{remote_id}] '
                          f'as it is not new nor changed')

        if entries:
            for entry in entries:
                demisto.debug(f'Sending entry {entry.get("id")}, type: {entry.get("type")}')
                if entry.get('type') == 3:
                    demisto.debug('Add new file\n')
                    path_res = demisto.getFilePath(entry.get('id'))
                    file_name = path_res.get('name')
                    upload_file(entry.get('id'), remote_id, file_name)
                else:  # handle comments
                    demisto.debug('Add new comment\n')
                    add_comment(remote_id, str(entry.get('contents', '')))
    except Exception as e:
        demisto.error(f"Error in Jira outgoing mirror for incident {remote_args.remote_incident_id} \n"
                      f"Error message: {str(e)}")
    finally:
        return remote_id

def get_user_info_data():
    """
    This function returns details for a current user in order to get timezone.
    :return: API response
    """
    HEADERS['Accept'] = "application/json"
    return requests.request(method='GET', url=BASE_URL + 'rest/api/latest/myself', headers=HEADERS, verify=USE_SSL,
                            auth=get_auth())

def get_modified_remote_data_command(args):
    """
    available from Cortex XSOAR version 6.1.0. This command queries for incidents that were modified since the last
    update. If the command is implemented in the integration, the get-remote-data command will only be performed on
    incidents returned from this command, rather than on all existing incidents.
    :param args: args['last_update']: Date string represents the last time we retrieved modified incidents for this
     integration.
    :return: GetModifiedRemoteDataResponse: this is the object that maintains a list of incident ids to run
     'get-remote-data' on.
    """
    remote_args = GetModifiedRemoteDataArgs(args)
    modified_issues_ids = []
    HEADERS['Accept'] = "application/json"
    try:
        res = get_user_info_data()
    except Exception as e:
        demisto.error(f'Could not get Jira\'s timezone for get-modified-remote-data. failed because: {e}')
    else:
        if res.status_code == 200:
            timezone_name = res.json().get('timeZone')
            if not timezone_name:
                demisto.error(f'Could not get Jira\'s time zone for get-modified-remote-data.Got unexpected reason:'
                              f' {res.json()}')
            last_update_date = parse(remote_args.last_update, settings={'TIMEZONE': timezone_name})
            assert last_update_date is not None, f'could not parse {remote_args.last_update}'
            last_update: str = last_update_date \
                .strftime('%Y-%m-%d %H:%M')
            demisto.debug(f'Performing get-modified-remote-data command. Last update is: {last_update}')
            _, _, context = issue_query_command(f'updated > "{last_update}"', max_results=100)
            modified_issues = context.get('issues', [])
            modified_issues_ids = [issue.get('id') for issue in modified_issues if issue.get('id')]
            demisto.debug(f'Performing get-modified-remote-data command. Issue IDs to update in XSOAR:'
                          f' {modified_issues_ids}')
        else:
            demisto.error(f'Could not get Jira\'s time zone for get-modified-remote-data. status code:'
                          f' {res.status_code}.'
                          f' reason: {res.reason}')
    finally:
        return GetModifiedRemoteDataResponse(modified_issues_ids)

def get_remote_data_command(args) -> GetRemoteDataResponse:
    """ Mirror-in data to incident from Jira into XSOAR 'jira issue' incident.

    Notes:
        1. Documentation on mirroring - https://xsoar.pan.dev/docs/integrations/mirroring_integration

    Args:
        args:
            id: Remote incident id.
            lastUpdate: Server last sync time with remote server.

    Returns:
        GetRemoteDataResponse: Structured incident response.
    """
    incident_update = {}
    parsed_entries = []
    parsed_args = GetRemoteDataArgs(args)
    try:
        # Get raw response on issue ID
        _, _, issue_raw_response = get_issue(issue_id=parsed_args.remote_incident_id)
        demisto.info('get remote data')
        # Timestamp - Issue last modified in jira server side
        jira_modified_date: datetime = \
            parse(dict_safe_get(issue_raw_response, ['fields', 'updated'], "", str))  # type: ignore
        # Timestamp - Issue last sync in demisto server side
        incident_modified_date: datetime = parse(parsed_args.last_update)  # type: ignore
        # Update incident only if issue modified in Jira server-side after the last sync
        demisto.info(f"jira_modified_date{jira_modified_date}")
        demisto.info(f"incident_modified_date{incident_modified_date}")
        if jira_modified_date > incident_modified_date:
            demisto.info('updating remote data')
            incident_update = issue_raw_response

            demisto.info(f"\nUpdate incident:\n\tIncident name: Jira issue {issue_raw_response.get('id')}\n\t"
                         f"Reason: Issue modified in remote.\n\tIncident Last update time: {incident_modified_date}"
                         f"\n\tRemote last updated time: {jira_modified_date}\n")
            demisto.info(f"\n raw incident: {issue_raw_response}\n")

            closed_issue = handle_incoming_closing_incident(incident_update)
            if closed_issue:
                demisto.info(
                    f'Close incident with ID: {parsed_args.remote_incident_id} this issue was marked as "Done"')
                incident_update['in_mirror_error'] = ''
                return GetRemoteDataResponse(incident_update, [closed_issue])

            entries = get_incident_entries(issue_raw_response, incident_modified_date)

            for comment in entries['comments']:
                parsed_entries.append({
                    'Type': EntryType.NOTE,
                    'Contents': comment.get('body', ''),
                    'ContentsFormat': EntryFormat.TEXT,
                    # 'Tags': ['comment'],  # the list of tags to add to the entry
                    'Note': True
                })
            for attachment in entries['attachments']:
                parsed_entries.append(attachment)
        if parsed_entries:
            demisto.info(f'Update the next entries: {parsed_entries}')

        incident_update['in_mirror_error'] = ''
        return GetRemoteDataResponse(incident_update, parsed_entries)

    except Exception as e:
        demisto.info(f"Error in Jira incoming mirror for incident {parsed_args.remote_incident_id} \n"
                     f"Error message: {str(e)}")

        if "Rate limit exceeded" in str(e):
            return_error("API rate limit")

        if incident_update:
            incident_update['in_mirror_error'] = str(e)
        else:
            incident_update = {
                'id': parsed_args.remote_incident_id,
                'in_mirror_error': str(e)
            }
        return GetRemoteDataResponse(
            mirrored_object=incident_update,
            entries=[]
        )

def main():
    demisto.debug(f'Command being called is {demisto.command()}')
    fetch_query = demisto.params().get('query')
    id_offset = demisto.params().get('idOffset')
    fetch_attachments = demisto.params().get('fetch_attachments')
    fetch_comments = demisto.params().get('fetch_comments')
    incoming_mirror = demisto.params().get("incoming_mirror")
    outgoing_mirror = demisto.params().get('outgoing_mirror')
    comment_tag = demisto.params().get('comment_tag')
    attachment_tag = demisto.params().get('file_tag')
    fetch_by_created = demisto.params().get('fetchByCreated')
    try:
        # Remove proxy if not set to true in params
        handle_proxy()

        if demisto.command() == 'test-module':
            # This is the call made when pressing the integration test button.
            demisto.results(test_module())

        elif demisto.command() == 'fetch-incidents':
            # Set and define the fetch incidents command to run after activated via integration settings.
            incidents = fetch_incidents(fetch_query, id_offset, fetch_attachments, fetch_comments, incoming_mirror,
                                        outgoing_mirror, comment_tag, attachment_tag, fetch_by_created)
            demisto.incidents(incidents)
        elif demisto.command() == 'jira-get-issue':
            human_readable, outputs, raw_response = get_issue(**snakify(demisto.args()))
            return_outputs(human_readable, outputs, raw_response)

        elif demisto.command() == 'jira-issue-query':
            human_readable, outputs, raw_response = issue_query_command(**snakify(demisto.args()))
            return_outputs(human_readable, outputs, raw_response)

        elif demisto.command() == 'jira-create-issue':
            create_issue_command()

        elif demisto.command() == 'jira-edit-issue':
            human_readable, outputs, raw_response = edit_issue_command(**snakify(demisto.args()))
            return_outputs(human_readable, outputs, raw_response)

        elif demisto.command() == 'jira-append-to-field':
            human_readable, outputs, raw_response = append_to_field_command(**snakify(demisto.args()))
            return_outputs(human_readable, outputs, raw_response)

        elif demisto.command() == 'jira-get-specific-field':
            human_readable, outputs, raw_response = get_field_command(**snakify(demisto.args()))
            return_outputs(human_readable, outputs, raw_response)

        elif demisto.command() == 'jira-get-comments':
            human_readable, outputs, raw_response = get_comments_command(**snakify(demisto.args()))
            return_outputs(readable_output=human_readable, outputs=outputs, raw_response=raw_response)

        elif demisto.command() == 'jira-issue-add-comment':
            add_comment_command(**snakify(demisto.args()))

        elif demisto.command() == 'jira-issue-upload-file':
            issue_upload_command(**snakify(demisto.args()))

        elif demisto.command() == 'jira-issue-add-link':
            add_link_command(**snakify(demisto.args()))

        elif demisto.command() == 'jira-delete-issue':
            delete_issue_command(**snakify(demisto.args()))

        elif demisto.command() == 'jira-get-id-offset':
            get_id_offset()

        elif demisto.command() == 'get-mapping-fields':
            return_results(get_mapping_fields_command())

        elif demisto.command() == 'update-remote-system':
            return_results(update_remote_system_command(demisto.args()))

        elif demisto.command() == 'get-remote-data':
            return_results(get_remote_data_command(demisto.args()))

        elif demisto.command() == 'jira-get-id-by-attribute':
            return_results(get_account_id_from_attribute(**demisto.args()))

        elif demisto.command() == 'jira-list-transitions':
            return_results(list_transitions_command(demisto.args()))
        elif demisto.command() == 'get-modified-remote-data':
            return_results(get_modified_remote_data_command(demisto.args()))
        else:
            raise NotImplementedError(f'{COMMAND_NOT_IMPELEMENTED_MSG}: {demisto.command()}')

    except Exception as err:
        if isinstance(err, NotImplementedError) and COMMAND_NOT_IMPELEMENTED_MSG in str(err):
            raise
        return_error(str(err))

    finally:
        LOG.print_log()

if __name__ in ["__builtin__", "builtins", '__main__']:
    main()