/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.ofbiz.base.util.cache;

import static org.apache.ofbiz.base.test.GenericTestCaseBase.useAllMemory;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.greaterThan;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import org.apache.ofbiz.base.util.UtilMisc;
import org.apache.ofbiz.base.util.UtilObject;
import org.junit.Test;

@SuppressWarnings("serial")
public class UtilCacheTests implements Serializable {
    abstract static class Change {
        private int count = 1;

        public int getCount() {
            return count;
        }

        public void incCount() {
            count += 1;
        }
    }

    protected static final class Removal<V> extends Change {
        private final V oldValue;

        protected Removal(V oldValue) {
            this.oldValue = oldValue;
        }

        @Override
        public int hashCode() {
            return UtilObject.doHashCode(oldValue);
        }

        @Override
        public boolean equals(Object o) {
            if (o instanceof Removal<?>) {
                Removal<?> other = (Removal<?>) o;
                return Objects.equals(oldValue, other.oldValue);
            }
            return false;
        }
    }

    protected static final class Addition<V> extends Change {
        private final V newValue;

        protected Addition(V newValue) {
            this.newValue = newValue;
        }

        @Override
        public int hashCode() {
            return UtilObject.doHashCode(newValue);
        }

        @Override
        public boolean equals(Object o) {
            if (o instanceof Addition<?>) {
                Addition<?> other = (Addition<?>) o;
                return Objects.equals(newValue, other.newValue);
            }
            return false;
        }
    }

    protected static final class Update<V> extends Change {
        private final V newValue;
        private final V oldValue;

        protected Update(V newValue, V oldValue) {
            this.newValue = newValue;
            this.oldValue = oldValue;
        }

        @Override
        public int hashCode() {
            return UtilObject.doHashCode(newValue) ^ UtilObject.doHashCode(oldValue);
        }

        @Override
        public boolean equals(Object o) {
            if (o instanceof Update<?>) {
                Update<?> other = (Update<?>) o;
                if (!Objects.equals(newValue, other.newValue)) {
                    return false;
                }
                return Objects.equals(oldValue, other.oldValue);
            }
            return false;
        }
    }

    private static final class Listener<K, V> implements CacheListener<K, V> {
        private Map<K, Set<Change>> changeMap = new HashMap<>();

        private void add(K key, Change change) {
            Set<Change> changeSet = changeMap.get(key);
            if (changeSet == null) {
                changeSet = new HashSet<>();
                changeMap.put(key, changeSet);
            }
            for (Change checkChange: changeSet) {
                if (checkChange.equals(change)) {
                    checkChange.incCount();
                    return;
                }
            }
            changeSet.add(change);
        }

        @Override
        public synchronized void noteKeyRemoval(UtilCache<K, V> cache, K key, V oldValue) {
            add(key, new Removal<>(oldValue));
        }

        @Override
        public synchronized void noteKeyAddition(UtilCache<K, V> cache, K key, V newValue) {
            add(key, new Addition<>(newValue));
        }

        @Override
        public synchronized void noteKeyUpdate(UtilCache<K, V> cache, K key, V newValue, V oldValue) {
            add(key, new Update<>(newValue, oldValue));
        }

        @Override
        public boolean equals(Object o) {
            if (!(o instanceof Listener)) {
                return false;
            }
            Listener<?, ?> other = (Listener<?, ?>) o;
            return changeMap.equals(other.changeMap);
        }

        @Override
        public int hashCode() {
            return super.hashCode();
        }
    }

    private static <K, V> Listener<K, V> createListener(UtilCache<K, V> cache) {
        Listener<K, V> listener = new Listener<>();
        cache.addListener(listener);
        return listener;
    }

    private <K, V> UtilCache<K, V> createUtilCache(int sizeLimit, int maxInMemory, long ttl, boolean useSoftReference) {
        return UtilCache.createUtilCache(getClass().getName(), sizeLimit, maxInMemory, ttl, useSoftReference);
    }

    private static <K, V> void assertUtilCacheSettings(UtilCache<K, V> cache, Integer sizeLimit, Integer maxInMemory,
            Long expireTime, Boolean useSoftReference) {
        if (sizeLimit != null) {
            assertEquals(cache.getName() + ":sizeLimit", sizeLimit.intValue(), cache.getSizeLimit());
        }
        if (maxInMemory != null) {
            assertEquals(cache.getName() + ":maxInMemory", maxInMemory.intValue(), cache.getMaxInMemory());
        }
        if (expireTime != null) {
            assertEquals(cache.getName() + ":expireTime", expireTime.longValue(), cache.getExpireTime());
        }
        if (useSoftReference != null) {
            assertEquals(cache.getName() + ":useSoftReference", useSoftReference.booleanValue(),
                    cache.getUseSoftReference());
        }
        assertEquals("initial empty", true, cache.isEmpty());
        assertEquals("empty keys", Collections.emptySet(), cache.getCacheLineKeys());
        assertEquals("empty values", Collections.emptyList(), cache.values());
        assertSame("find cache", cache, UtilCache.findCache(cache.getName()));
        assertNotSame("new cache", cache, UtilCache.createUtilCache());
    }

    @Test
    public void testCreateUtilCache() {
        String name = getClass().getName();
        assertUtilCacheSettings(UtilCache.createUtilCache(), null, null, null, null);
        assertUtilCacheSettings(UtilCache.createUtilCache(name), null, null, null, null);
        assertUtilCacheSettings(UtilCache.createUtilCache(name, false), null, null, null, Boolean.FALSE);
        assertUtilCacheSettings(UtilCache.createUtilCache(name, true), null, null, null, Boolean.TRUE);
        assertUtilCacheSettings(UtilCache.createUtilCache(5, 15000), 5, null, 15000L, null);
        assertUtilCacheSettings(UtilCache.createUtilCache(name, 6, 16000), 6, null, 16000L, null);
        assertUtilCacheSettings(UtilCache.createUtilCache(name, 7, 17000, false), 7, null, 17000L, Boolean.FALSE);
        assertUtilCacheSettings(UtilCache.createUtilCache(name, 8, 18000, true), 8, null, 18000L, Boolean.TRUE);
        assertUtilCacheSettings(UtilCache.createUtilCache(name, 9, 5, 19000, false), 9, 5, 19000L, Boolean.FALSE);
        assertUtilCacheSettings(UtilCache.createUtilCache(name, 10, 6, 20000, false), 10, 6, 20000L, Boolean.FALSE);
        assertUtilCacheSettings(
                UtilCache.createUtilCache(name, 11, 7, 21000, false, "a", "b"), 11, 7, 21000L, Boolean.FALSE);
        assertUtilCacheSettings(
                UtilCache.createUtilCache(name, 12, 8, 22000, false, "c", "d"), 12, 8, 22000L, Boolean.FALSE);
    }

    public static <K, V> void assertKey(String label, UtilCache<K, V> cache, K key, V value, V other, int size,
            Map<K, V> map) {
        assertNull(label + ":get-empty", cache.get(key));
        assertFalse(label + ":containsKey-empty", cache.containsKey(key));
        V oldValue = cache.put(key, other);
        assertTrue(label + ":containsKey-class", cache.containsKey(key));
        assertEquals(label + ":get-class", other, cache.get(key));
        assertNull(label + ":oldValue-class", oldValue);
        assertEquals(label + ":size-class", size, cache.size());
        oldValue = cache.put(key, value);
        assertTrue(label + ":containsKey-value", cache.containsKey(key));
        assertEquals(label + ":get-value", value, cache.get(key));
        assertEquals(label + ":oldValue-value", other, oldValue);
        assertEquals(label + ":size-value", size, cache.size());
        map.put(key, value);
        assertEquals(label + ":map-keys", map.keySet(), cache.getCacheLineKeys());
        assertThat(label + ":map-values", cache.values(), containsInAnyOrder(map.values().toArray()));
    }

    private static <K, V> void assertHasSingleKey(UtilCache<K, V> cache, K key, V value) {
        assertFalse("is-empty", cache.isEmpty());
        assertEquals("size", 1, cache.size());
        assertTrue("found", cache.containsKey(key));
        assertTrue("validKey", UtilCache.validKey(cache.getName(), key));
        assertFalse("validKey", UtilCache.validKey(":::" + cache.getName(), key));
        assertEquals("get", value, cache.get(key));
        assertEquals("keys", new HashSet<>(UtilMisc.toList(key)), cache.getCacheLineKeys());
        assertEquals("values", UtilMisc.toList(value), cache.values());
    }

    private static <K, V> void assertNoSingleKey(UtilCache<K, V> cache, K key) {
        assertFalse("not-found", cache.containsKey(key));
        assertFalse("validKey", UtilCache.validKey(cache.getName(), key));
        assertNull("no-get", cache.get(key));
        assertNull("remove", cache.remove(key));
        assertTrue("is-empty", cache.isEmpty());
        assertEquals("size", 0, cache.size());
        assertEquals("keys", Collections.emptySet(), cache.getCacheLineKeys());
        assertEquals("values", Collections.emptyList(), cache.values());
    }

    private static void basicTest(UtilCache<String, String> cache) throws Exception {
        Listener<String, String> gotListener = createListener(cache);
        Listener<String, String> wantedListener = new Listener<>();
        for (int i = 0; i < 2; i++) {
            assertTrue("UtilCacheTable.keySet", UtilCache.getUtilCacheTableKeySet().contains(cache.getName()));
            assertSame("UtilCache.findCache", cache, UtilCache.findCache(cache.getName()));
            assertSame("UtilCache.getOrCreateUtilCache", cache, UtilCache.getOrCreateUtilCache(cache.getName(),
                    cache.getSizeLimit(), cache.getMaxInMemory(), cache.getExpireTime(), cache.getUseSoftReference()));

            assertNoSingleKey(cache, "one");
            long origByteSize = cache.getSizeInBytes();

            wantedListener.noteKeyAddition(cache, null, "null");
            assertNull("put", cache.put(null, "null"));
            assertHasSingleKey(cache, null, "null");
            long nullByteSize = cache.getSizeInBytes();
            assertThat(nullByteSize, greaterThan(origByteSize));

            wantedListener.noteKeyRemoval(cache, null, "null");
            assertEquals("remove", "null", cache.remove(null));
            assertNoSingleKey(cache, null);

            wantedListener.noteKeyAddition(cache, "one", "uno");
            assertNull("put", cache.put("one", "uno"));
            assertHasSingleKey(cache, "one", "uno");
            long unoByteSize = cache.getSizeInBytes();
            assertThat(unoByteSize, greaterThan(origByteSize));

            wantedListener.noteKeyUpdate(cache, "one", "single", "uno");
            assertEquals("replace", "uno", cache.put("one", "single"));
            assertHasSingleKey(cache, "one", "single");
            long singleByteSize = cache.getSizeInBytes();
            assertThat(singleByteSize, greaterThan(origByteSize));
            assertThat(singleByteSize, greaterThan(unoByteSize));

            wantedListener.noteKeyRemoval(cache, "one", "single");
            assertEquals("remove", "single", cache.remove("one"));
            assertNoSingleKey(cache, "one");
            assertEquals("byteSize", origByteSize, cache.getSizeInBytes());

            wantedListener.noteKeyAddition(cache, "one", "uno");
            assertNull("put", cache.put("one", "uno"));
            assertHasSingleKey(cache, "one", "uno");

            wantedListener.noteKeyUpdate(cache, "one", "only", "uno");
            assertEquals("replace", "uno", cache.put("one", "only"));
            assertHasSingleKey(cache, "one", "only");

            wantedListener.noteKeyRemoval(cache, "one", "only");
            cache.erase();
            assertNoSingleKey(cache, "one");
            assertEquals("byteSize", origByteSize, cache.getSizeInBytes());

            cache.setExpireTime(100);
            wantedListener.noteKeyAddition(cache, "one", "uno");
            assertNull("put", cache.put("one", "uno"));
            assertHasSingleKey(cache, "one", "uno");

            wantedListener.noteKeyRemoval(cache, "one", "uno");
            Thread.sleep(200);
            assertNoSingleKey(cache, "one");
        }

        assertEquals("get-miss", 10, cache.getMissCountNotFound());
        assertEquals("get-miss-total", 10, cache.getMissCountTotal());
        assertEquals("get-hit", 12, cache.getHitCount());
        assertEquals("remove-hit", 6, cache.getRemoveHitCount());
        assertEquals("remove-miss", 10, cache.getRemoveMissCount());
        cache.removeListener(gotListener);
        assertEquals("listener", wantedListener, gotListener);
        UtilCache.clearCache(cache.getName());
        UtilCache.clearCache(":::" + cache.getName());
    }

    @Test
    public void testSimple() throws Exception {
        UtilCache<String, String> cache = createUtilCache(5, 0, 0, false);
        basicTest(cache);
    }

    @Test
    public void testPutIfAbsent() throws Exception {
        UtilCache<String, String> cache = createUtilCache(5, 5, 2000, false);
        Listener<String, String> gotListener = createListener(cache);
        Listener<String, String> wantedListener = new Listener<>();
        wantedListener.noteKeyAddition(cache, "two", "dos");
        assertNull("putIfAbsent", cache.putIfAbsent("two", "dos"));
        assertHasSingleKey(cache, "two", "dos");
        assertEquals("putIfAbsent", "dos", cache.putIfAbsent("two", "double"));
        assertHasSingleKey(cache, "two", "dos");
        cache.removeListener(gotListener);
        assertEquals("listener", wantedListener, gotListener);
    }

    @Test
    public void testPutIfAbsentAndGet() throws Exception {
        UtilCache<String, String> cache = createUtilCache(5, 5, 2000, false);
        Listener<String, String> gotListener = createListener(cache);
        Listener<String, String> wantedListener = new Listener<>();
        wantedListener.noteKeyAddition(cache, "key", "value");
        wantedListener.noteKeyAddition(cache, "anotherKey", "anotherValue");
        assertNull("no-get", cache.get("key"));
        assertEquals("putIfAbsentAndGet", "value", cache.putIfAbsentAndGet("key", "value"));
        assertHasSingleKey(cache, "key", "value");
        assertEquals("putIfAbsentAndGet", "value", cache.putIfAbsentAndGet("key", "newValue"));
        assertHasSingleKey(cache, "key", "value");
        String anotherValueAddedToCache = new String("anotherValue");
        String anotherValueNotAddedToCache = new String("anotherValue");
        assertEquals(anotherValueAddedToCache, anotherValueNotAddedToCache);
        assertNotSame(anotherValueAddedToCache, anotherValueNotAddedToCache);
        String cachedValue = cache.putIfAbsentAndGet("anotherKey", anotherValueAddedToCache);
        assertSame(cachedValue, anotherValueAddedToCache);
        cachedValue = cache.putIfAbsentAndGet("anotherKey", anotherValueNotAddedToCache);
        assertNotSame(cachedValue, anotherValueNotAddedToCache);
        assertSame(cachedValue, anotherValueAddedToCache);
        cache.removeListener(gotListener);
        assertEquals("listener", wantedListener, gotListener);
    }

    @Test
    public void testChangeMemSize() throws Exception {
        int size = 5;
        long ttl = 2000;
        UtilCache<String, Serializable> cache = createUtilCache(size, size, ttl, false);
        Map<String, Serializable> map = new HashMap<>();
        assertKeyLoop(size, cache, map);
        cache.setMaxInMemory(2);
        assertEquals("cache.size", 2, cache.size());
        map.keySet().retainAll(cache.getCacheLineKeys());
        assertEquals("map-keys", map.keySet(), cache.getCacheLineKeys());
        assertThat("map-values", cache.values(), containsInAnyOrder(map.values().toArray()));
        cache.setMaxInMemory(0);
        assertEquals("map-keys", map.keySet(), cache.getCacheLineKeys());
        assertThat("map-values", cache.values(), containsInAnyOrder(map.values().toArray()));
        for (int i = size * 2; i < size * 3; i++) {
            String s = Integer.toString(i);
            assertKey(s, cache, s, new String(s), new String(":" + s), i - size * 2 + 3, map);
        }
        cache.setMaxInMemory(0);
        assertEquals("map-keys", map.keySet(), cache.getCacheLineKeys());
        assertThat("map-values", cache.values(), containsInAnyOrder(map.values().toArray()));
        cache.setMaxInMemory(size);
        for (int i = 0; i < size * 2; i++) {
            map.remove(Integer.toString(i));
        }
        // Can't compare the contents of these collections, as setting LRU after not
        // having one, means the items that get evicted are essentially random.
        assertEquals("map-keys", map.keySet().size(), cache.getCacheLineKeys().size());
        assertEquals("map-values", map.values().size(), cache.values().size());
    }

    private static void expireTest(UtilCache<String, Serializable> cache, int size, long ttl) throws Exception {
        Map<String, Serializable> map = new HashMap<>();
        assertKeyLoop(size, cache, map);
        Thread.sleep(ttl + 500);
        map.clear();
        for (int i = 0; i < size; i++) {
            String s = Integer.toString(i);
            assertNull("no-key(" + s + ")", cache.get(s));
        }
        assertEquals("map-keys", map.keySet(), cache.getCacheLineKeys());
        assertThat("map-values", cache.values(), containsInAnyOrder(map.values().toArray()));
        assertKeyLoop(size, cache, map);
        assertEquals("map-keys", map.keySet(), cache.getCacheLineKeys());
        assertThat("map-values", cache.values(), containsInAnyOrder(map.values().toArray()));
    }

    private static void assertKeyLoop(int size, UtilCache<String, Serializable> cache, Map<String, Serializable> map) {
        for (int i = 0; i < size; i++) {
            String s = Integer.toString(i);
            assertKey(s, cache, s, new String(s), new String(":" + s), i + 1, map);
        }
    }

    @Test
    public void testExpire() throws Exception {
        UtilCache<String, Serializable> cache = createUtilCache(5, 5, 2000, false);
        expireTest(cache, 5, 2000);
        long start = System.currentTimeMillis();
        useAllMemory();
        long end = System.currentTimeMillis();
        long ttl = end - start + 1000;
        cache = createUtilCache(1, 1, ttl, true);
        expireTest(cache, 1, ttl);
        assertFalse("not empty", cache.isEmpty());
        useAllMemory();
        assertNull("not-key(0)", cache.get("0"));
        assertTrue("empty", cache.isEmpty());
    }
}


var Symbol = require('./_Symbol'),
    copyArray = require('./_copyArray'),
    getTag = require('./_getTag'),
    isArrayLike = require('./isArrayLike'),
    isString = require('./isString'),
    iteratorToArray = require('./_iteratorToArray'),
    mapToArray = require('./_mapToArray'),
    setToArray = require('./_setToArray'),
    stringToArray = require('./_stringToArray'),
    values = require('./values');

/** `Object#toString` result references. */
var mapTag = '[object Map]',
    setTag = '[object Set]';

/** Built-in value references. */
var symIterator = Symbol ? Symbol.iterator : undefined;

/**
 * Converts `value` to an array.
 *
 * @static
 * @since 0.1.0
 * @memberOf _
 * @category Lang
 * @param {*} value The value to convert.
 * @returns {Array} Returns the converted array.
 * @example
 *
 * _.toArray({ 'a': 1, 'b': 2 });
 * // => [1, 2]
 *
 * _.toArray('abc');
 * // => ['a', 'b', 'c']
 *
 * _.toArray(1);
 * // => []
 *
 * _.toArray(null);
 * // => []
 */
function toArray(value) {
  if (!value) {
    return [];
  }
  if (isArrayLike(value)) {
    return isString(value) ? stringToArray(value) : copyArray(value);
  }
  if (symIterator && value[symIterator]) {
    return iteratorToArray(value[symIterator]());
  }
  var tag = getTag(value),
      func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);

  return func(value);
}

module.exports = toArray;


/* THIS CODE IS USELESS until I find a way to use spaces in Makefile
 * variables.  It seemed like a good idea at the time and I'm not deleting
 * it now because I'm a packrat. --Cliff
 */

/*
 * This program combines with bash's IFS variable to provide smarter
 * word splitting than bash normally provides.
 *
 * cflags='-Dthis -Dthat="argument with spaces"'
 * can cause problems when ${cflags} if expanded and word split and
 * becomes these four arguments:
 * -Dthis
 * -Dthat="argument
 * with
 * spaces"
 *
 * So instead use:
 * saveifs="$IFS"
 * cflags=`smartsplit "${cflags}"`
 * IFS=`smartsplit -ifs "${cflags}"`
 * ${cflags}
 * IFS="$saveifs"
 *
 * Ugly, but it's the best thing I thought of in order to allow me to have
 * spaces in my configuration file.
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

/*
 * returns 1 if successful, 0 otherwise.  NOTE: In theory, any character
 * that's not currently in the string could be a separator.  However,
 * empirical evidence suggests that at least under bash 1.14.7.1, control-a
 * will not work as a separator.  So, we try a few specific separators by
 * hand, then try any printable character, then try control-b, then give
 * up.
 */

static int
findsep (const char *str, char *ifsp)
{
  int retval;
  static char nice_separators[] = "@:+";

  retval = 0;

  if (!retval)
    {
      const char *nicep;

      for (nicep = nice_separators; !retval && *nicep; ++nicep)
	{
	  if (!strchr (str, *nicep))
	    {
	      *ifsp = *nicep;
	      retval = 1;
	    }
	}
    }

  if (!retval)
    {
      int c;

      for (c = 0; !retval && c < 255; ++c)
	{
	  if (isprint (c))
	    {
	      if (!strchr (str, c))
		{
		  *ifsp = c;
		  retval = 1;
		}
	    }
	}
    }

  if (!retval)
    if (!strchr (str, 2))
      {
	*ifsp = 2;
	retval = 1;
      }
  return retval;
}

static int
smartsplit (const char *str, char *ifsp, char **strpp)
{
  int retval;

  retval = findsep (str, ifsp);
  if (retval && strpp)
    {
      const char *ip;
      char *op;
      char current_quote;

      *strpp = malloc (strlen (str) + 1);
      current_quote = 0;
      for (ip = str, op = *strpp; *ip; ++ip)
	{
	  if (current_quote)
	    {
	      *op++ = *ip;
	      if (*ip == current_quote)
		current_quote = 0;
	    }
	  else
	    {
	      if (*ip == '\'' || *ip == '"')
		{
		  *op++ = *ip;
		  current_quote = *ip;
		}
	      else if (isspace ((unsigned char) *ip))
		*op++ = *ifsp;
	      else
		*op++ = *ip;
	    }
	}
      *op = 0;
  }

  return retval;
}

static void
output_prog_name (const char *prog)
{
  const char *lastslash;

  lastslash = strrchr (prog, '/');
  fputs (lastslash ? lastslash + 1 : prog, stderr);
}

static void
usage (const char *prog)
{
  fputs ("Usage: ", stderr);
  output_prog_name (prog);
  fputs (" [-ifs] string", stderr);
}

int
main (int argc, char *argv[])
{
  int retval;

  retval = 0;
  switch (argc)
    {
    case 2:
      {
	int success;
	char ifs;
	char *str;

	success = smartsplit (argv[1], &ifs, &str);
	if (success)
	  puts (str);
	else
	  {
	    output_prog_name (argv[0]);
	    fprintf (stderr, ": all separators used\n");
	    retval = 1;
	  }
      }
      break;
    case 3:
      if (strcmp (argv[1], "-ifs") == 0)
	{
	  char ifs;

	  smartsplit (argv[2], &ifs, 0);
	  putchar (ifs);
	}
      else
	{
	  usage (argv[0]);
	  retval = 1;
	}
      break;
    default:
      usage (argv[0]);
      retval = 2;
      break;
    }
  return retval;
}


#Использовать logos

Перем Лог;

#Область Подписки_на_события

#Область Подписка_на_активизацию_плагинов

// Вызывается при начале установке новых подписчиков
//
// Параметры:
//   МенеджерСинхронизации - Объект.МенеджерСинхронизации - ссылка на класс МенеджерСинхронизации
//
Процедура ПриАктивизации(МенеджерСинхронизации) Экспорт

	Лог.Информация("Вызвано событие <ПриАктивизации> для плагина <%1>", Имя());

КонецПроцедуры

#КонецОбласти

#Область Подписка_на_получение_параметров_выполнения

// Вызывается при передаче параметров в МенеджерСинхронизации
//
// Параметры:
//   ПараметрыПодписчиков - Объект.ПараметрыПодписчиков - ссылка на класс ПараметрыПодписчиков
//
// Объект <ПараметрыПодписчиков> реализовывает публичные функции:
// * Функция <Параметр>
// 		Получает и возвращает значение из индекса параметров
//
// 		Параметры:
//   	  * СтрокаИмениПараметра - Строка - имя параметра допустимо указание нескольких имен к параметру через пробел
//                              		  Например, "config --config -c c"
//   	  * ЗначениеПоУмолчанию  - Произвольный - возвращаемое значение в случае отсутствия параметра после получения из индекса
// 		Возвращаемое значение:
//   	  Строка, Число, Булево, Массив, Соответствие, Неопределено - значение параметра
// * Функция <ПолучитьПараметры>
// 		Возвращает используемый индекс параметров
//
// 		Возвращаемое значение:
//   	  Соответствие - соответствие ключей и значение параметров
//
// Примеры:
//   ```
//
//   ОтправлятьМетки = ПараметрыПодписчиков.Параметр("push --push P ОтправлятьМетки", Ложь);
//
//   ```
Процедура ПриПолученииПараметров(ПараметрыПодписчиков) Экспорт

	Лог.Информация("Вызвано событие <ПриПолученииПараметров> для плагина <%1>", Имя());

КонецПроцедуры

#КонецОбласти

#Область Подписки_на_регистрацию_команд_приложения

// Вызывается при регистрации команды приложения
//
// Параметры:
//   ИмяКоманды - Строка - имя регистрируемой команды
//   КлассРеализации - Объект.КомандаПриложения - ссылка на класс <КомандаПриложения>
//
Процедура ПриРегистрацииКомандыПриложения(ИмяКоманды, КлассРеализации) Экспорт

	Лог.Информация("Вызвано событие <ПриРегистрацииКомандыПриложения> для плагина <%1>", Имя());

КонецПроцедуры

#КонецОбласти

#Область Подписки_на_начало_и_окончания_выполнения

// Вызывается перед началом работы менеджера синхронизации
//
// Параметры:
//   ПутьКХранилищу - Строка - полный путь к хранилищу конфигурации
//   КаталогРабочейКопии - Строка - полный путь к рабочему каталогу копии
//
Процедура ПередНачаломВыполнения(ПутьКХранилищу, КаталогРабочейКопии) Экспорт

	Лог.Информация("Вызвано событие <ПередНачаломВыполнения> для плагина <%1>", Имя());

КонецПроцедуры

// Вызывается после завершения работы менеджера синхронизации
//
// Параметры:
//   ПутьКХранилищу - Строка - полный путь к хранилищу конфигурации
//   КаталогРабочейКопии - Строка - полный путь к рабочему каталогу копии
//
Процедура ПослеОкончанияВыполнения(ПутьКХранилищу, КаталогРабочейКопии) Экспорт

	Лог.Информация("Вызвано событие <ПослеОкончанияВыполнения> для плагина <%1>", Имя());

КонецПроцедуры

#КонецОбласти

#Область Подписки_на_получение_таблицы_версий

// Вызывается при получении таблицы версий из хранилища конфигурации
//
// Параметры:
//   ТаблицаВерсий - ТаблицаЗначений - инициализированная таблица с колонками:
//     * Дата                - Дата   - дата версии
//     * НомерВерсии         - Число  - номер версии
// 	   * Комментарий         - Строка - комментарий автора к версии
//     * Автор               - Строка - имя автора версии в хранилище
// 	   * Тэг                 - Строка - метка версии в хранилище
// 	   * ГУИД_Автора         - Строка - уникальный идентификатор автора версии
//     * ПредставлениеАвтора - Строка - представление автора для коммита в git
//   ПутьКХранилищу - Строка - полный путь к хранилищу конфигурации
//   НачальнаяВерсия - Число - номер начальной версии хранилища
//   СтандартнаяОбработка - Булево - признак отказ от обработки по умолчанию
//
Процедура ПриПолученииТаблицыВерсий(ТаблицаВерсий, ПутьКХранилищу, НачальнаяВерсия, СтандартнаяОбработка) Экспорт

	Лог.Информация("Вызвано событие <ПриПолученииТаблицыВерсий> для плагина <%1>", Имя());

КонецПроцедуры

// Вызывается после получении таблицы версий из хранилища конфигурации
//
// Параметры:
//   ТаблицаВерсий - ТаблицаЗначений - заполненная таблица с колонками:
//     * Дата                - Дата   - дата версии
//     * НомерВерсии         - Число  - номер версии
// 	   * Комментарий         - Строка - комментарий автора к версии
//     * Автор               - Строка - имя автора версии в хранилище
// 	   * Тэг                 - Строка - метка версии в хранилище
// 	   * ГУИД_Автора         - Строка - уникальный идентификатор автора версии
//     * ПредставлениеАвтора - Строка - представление автора для коммита в git
//   ПутьКХранилищу - Строка - полный путь к хранилищу конфигурации
//
Процедура ПослеПолученияТаблицыВерсий(ТаблицаВерсий, ПутьКХранилищу) Экспорт

	Лог.Информация("Вызвано событие <ПослеПолученияТаблицыВерсий> для плагина <%1>", Имя());

КонецПроцедуры

#КонецОбласти

#Область Подписки_на_получение_таблицы_пользователей

// Вызывается при получении таблицы пользователей из хранилища конфигурации
//
// Параметры:
//   ТаблицаПользователей - ТаблицаЗначений - инициализированная таблица с колонками:
//     * Автор               - Строка - имя автора версии в хранилище
//     * ПредставлениеАвтора - Строка - представление автора для коммита в git
// 	   * ГУИД_Автора         - Строка - уникальный идентификатор автора версии
//   ПутьКХранилищу - Строка - полный путь к хранилищу конфигурации
//   СтандартнаяОбработка - Булево - признак отказ от обработки по умолчанию
//
Процедура ПриПолученииТаблицыПользователей(ТаблицаПользователей, ПутьКХранилищу, СтандартнаяОбработка) Экспорт

	Лог.Информация("Вызвано событие <ПриПолученииТаблицыПользователей> для плагина <%1>", Имя());

КонецПроцедуры

// Вызывается после получении таблицы пользователей из хранилища конфигурации
//
// Параметры:
//   ТаблицаПользователей - ТаблицаЗначений - заполненная таблица с колонками:
//     * Автор               - Строка - имя автора версии в хранилище
//     * ПредставлениеАвтора - Строка - представление автора для коммита в git
// 	   * ГУИД_Автора         - Строка - уникальный идентификатор автора версии
//   ПутьКХранилищу - Строка - полный путь к хранилищу конфигурации
//
Процедура ПослеПолученияТаблицыПользователей(ТаблицаПользователей, ПутьКХранилищу) Экспорт

	Лог.Информация("Вызвано событие <ПослеПолученияТаблицыПользователей> для плагина <%1>", Имя());

КонецПроцедуры

// Вызывается при получении таблицы пользователей из хранилища конфигурации
//
// Параметры:
//   ПутьКФайлуАвторов - Строка - полный путь к хранилищу конфигурации
//   ТаблицаАвторов - ТаблицаЗначений - инициализированная таблица с колонками:
//     * Автор               - Строка - имя автора версии в хранилище
//     * ПредставлениеАвтора - Строка - представление автора для коммита в git
//   СтандартнаяОбработка - Булево - признак отказ от обработки по умолчанию
//
Процедура ПриПолученииТаблицыАвторов(ПутьКФайлуАвторов, ТаблицаАвторов, СтандартнаяОбработка) Экспорт

	Лог.Информация("Вызвано событие <ПриПолученииТаблицыАвторов> для плагина <%1>", Имя());

КонецПроцедуры

// Вызывается при получении таблицы пользователей из хранилища конфигурации
//
// Параметры:
//   ПутьКФайлуАвторов - Строка - полный путь к хранилищу конфигурации
//   ТаблицаАвторов - ТаблицаЗначений - инициализированная таблица с колонками:
//     * Автор               - Строка - имя автора версии в хранилище
//     * ПредставлениеАвтора - Строка - представление автора для коммита в git
//
Процедура ПослеПолученияТаблицыАвторов(ПутьКФайлуАвторов, ТаблицаАвторов) Экспорт

	Лог.Информация("Вызвано событие <ПослеПолученияТаблицыАвторов> для плагина <%1>", Имя());

КонецПроцедуры

#КонецОбласти

#Область Подписки_на_обработки_строки_версии

// Вызывается перед началом обработки таблица истории хранилища конфигурации
//
// Параметры:
//   ТаблицаИсторииХранилища - ТаблицаЗначений - заполненная таблица с колонками:
//     * Дата                - Дата   - дата версии
//     * НомерВерсии         - Число  - номер версии
// 	   * Комментарий         - Строка - комментарий автора к версии
//     * Автор               - Строка - имя автора версии в хранилище
// 	   * Тэг                 - Строка - метка версии в хранилище
// 	   * ГУИД_Автора         - Строка - уникальный идентификатор автора версии
//     * ПредставлениеАвтора - Строка - представление автора для коммита в git
//   ТекущаяВерсия - Число - текущая/последняя синхронизированная версия из файла <VERSION>
//   СледующаяВерсия - Число - следующая версия для обработки
//   МаксимальнаяВерсияДляРазбора - Число - максимальная версия для обработки
//
Процедура ПередНачаломЦиклаОбработкиВерсий(ТаблицаИсторииХранилища, ТекущаяВерсия, СледующаяВерсия, МаксимальнаяВерсияДляРазбора) Экспорт

	Лог.Информация("Вызвано событие <ПередНачаломЦиклаОбработкиВерсий> для плагина <%1>", Имя());

КонецПроцедуры

// Вызывается перед обработкой версии хранилища
//
// Параметры:
//   СтрокаВерсии - СтрокаТаблицыЗначений - текущая строка из ТаблицаИсторииХранилища
//   ТекущаяВерсия - Число - текущая версия для обработки
//
Процедура ПередОбработкойВерсииХранилища(СтрокаВерсии, ТекущаяВерсия) Экспорт

	Лог.Информация("Вызвано событие <ПередОбработкойВерсииХранилища> для плагина <%1>", Имя());

КонецПроцедуры

// Вызывается при обработкой версии хранилища
//
// Параметры:
//   СтрокаВерсии - СтрокаТаблицыЗначений - текущая строка из ТаблицаИсторииХранилища
//   ТекущаяВерсия - Число - текущая версия для обработки
//
Процедура ПриОбработкеВерсииХранилища(СтрокаВерсии, ТекущаяВерсия) Экспорт

	Лог.Информация("Вызвано событие <ПриОбработкеВерсииХранилища> для плагина <%1>", Имя());

КонецПроцедуры

// Вызывается после обработкой версии хранилища
//
// Параметры:
//   СтрокаВерсии - СтрокаТаблицыЗначений - текущая строка из ТаблицаИсторииХранилища
//   ТекущаяВерсия - Число - текущая версия для обработки
//
Процедура ПослеОбработкиВерсииХранилища(СтрокаВерсии, ТекущаяВерсия) Экспорт

	Лог.Информация("Вызвано событие <ПослеОбработкиВерсииХранилища> для плагина <%1>", Имя());

КонецПроцедуры

#КонецОбласти

#Область Подписки_на_выполнение_коммита

// Вызывается перед фиксацией изменений в рабочей копии
//
// Параметры:
//   КаталогРабочейКопии - Строка - полный путь к рабочему каталогу копии
//   Комментарий - Строка - комментарий изменений при фиксации
//   Автор - Строка - автор изменений при фиксации
//   Дата - Дата - дата изменений фиксации
//
Процедура ПередКоммитом(КаталогРабочейКопии, Комментарий, Автор, Дата) Экспорт

	Лог.Информация("Вызвано событие <ПередКоммитом> для плагина <%1>", Имя());

КонецПроцедуры

// Вызывается при фиксации изменений в рабочей копии
//
// Параметры:
//   ГитРепозиторий - Объект.ГитРепозиторий - подготовленный объект класса <ГитРепозиторий>
//   Комментарий - Строка - комментарий при фиксации изменений
//   ПроиндексироватьОтслеживаемыеФайлы - Булево - признак добавления не отслеживаемых файлов в фиксацию
//   ИмяФайлаКомментария - Строка - путь к файлу для записи комментария фиксации
//   АвторДляГит - Строка - автор изменений изменений в формате `Иванов_А <ivanov@mail.ru>`
//   ДатаДляГит - Дата - дата изменений
//   Коммитер - Строка - автор фиксации изменений в формате `Иванов_А <ivanov@mail.ru>`
//   ДатаКоммитера - Дата - дата фиксации изменений
//
Процедура ПриКоммите(ГитРепозиторий,
						Комментарий,
						ПроиндексироватьОтслеживаемыеФайлы,
						ИмяФайлаКомментария,
						АвторДляГит,
						ДатаДляГит,
						Коммитер,
						ДатаКоммитера) Экспорт

	Лог.Информация("Вызвано событие <ПриКоммите> для плагина <%1>", Имя());

КонецПроцедуры

// Вызывается после фиксацией изменений в рабочей копии
//
// Параметры:
//   ГитРепозиторий - Объект.ГитРепозиторий - подготовленный объект класса <ГитРепозиторий>
//   КаталогРабочейКопии - Строка - полный путь к рабочему каталогу копии
//
Процедура ПослеКоммита(ГитРепозиторий, КаталогРабочейКопии) Экспорт

	Лог.Информация("Вызвано событие <ПослеКоммита> для плагина <%1>", Имя());

КонецПроцедуры

#КонецОбласти

#Область Подписки_на_начало_и_окончания_выгрузки_версии_конфигурации

// <Описание процедуры>
//
// Параметры:
//   Конфигуратор - <Тип.Вид> - <описание параметра>
//   КаталогРабочейКопии - <Тип.Вид> - <описание параметра>
//   ПутьКХранилищу - <Тип.Вид> - <описание параметра>
//   НомерВерсии - <Тип.Вид> - <описание параметра>
//
Процедура ПередНачаломВыгрузкиВерсииХранилищаКонфигурации(Конфигуратор, КаталогРабочейКопии, ПутьКХранилищу, НомерВерсии) Экспорт

	Лог.Информация("Вызвано событие <ПередНачаломВыгрузкиВерсииХранилищаКонфигурации> для плагина <%1>", Имя());

КонецПроцедуры

// <Описание процедуры>
//
// Параметры:
//   Конфигуратор - <Тип.Вид> - <описание параметра>
//   КаталогРабочейКопии - <Тип.Вид> - <описание параметра>
//   ПутьКХранилищу - <Тип.Вид> - <описание параметра>
//   НомерВерсии - <Тип.Вид> - <описание параметра>
//
Процедура ПослеОкончанияВыгрузкиВерсииХранилищаКонфигурации(Конфигуратор, КаталогРабочейКопии, ПутьКХранилищу, НомерВерсии) Экспорт

	Лог.Информация("Вызвано событие <ПослеОкончанияВыгрузкиВерсииХранилищаКонфигурации> для плагина <%1>", Имя());

КонецПроцедуры

#КонецОбласти

#Область Подписки_на_загрузку_версии_конфигурации_из_хранилища

// <Описание процедуры>
//
// Параметры:
//   Конфигуратор - <Тип.Вид> - <описание параметра>
//   КаталогРабочейКопии - <Тип.Вид> - <описание параметра>
//   ПутьКХранилищу - <Тип.Вид> - <описание параметра>
//   НомерВерсии - <Тип.Вид> - <описание параметра>
//
Процедура ПередЗагрузкойВерсииХранилищаКонфигурации(Конфигуратор, КаталогРабочейКопии, ПутьКХранилищу, НомерВерсии) Экспорт

	Лог.Информация("Вызвано событие <ПередЗагрузкойВерсииХранилищаКонфигурации> для плагина <%1>", Имя());

КонецПроцедуры

// <Описание процедуры>
//
// Параметры:
//   Конфигуратор - <Тип.Вид> - <описание параметра>
//   КаталогРабочейКопии - <Тип.Вид> - <описание параметра>
//   ПутьКХранилищу - <Тип.Вид> - <описание параметра>
//   НомерВерсии - <Тип.Вид> - <описание параметра>
//   СтандартнаяОбработка - <Тип.Вид> - <описание параметра>
//
Процедура ПриЗагрузкеВерсииХранилищаВКонфигурацию(Конфигуратор, КаталогРабочейКопии, ПутьКХранилищу, НомерВерсии, СтандартнаяОбработка) Экспорт

	Лог.Информация("Вызвано событие <ПриЗагрузкеВерсииХранилищаВКонфигурацию> для плагина <%1>", Имя());

КонецПроцедуры

// <Описание процедуры>
//
// Параметры:
//   Конфигуратор - <Тип.Вид> - <описание параметра>
//   КаталогРабочейКопии - <Тип.Вид> - <описание параметра>
//   ПутьКХранилищу - <Тип.Вид> - <описание параметра>
//   НомерВерсии - <Тип.Вид> - <описание параметра>
//
Процедура ПослеЗагрузкиВерсииХранилищаВКонфигурацию(Конфигуратор, КаталогРабочейКопии, ПутьКХранилищу, НомерВерсии) Экспорт

	Лог.Информация("Вызвано событие <ПослеЗагрузкиВерсииХранилищаВКонфигурацию> для плагина <%1>", Имя());

КонецПроцедуры

#КонецОбласти

#Область Подписки_на_выгрузку_конфигурации_в_исходники

// <Описание процедуры>
//
// Параметры:
//   Конфигуратор - <Тип.Вид> - <описание параметра>
//   КаталогРабочейКопии - <Тип.Вид> - <описание параметра>
//   КаталогВыгрузки - <Тип.Вид> - <описание параметра>
//   ПутьКХранилищу - <Тип.Вид> - <описание параметра>
//   НомерВерсии - <Тип.Вид> - <описание параметра>
//
Процедура ПередВыгрузкойКонфигурациюВИсходники(Конфигуратор, КаталогРабочейКопии, КаталогВыгрузки, ПутьКХранилищу, НомерВерсии) Экспорт

	Лог.Информация("Вызвано событие <ПередВыгрузкойКонфигурациюВИсходники> для плагина <%1>", Имя());

КонецПроцедуры

// <Описание процедуры>
//
// Параметры:
//   Конфигуратор - <Тип.Вид> - <описание параметра>
//   КаталогВыгрузки - <Тип.Вид> - <описание параметра>
//   СтандартнаяОбработка - <Тип.Вид> - <описание параметра>
//
Процедура ПриВыгрузкеКонфигурациюВИсходники(Конфигуратор, КаталогВыгрузки, СтандартнаяОбработка) Экспорт

	Лог.Информация("Вызвано событие <ПриВыгрузкеКонфигурациюВИсходники> для плагина <%1>", Имя());

КонецПроцедуры

// <Описание процедуры>
//
// Параметры:
//   Конфигуратор - <Тип.Вид> - <описание параметра>
//   КаталогВыгрузки - <Тип.Вид> - <описание параметра>
//
Процедура ПослеВыгрузкиКонфигурациюВИсходники(Конфигуратор, КаталогВыгрузки) Экспорт

	Лог.Информация("Вызвано событие <ПослеВыгрузкиКонфигурациюВИсходники> для плагина <%1>", Имя());

КонецПроцедуры

#КонецОбласти

#Область Подписки_на_очистку_каталога_рабочей_версии

// <Описание процедуры>
//
// Параметры:
//   Конфигуратор - <Тип.Вид> - <описание параметра>
//   КаталогРабочейКопии - <Тип.Вид> - <описание параметра>
//   КаталогВыгрузки - <Тип.Вид> - <описание параметра>
//   ПутьКХранилищу - <Тип.Вид> - <описание параметра>
//   НомерВерсии - <Тип.Вид> - <описание параметра>
//
Процедура ПередОчисткойКаталогаРабочейКопии(Конфигуратор, КаталогРабочейКопии, КаталогВыгрузки, ПутьКХранилищу, НомерВерсии) Экспорт

	Лог.Информация("Вызвано событие <ПередОчисткойКаталогаРабочейКопии> для плагина <%1>", Имя());

КонецПроцедуры

// <Описание процедуры>
//
// Параметры:
//   КаталогРабочейКопии - <Тип.Вид> - <описание параметра>
//   СоответствиеИменФайловДляПропуска - <Тип.Вид> - <описание параметра>
//   СтандартнаяОбработка - <Тип.Вид> - <описание параметра>
//
Процедура ПриОчисткеКаталогаРабочейКопии(КаталогРабочейКопии, СоответствиеИменФайловДляПропуска, СтандартнаяОбработка) Экспорт

	Лог.Информация("Вызвано событие <ПриОчисткеКаталогаРабочейКопии> для плагина <%1>", Имя());

КонецПроцедуры

// <Описание процедуры>
//
// Параметры:
//   КаталогРабочейКопии - <Тип.Вид> - <описание параметра>
//   СоответствиеИменФайловДляПропуска - <Тип.Вид> - <описание параметра>
//
Процедура ПослеОчисткиКаталогаРабочейКопии(КаталогРабочейКопии, СоответствиеИменФайловДляПропуска) Экспорт

	Лог.Информация("Вызвано событие <ПослеОчисткиКаталогаРабочейКопии> для плагина <%1>", Имя());

КонецПроцедуры

#КонецОбласти

#Область Подписки_на_перемещение_в_каталог_рабочей_копии

// <Описание процедуры>
//
// Параметры:
//   Конфигуратор - <Тип.Вид> - <описание параметра>
//   КаталогРабочейКопии - <Тип.Вид> - <описание параметра>
//   КаталогВыгрузки - <Тип.Вид> - <описание параметра>
//   ПутьКХранилищу - <Тип.Вид> - <описание параметра>
//   НомерВерсии - <Тип.Вид> - <описание параметра>
//
Процедура ПередПеремещениемВКаталогРабочейКопии(Конфигуратор, КаталогРабочейКопии, КаталогВыгрузки, ПутьКХранилищу, НомерВерсии) Экспорт

	Лог.Информация("Вызвано событие <ПередПеремещениемВКаталогРабочейКопии> для плагина <%1>", Имя());

КонецПроцедуры

// <Описание процедуры>
//
// Параметры:
//   КаталогРабочейКопии - <Тип.Вид> - <описание параметра>
//   КаталогВыгрузки - <Тип.Вид> - <описание параметра>
//   СтандартнаяОбработка - <Тип.Вид> - <описание параметра>
//
Процедура ПриПеремещенииВКаталогРабочейКопии(КаталогРабочейКопии, КаталогВыгрузки, СтандартнаяОбработка) Экспорт

	Лог.Информация("Вызвано событие <ПриПеремещенииВКаталогРабочейКопии> для плагина <%1>", Имя());

КонецПроцедуры

// <Описание процедуры>
//
// Параметры:
//   КаталогРабочейКопии - <Тип.Вид> - <описание параметра>
//   КаталогВыгрузки - <Тип.Вид> - <описание параметра>
//
Процедура ПослеПеремещенияВКаталогРабочейКопии(КаталогРабочейКопии, КаталогВыгрузки) Экспорт

	Лог.Информация("Вызвано событие <ПослеПеремещенияВКаталогРабочейКопии> для плагина <%1>", Имя());

КонецПроцедуры

#КонецОбласти

#Область Интерфейс_плагина

// <Описание функции>
//
//  Возвращаемое значение:
//   <Тип.Вид> - <описание возвращаемого значения>
//
Функция Версия() Экспорт
	Возврат "0.0.1";
КонецФункции

// <Описание функции>
//
//  Возвращаемое значение:
//   <Тип.Вид> - <описание возвращаемого значения>
//
Функция Описание() Экспорт
	Возврат "Тестовый плагин";
КонецФункции

// <Описание функции>
//
//  Возвращаемое значение:
//   <Тип.Вид> - <описание возвращаемого значения>
//
Функция Справка() Экспорт
	Возврат "Справка плагина";
КонецФункции

// <Описание функции>
//
//  Возвращаемое значение:
//   <Тип.Вид> - <описание возвращаемого значения>
//
Функция Имя() Экспорт
	Возврат "test_plugin";
КонецФункции

// <Описание функции>
//
//  Возвращаемое значение:
//   <Тип.Вид> - <описание возвращаемого значения>
//
Функция ИмяЛога() Экспорт
	Возврат "oscript.lib.gitsync.test_plugin";
КонецФункции

// <Описание функции>
//
//  Возвращаемое значение:
//   <Тип.Вид> - <описание возвращаемого значения>
//
Функция Приоритет() Экспорт
	Возврат 1;
КонецФункции

#КонецОбласти

Лог = Логирование.ПолучитьЛог(ИмяЛога());


.h1,
.h2,
.h3,
.h4,
.h5,
.h6,
h1,
h2,
h3,
h4,
h5,
h6 {
  margin-bottom: .5rem;
  font-family: inherit;
  font-weight: 500;
  line-height: 1.2;
  color: inherit;
}

h1,
.h1 {
  margin: 0;
  padding: 15px 0 0;
  font-weight: 700;
  font-size: 2.5rem;

  @include mq('handheld-and-up') {
    font-size: 3rem;
  }

  @include mq('print') {
    font-size: 18pt;
    padding: 0 0 5px;
  }
}

h2,
.h2 {
  font-size: 2rem;
}

h3,
.h3 {
  font-size: 1.2rem;
  font-weight: 700;

  @include mq('handheld-and-up') {
    font-size: 1.3rem;
  }
}

h4,
.h4 {
  font-size: 1.2rem;
  font-weight: 700;

  @include mq('handheld-and-up') {
    font-size: 1.3rem;
  }
}


#region Copyright Syncfusion Inc. 2001-2020.
// Copyright Syncfusion Inc. 2001-2020. All rights reserved.
// Use of this code is subject to the terms of our license.
// A copy of the current license can be obtained at any time by e-mailing
// licensing@syncfusion.com. Any infringement will be prosecuted under
// applicable laws.
#endregion
using System;
using System.IO;
using System.Reflection;
using SampleBrowser.Core;
using Syncfusion.DocIO;
using Syncfusion.DocIO.DLS;
using Xamarin.Forms;

namespace SampleBrowser.DocIO
{
    /// <summary>
    /// A sample view that can be used on FormFillingAndProtection.
    /// </summary>
    public partial class FormFillingAndProtection : SampleView
    {
        /// <summary>
        /// Constructor for FormFillingAndProtection.
        /// </summary>
        public FormFillingAndProtection()
        {
            InitializeComponent();

            if (Device.Idiom != TargetIdiom.Phone && Device.RuntimePlatform == Device.UWP)
            {

                this.Content_1.HorizontalOptions = LayoutOptions.Start;
                this.btnGenerate.HorizontalOptions = LayoutOptions.Start;

                this.Content_1.VerticalOptions = LayoutOptions.Center;
                this.btnGenerate.VerticalOptions = LayoutOptions.Center;
				this.btnGenerate.BackgroundColor = Xamarin.Forms.Color.Gray;
            }
            else if (Device.Idiom == TargetIdiom.Phone && Device.RuntimePlatform == Device.UWP)
            {
              //if (!SampleBrowser.DocIO.App.isUWP)
                //{
                //    this.Content_1.FontSize = 18.5;
                //}
                //else
                //{
                    this.Content_1.FontSize = 13.5;
               // }

                this.Content_1.VerticalOptions = LayoutOptions.Center;
                this.btnGenerate.VerticalOptions = LayoutOptions.Center;
            }
        }
        /// <summary>
        /// Button click event for FormFillingAndProtection.
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Event args</param>
        private void OnButtonClicked(object sender, EventArgs e)
        {
#if COMMONSB
            string rootPath = "SampleBrowser.Samples.DocIO.Samples.Templates.";
#else
            string rootPath = "SampleBrowser.DocIO.Samples.Templates.";
#endif
            // Load Template document stream.
            Stream inputStream = typeof(FormFillingAndProtection).GetTypeInfo().Assembly.GetManifestResourceStream(rootPath + "ContentControlTemplate.docx");

            // Creates an empty Word document instance.
            WordDocument document = new WordDocument();
            // Opens template document.
            document.Open(inputStream, FormatType.Docx);

            IWTextRange textRange;
            //Gets table from the template document.
            IWTable table = document.LastSection.Tables[0];
            WTableRow row = table.Rows[1];

            #region Inserting content controls

            #region Calendar content control
            IWParagraph cellPara = row.Cells[0].Paragraphs[0];
            //Accesses the date picker content control.
            IInlineContentControl inlineControl = (cellPara.ChildEntities[2] as IInlineContentControl);
            textRange = inlineControl.ParagraphItems[0] as WTextRange;
            //Sets today's date to display.
            textRange.Text = DateTime.Now.ToString("d");
            textRange.CharacterFormat.FontSize = 14;
            //Protects the content control.
            inlineControl.ContentControlProperties.LockContents = true;
            #endregion

            #region Plain text content controls
            table = document.LastSection.Tables[1];
            row = table.Rows[0];
            cellPara = row.Cells[0].LastParagraph;
            //Accesses the plain text content control.
            inlineControl = (cellPara.ChildEntities[1] as IInlineContentControl);
            //Protects the content control.
            inlineControl.ContentControlProperties.LockContents = true;
            textRange = inlineControl.ParagraphItems[0] as WTextRange;
            //Sets text in plain text content control.
            textRange.Text = "Northwind Analytics";
            textRange.CharacterFormat.FontSize = 14;

            cellPara = row.Cells[1].LastParagraph;
            //Accesses the plain text content control.
            inlineControl = (cellPara.ChildEntities[1] as IInlineContentControl);
            //Protects the content control.
            inlineControl.ContentControlProperties.LockContents = true;
            textRange = inlineControl.ParagraphItems[0] as WTextRange;
            //Sets text in plain text content control.
            textRange.Text = "Northwind";
            textRange.CharacterFormat.FontSize = 14;

            row = table.Rows[1];
            cellPara = row.Cells[0].LastParagraph;
            //Accesses the plain text content control.
            inlineControl = (cellPara.ChildEntities[1] as IInlineContentControl);
            //Protects the content control.
            inlineControl.ContentControlProperties.LockContents = true;
            //Sets text in plain text content control.
            textRange = inlineControl.ParagraphItems[0] as WTextRange;
            textRange.Text = "10";
            textRange.CharacterFormat.FontSize = 14;

            cellPara = row.Cells[1].LastParagraph;
            //Accesses the plain text content control.
            inlineControl = (cellPara.ChildEntities[1] as IInlineContentControl);
            //Protects the content control.
            inlineControl.ContentControlProperties.LockContents = true;
            //Sets text in plain text content control.
            textRange = inlineControl.ParagraphItems[0] as WTextRange;
            textRange.Text = "Nancy Davolio";
            textRange.CharacterFormat.FontSize = 14;
            #endregion

            #region CheckBox Content control
            row = table.Rows[2];
            cellPara = row.Cells[0].LastParagraph;
            //Inserts checkbox content control.
            inlineControl = cellPara.AppendInlineContentControl(ContentControlType.CheckBox);
            inlineControl.ContentControlProperties.LockContents = true;
            //Sets checkbox as checked state.
            inlineControl.ContentControlProperties.IsChecked = true;
            textRange = cellPara.AppendText("C#, ");
            textRange.CharacterFormat.FontSize = 14;

            //Inserts checkbox content control.
            inlineControl = cellPara.AppendInlineContentControl(ContentControlType.CheckBox);
            inlineControl.ContentControlProperties.LockContents = true;
            //Sets checkbox as checked state.
            inlineControl.ContentControlProperties.IsChecked = true;
            textRange = cellPara.AppendText("VB");
            textRange.CharacterFormat.FontSize = 14;
            #endregion

            #region Drop down list content control
            cellPara = row.Cells[1].LastParagraph;
            //Accesses the dropdown list content control.
            inlineControl = (cellPara.ChildEntities[1] as IInlineContentControl);
            inlineControl.ContentControlProperties.LockContents = true;
            //Sets default option to display.
            textRange = inlineControl.ParagraphItems[0] as WTextRange;
            textRange.Text = "ASP.NET";
            textRange.CharacterFormat.FontSize = 14;
            inlineControl.ParagraphItems.Add(textRange);

            //Adds items to the dropdown list.
            ContentControlListItem item;
            item = new ContentControlListItem();
            item.DisplayText = "ASP.NET MVC";
            item.Value = "2";
            inlineControl.ContentControlProperties.ContentControlListItems.Add(item);

            item = new ContentControlListItem();
            item.DisplayText = "Windows Forms";
            item.Value = "3";
            inlineControl.ContentControlProperties.ContentControlListItems.Add(item);

            item = new ContentControlListItem();
            item.DisplayText = "WPF";
            item.Value = "4";
            inlineControl.ContentControlProperties.ContentControlListItems.Add(item);

            item = new ContentControlListItem();
            item.DisplayText = "Xamarin";
            item.Value = "5";
            inlineControl.ContentControlProperties.ContentControlListItems.Add(item);
            #endregion

            #region Calendar content control
            row = table.Rows[3];
            cellPara = row.Cells[0].LastParagraph;
            //Accesses the date picker content control.
            inlineControl = (cellPara.ChildEntities[1] as IInlineContentControl);
            inlineControl.ContentControlProperties.LockContents = true;
            //Sets default date to display.
            textRange = inlineControl.ParagraphItems[0] as WTextRange;
            textRange.Text = DateTime.Now.AddDays(-5).ToString("d");
            textRange.CharacterFormat.FontSize = 14;

            cellPara = row.Cells[1].LastParagraph;
            //Inserts date picker content control.
            inlineControl = (cellPara.ChildEntities[1] as IInlineContentControl);
            inlineControl.ContentControlProperties.LockContents = true;
            //Sets default date to display.
            textRange = inlineControl.ParagraphItems[0] as WTextRange;
            textRange.Text = DateTime.Now.AddDays(10).ToString("d");
            textRange.CharacterFormat.FontSize = 14;
            #endregion

            #endregion
            #region Block content control
            //Accesses the block content control.
            BlockContentControl blockContentControl = ((document.ChildEntities[0] as WSection).Body.ChildEntities[2] as BlockContentControl);
            //Protects the block content control
            blockContentControl.ContentControlProperties.LockContents = true;
            #endregion

            MemoryStream stream = new MemoryStream();
            document.Save(stream, FormatType.Docx);
            document.Close();

            if (Device.RuntimePlatform == Device.UWP)
                DependencyService.Get<ISaveWindowsPhone>()
                    .Save("FormFillingAndProtection.docx", "application/msword", stream);
            else
                DependencyService.Get<ISave>().Save("FormFillingAndProtection.docx", "application/msword", stream);
        }
    }
}


/*
 * Copyright (C) 2010-2020 Structr GmbH
 *
 * This file is part of Structr <http://structr.org>.
 *
 * Structr is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * Structr is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Structr.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.structr.memgraph;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.neo4j.driver.v1.types.Path.Segment;
import org.neo4j.driver.v1.types.Relationship;
import org.structr.api.NotFoundException;
import org.structr.api.graph.Path;
import org.structr.api.graph.PropertyContainer;

/**
 *
 */
class PathWrapper implements Path {

	private org.neo4j.driver.v1.types.Path path = null;
	private MemgraphDatabaseService db              = null;

	public PathWrapper(final MemgraphDatabaseService db, final org.neo4j.driver.v1.types.Path path) {

		this.path = path;
		this.db   = db;
	}

	@Override
	public Iterator<PropertyContainer> iterator() {

		if (path.length() > 0) {

			return new SegmentIterator(path);
		}

		final List<PropertyContainer> list = new LinkedList<>();
		list.add(NodeWrapper.newInstance(db, path.start()));

		return list.iterator();
	}

	// ----- nested classes -----
	private class SegmentIterator implements Iterator<PropertyContainer> {

		private Iterator<Segment> it = null;
		private Segment current      = null;
		private int state            = 0;

		public SegmentIterator(final org.neo4j.driver.v1.types.Path path) {
			this.it = path.iterator();
		}

		@Override
		public boolean hasNext() {
			return state < 3;
		}

		@Override
		public PropertyContainer next() {

			if (current == null) {

				current = it.next();
			}

			switch (state) {

				case 0:
					state = 1;
					return NodeWrapper.newInstance(db, current.start());

				case 1:
					final Relationship rel = current.relationship();
					if (it.hasNext()) {

						state = 0;
						current = null;

					} else {

						state = 2;
					}
					return RelationshipWrapper.newInstance(db, rel);

				case 2:
					state = 3;
					return NodeWrapper.newInstance(db, current.end());
			}

			throw new NotFoundException("No such element.");
		}

		@Override
		public void remove() {
			throw new UnsupportedOperationException("Removal not supported.");
		}
	}

}


package liquibase.ext.hibernate.database.connection;

import liquibase.resource.ResourceAccessor;

import java.io.IOException;
import java.io.StringReader;
import java.net.URLDecoder;
import java.sql.*;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;

/**
 * Implements java.sql.Connection in order to pretend a hibernate configuration is a database in order to fit into the Liquibase framework.
 * Beyond standard Connection methods, this class exposes {@link #getPrefix()}, {@link #getPath()} and {@link #getProperties()} to access the setting passed in the JDBC URL.
 */
public class HibernateConnection implements Connection {
    private String prefix;
    private String url;

    private String path;
    private ResourceAccessor resourceAccessor;
    private Properties properties;

    public HibernateConnection(String url, ResourceAccessor resourceAccessor) {
        this.url = url;

        this.prefix = url.replaceFirst(":[^:]+$", "");

        // Trim the prefix off the URL for the path
        path = url.substring(prefix.length() + 1);
        this.resourceAccessor = resourceAccessor;

        // Check if there is a parameter/query string value.
        properties = new Properties();

        int queryIndex = path.indexOf('?');
        if (queryIndex >= 0) {
            // Convert the query string into properties
            properties.putAll(readProperties(path.substring(queryIndex + 1)));

            if (properties.containsKey("dialect") && !properties.containsKey("hibernate.dialect")) {
                properties.put("hibernate.dialect", properties.getProperty("dialect"));
            }

            // Remove the query string
            path = path.substring(0, queryIndex);
        }
    }

    /**
     * Creates properties to attach to this connection based on the passed query string.
     */
    protected Properties readProperties(String queryString) {
        Properties properties = new Properties();
        queryString = queryString.replaceAll("&", System.getProperty("line.separator"));
        try {
            queryString = URLDecoder.decode(queryString, "UTF-8");
            properties.load(new StringReader(queryString));
        } catch (IOException ioe) {
            throw new IllegalStateException("Failed to read properties from url", ioe);
        }

        return properties;
    }

    /**
     * Returns the entire connection URL
     */
    public String getUrl() {
        return url;
    }

    /**
     * Returns the 'protocol' of the URL. For example, "hibernate:classic" or "hibernate:ejb3"
     */
    public String getPrefix() {
        return prefix;
    }

    /**
     * The portion of the url between the path and the query string. Normally a filename or a class name.
     */
    public String getPath() {
        return path;
    }

    /**
     * The set of properties provided by the URL. Eg:
     *

     * hibernate:classic:/path/to/hibernate.cfg.xml?foo=bar
     *

     * This will have a property called 'foo' with a value of 'bar'.
     */
    public Properties getProperties() {
        return properties;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// JDBC METHODS
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public Statement createStatement() throws SQLException {
        return null;
    }

    public PreparedStatement prepareStatement(String sql) throws SQLException {
        return null;
    }

    public CallableStatement prepareCall(String sql) throws SQLException {
        return null;
    }

    public String nativeSQL(String sql) throws SQLException {
        return null;
    }

    public void setAutoCommit(boolean autoCommit) throws SQLException {

    }

    public boolean getAutoCommit() throws SQLException {
        return false;
    }

    public void commit() throws SQLException {

    }

    public void rollback() throws SQLException {

    }

    public void close() throws SQLException {

    }

    public boolean isClosed() throws SQLException {
        return false;
    }

    public DatabaseMetaData getMetaData() throws SQLException {
        return new HibernateConnectionMetadata(url);
    }

    public void setReadOnly(boolean readOnly) throws SQLException {

    }

    public boolean isReadOnly() throws SQLException {
        return true;
    }

    public void setCatalog(String catalog) throws SQLException {

    }

    public String getCatalog() throws SQLException {
        return "HIBERNATE";
    }

    public void setTransactionIsolation(int level) throws SQLException {

    }

    public int getTransactionIsolation() throws SQLException {
        return 0;
    }

    public SQLWarning getWarnings() throws SQLException {
        return null;
    }

    public void clearWarnings() throws SQLException {

    }

    public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
        return null;
    }

    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
        return null;
    }

    public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
        return null;
    }

    public Map<String, Class<?>> getTypeMap() throws SQLException {
        return null;
    }

    public void setTypeMap(Map<String, Class<?>> map) throws SQLException {

    }

    public void setHoldability(int holdability) throws SQLException {

    }

    public int getHoldability() throws SQLException {
        return 0;
    }

    public Savepoint setSavepoint() throws SQLException {
        return null;
    }

    public Savepoint setSavepoint(String name) throws SQLException {
        return null;
    }

    public void rollback(Savepoint savepoint) throws SQLException {

    }

    public void releaseSavepoint(Savepoint savepoint) throws SQLException {

    }

    public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
        return null;
    }

    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
        return null;
    }

    public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
        return null;
    }

    public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
        return null;
    }

    public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
        return null;
    }

    public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
        return null;
    }

    public Clob createClob() throws SQLException {
        return null;
    }

    public Blob createBlob() throws SQLException {
        return null;
    }

    public NClob createNClob() throws SQLException {
        return null;
    }

    public SQLXML createSQLXML() throws SQLException {
        return null;
    }

    public boolean isValid(int timeout) throws SQLException {
        return false;
    }

    public void setClientInfo(String name, String value) throws SQLClientInfoException {

    }

    public void setClientInfo(Properties properties) throws SQLClientInfoException {

    }

    public String getClientInfo(String name) throws SQLException {
        return null;
    }

    public Properties getClientInfo() throws SQLException {
        return null;
    }

    public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
        return null;
    }

    public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
        return null;
    }

    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }

    //@Override only in java 1.7
    public void abort(Executor arg0) throws SQLException {
    }

    //@Override only in java 1.7
    public int getNetworkTimeout() throws SQLException {
        return 0;
    }

    //@Override only in java 1.7
    public String getSchema() throws SQLException {
        return "HIBERNATE";
    }

    //@Override only in java 1.7
    public void setNetworkTimeout(Executor arg0, int arg1) throws SQLException {
    }

    //@Override only in java 1.7
    public void setSchema(String arg0) throws SQLException {
    }

    public ResourceAccessor getResourceAccessor() {
        return resourceAccessor;
    }
}


/* -----------------------------------------------------------------------------

	Copyright (c) 2006 Simon Brown                          si@sjbrown.co.uk

	Permission is hereby granted, free of charge, to any person obtaining
	a copy of this software and associated documentation files (the
	"Software"), to	deal in the Software without restriction, including
	without limitation the rights to use, copy, modify, merge, publish,
	distribute, sublicense, and/or sell copies of the Software, and to
	permit persons to whom the Software is furnished to do so, subject to
	the following conditions:

	The above copyright notice and this permission notice shall be included
	in all copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
	CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
	TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

   -------------------------------------------------------------------------- */

#include "colourset.h"

namespace squish {

ColourSet::ColourSet( u8 const* rgba, int mask, int flags )
  : m_count( 0 ),
	m_transparent( false )
{
	// check the compression mode for dxt1
	bool isDxt1 = ( ( flags & kDxt1 ) != 0 );
	bool weightByAlpha = ( ( flags & kWeightColourByAlpha ) != 0 );

	// create the minimal set
	for( int i = 0; i < 16; ++i )
	{
		// check this pixel is enabled
		int bit = 1 << i;
		if( ( mask & bit ) == 0 )
		{
			m_remap[i] = -1;
			continue;
		}

		// check for transparent pixels when using dxt1
		if( isDxt1 && rgba[4*i + 3] < 128 )
		{
			m_remap[i] = -1;
			m_transparent = true;
			continue;
		}

		// loop over previous points for a match
		for( int j = 0;; ++j )
		{
			// allocate a new point
			if( j == i )
			{
				// normalise coordinates to [0,1]
				float x = ( float )rgba[4*i] / 255.0f;
				float y = ( float )rgba[4*i + 1] / 255.0f;
				float z = ( float )rgba[4*i + 2] / 255.0f;

				// ensure there is always non-zero weight even for zero alpha
				float w = ( float )( rgba[4*i + 3] + 1 ) / 256.0f;

				// add the point
				m_points[m_count] = Vec3( x, y, z );
				m_weights[m_count] = ( weightByAlpha ? w : 1.0f );
				m_remap[i] = m_count;

				// advance
				++m_count;
				break;
			}

			// check for a match
			int oldbit = 1 << j;
			bool match = ( ( mask & oldbit ) != 0 )
				&& ( rgba[4*i] == rgba[4*j] )
				&& ( rgba[4*i + 1] == rgba[4*j + 1] )
				&& ( rgba[4*i + 2] == rgba[4*j + 2] )
				&& ( rgba[4*j + 3] >= 128 || !isDxt1 );
			if( match )
			{
				// get the index of the match
				int index = m_remap[j];

				// ensure there is always non-zero weight even for zero alpha
				float w = ( float )( rgba[4*i + 3] + 1 ) / 256.0f;

				// map to this point and increase the weight
				m_weights[index] += ( weightByAlpha ? w : 1.0f );
				m_remap[i] = index;
				break;
			}
		}
	}

	// square root the weights
	for( int i = 0; i < m_count; ++i )
		m_weights[i] = std::sqrt( m_weights[i] );
}

void ColourSet::RemapIndices( u8 const* source, u8* target ) const
{
	for( int i = 0; i < 16; ++i )
	{
		int j = m_remap[i];
		if( j == -1 )
			target[i] = 3;
		else
			target[i] = source[j];
	}
}

} // namespace squish


GO

>_16c0_s noninterleaved
haux 16c0_s/resaux_0.vqd _16c0_s_single 0,64,2 10

:_p1_0 16c0_s/res_sub0_part1_pass2.vqd, 8, nonseq cull, 0 +- 1
:_p2_0 16c0_s/res_sub0_part2_pass2.vqd, 4, nonseq cull, 0 +- 1 2
:_p3_0 16c0_s/res_sub0_part3_pass2.vqd, 4, nonseq cull, 0 +- 1 2
:_p4_0 16c0_s/res_sub0_part4_pass2.vqd, 2, nonseq cull, 0 +- 1 2 3 4
:_p5_0 16c0_s/res_sub0_part5_pass2.vqd, 2, nonseq cull, 0 +- 1 2 3 4
:_p6_0 16c0_s/res_sub0_part6_pass2.vqd, 2, nonseq cull, 0 +- 1 2 3 4 5 6 7 8

:_p7_0 16c0_s/res_sub0_part7_pass0.vqd, 4, nonseq cull, 0 +- 11
:_p7_1 16c0_s/res_sub0_part7_pass1.vqd, 2, nonseq cull, 0 +- 1 2 3 4 5

:_p8_0 16c0_s/res_sub0_part8_pass0.vqd, 2, nonseq cull, 0 +- 5 10 15 20 25 30
:_p8_1 16c0_s/res_sub0_part8_pass1.vqd, 2, nonseq cull, 0 +- 1 2

:_p9_0 16c0_s/res_sub0_part9_pass0.vqd, 4, nonseq, 0 +- 315
:_p9_1 16c0_s/res_sub0_part9_pass1.vqd, 2, nonseq, 0 +- 21 42 63 84 105 126 147
:_p9_2 16c0_s/res_sub0_part9_pass2.vqd, 2, nonseq, 0 +- 1 2 3 4 5 6 7 8 9 10

>_16c1s_s noninterleaved
haux 16c1_s/resaux_0.vqd _16c1_s_short 0,64,2 10

>_16c1_s noninterleaved
haux 16c1_s/resaux_1.vqd _16c1_s_long 0,64,2 10

:_p1_0 16c1_s/res_sub0_part1_pass2.vqd, 8, nonseq cull, 0 +- 1
:_p2_0 16c1_s/res_sub0_part2_pass2.vqd, 4, nonseq cull, 0 +- 1 2
:_p3_0 16c1_s/res_sub0_part3_pass2.vqd, 4, nonseq cull, 0 +- 1 2
:_p4_0 16c1_s/res_sub0_part4_pass2.vqd, 2, nonseq cull, 0 +- 1 2 3 4
:_p5_0 16c1_s/res_sub0_part5_pass2.vqd, 2, nonseq cull, 0 +- 1 2 3 4
:_p6_0 16c1_s/res_sub0_part6_pass2.vqd, 2, nonseq cull, 0 +- 1 2 3 4 5 6 7 8

:_p7_0 16c1_s/res_sub0_part7_pass0.vqd, 4, nonseq cull, 0 +- 11
:_p7_1 16c1_s/res_sub0_part7_pass1.vqd, 2, nonseq cull, 0 +- 1 2 3 4 5

:_p8_0 16c1_s/res_sub0_part8_pass0.vqd, 2, nonseq cull, 0 +- 5 10 15 20 25 30
:_p8_1 16c1_s/res_sub0_part8_pass1.vqd, 2, nonseq cull, 0 +- 1 2

:_p9_0 16c1_s/res_sub0_part9_pass0.vqd, 2, nonseq, 0 +- 315 630 945 1260 1575 1890
:_p9_1 16c1_s/res_sub0_part9_pass1.vqd, 2, nonseq, 0 +- 21 42 63 84 105 126 147
:_p9_2 16c1_s/res_sub0_part9_pass2.vqd, 2, nonseq, 0 +- 1 2 3 4 5 6 7 8 9 10

>_16c2s_s noninterleaved
haux 16c2_s/resaux_0.vqd _16c2_s_short 0,64,2 10
>_16c2_s noninterleaved
haux 16c2_s/resaux_1.vqd _16c2_s_long 0,64,2 10

:_p1_0 16c2_s/res_sub0_part1_pass2.vqd, 4, nonseq cull, 0 +- 1
:_p2_0 16c2_s/res_sub0_part2_pass2.vqd, 4, nonseq cull, 0 +- 1 2
:_p3_0 16c2_s/res_sub0_part3_pass2.vqd, 2, nonseq cull, 0 +- 1 2 3 4
:_p4_0 16c2_s/res_sub0_part4_pass2.vqd, 2, nonseq cull, 0 +- 1 2 3 4 5 6 7 8

:_p5_0 16c2_s/res_sub0_part5_pass0.vqd, 4, nonseq cull, 0 +- 11
:_p5_1 16c2_s/res_sub0_part5_pass1.vqd, 2, nonseq cull, 0 +- 1 2 3 4 5

:_p6_0 16c2_s/res_sub0_part6_pass0.vqd, 2, nonseq cull, 0 +- 5 10 15 20 25 30
:_p6_1 16c2_s/res_sub0_part6_pass1.vqd, 2, nonseq cull, 0 +- 1 2

:_p7_0 16c2_s/res_sub0_part7_pass0.vqd, 2, nonseq, 0 +- 11 22 33 44 55 66
:_p7_1 16c2_s/res_sub0_part7_pass1.vqd, 2, nonseq cull, 0 +- 1 2 3 4 5

:_p8_0 16c2_s/res_sub0_part8_pass0.vqd, 2, nonseq, 0 +- 21 42 63 84 105 126 147
:_p8_1 16c2_s/res_sub0_part8_pass1.vqd, 2, nonseq cull, 0 +- 1 2 3 4 5 6 7 8 9 10

:_p9_0 16c2_s/res_sub0_part9_pass0.vqd, 2, nonseq, 0 +- 931 1862 2793 3724 4655 5586 6517 7448
:_p9_1 16c2_s/res_sub0_part9_pass1.vqd, 2, nonseq, 0 +- 49 98 147 196 245 294 343 392 441
:_p9_2 16c2_s/res_sub0_part9_pass2.vqd, 1, nonseq, 0 +- 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24


from __future__ import absolute_import, division, print_function

from trakt.interfaces.base import authenticated
from trakt.interfaces.sync.core.mixins import Get, Add, Remove

class SyncWatchlistInterface(Get, Add, Remove):
    path = 'sync/watchlist'
    flags = {'in_watchlist': True}

    def get(self, media=None, page=1, per_page=10, start_at=None, end_at=None, store=None, **kwargs):
        # Build query
        query = {}

        if page:
            query['page'] = page

        if per_page:
            query['limit'] = per_page

        # Request watched history
        return super(SyncWatchlistInterface, self).get(
            media, store,
            query=query,
            flat=media is None,
            **kwargs
        )

    @authenticated
    def seasons(self, store=None, **kwargs):
        return self.get(
            'seasons',
            store,
            **kwargs
        )

    @authenticated
    def episodes(self, store=None, **kwargs):
        return self.get(
            'episodes',
            store,
            **kwargs
        )


// RUN: %target-typecheck-verify-swift

let x: Bool = 3/4 as Float > 1/2 as Float

func testInIf(a: Any) {
  if a as? Float {} // expected-error {{cannot be used as a boolean}} {{6-6=((}} {{17-17=) != nil)}}
  let _: Float = a as? Float // expected-error {{value of optional type 'Float?' must be unwrapped}}
  // expected-note@-1{{coalesce}}
  // expected-note@-2{{force-unwrap}}
}


// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !gccgo

#include "textflag.h"

//
// System call support for 386, FreeBSD
//

// Just jump to package syscall's implementation for all these functions.
// The runtime may know about them.

TEXT	·Syscall(SB),NOSPLIT,$0-28
	JMP	syscall·Syscall(SB)

TEXT	·Syscall6(SB),NOSPLIT,$0-40
	JMP	syscall·Syscall6(SB)

TEXT	·Syscall9(SB),NOSPLIT,$0-52
	JMP	syscall·Syscall9(SB)

TEXT ·RawSyscall(SB),NOSPLIT,$0-28
	JMP	syscall·RawSyscall(SB)

TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
	JMP	syscall·RawSyscall6(SB)


<annotation>
	<folder>imagesRaw</folder>
	<filename>2017-12-19 12:52:23.942753.jpg</filename>
	<path>/Users/abell/Development/other.nyc/Camera/imagesRaw/2017-12-19 12:52:23.942753.jpg</path>
	<source>
		<database>Unknown</database>
	</source>
	<size>
		<width>352</width>
		<height>240</height>
		<depth>3</depth>
	</size>
	<segmented>0</segmented>
	<object>
		<name>bus</name>
		<pose>Unspecified</pose>
		<truncated>1</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>1</xmin>
			<ymin>149</ymin>
			<xmax>108</xmax>
			<ymax>234</ymax>
		</bndbox>
	</object>
	<object>
		<name>truck</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>163</xmin>
			<ymin>123</ymin>
			<xmax>180</xmax>
			<ymax>141</ymax>
		</bndbox>
	</object>
	<object>
		<name>car</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>112</xmin>
			<ymin>146</ymin>
			<xmax>133</xmax>
			<ymax>161</ymax>
		</bndbox>
	</object>
	<object>
		<name>car</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>128</xmin>
			<ymin>136</ymin>
			<xmax>144</xmax>
			<ymax>149</ymax>
		</bndbox>
	</object>
	<object>
		<name>car</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>148</xmin>
			<ymin>135</ymin>
			<xmax>160</xmax>
			<ymax>144</ymax>
		</bndbox>
	</object>
	<object>
		<name>car</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>150</xmin>
			<ymin>142</ymin>
			<xmax>166</xmax>
			<ymax>153</ymax>
		</bndbox>
	</object>
	<object>
		<name>car</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>175</xmin>
			<ymin>138</ymin>
			<xmax>189</xmax>
			<ymax>148</ymax>
		</bndbox>
	</object>
	<object>
		<name>car</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>199</xmin>
			<ymin>147</ymin>
			<xmax>220</xmax>
			<ymax>162</ymax>
		</bndbox>
	</object>
</annotation>


// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
// Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
// ------------------------------------------------------------

#include "Ra.Stdafx.h"

using namespace std;
using namespace Common;
using namespace Reliability;
using namespace ReconfigurationAgentComponent;
using namespace ReplicationComponent;
using namespace ServiceModel;

namespace
{
    StringLiteral const ReadStatusTag("read");
    StringLiteral const WriteStatusTag("write");
}

ComStatefulServicePartition::ComStatefulServicePartition(
    Common::Guid const & partitionId,
    FABRIC_REPLICA_ID replicaId,
    ConsistencyUnitDescription const & consistencyUnitDescription,
    bool hasPersistedState,
    std::weak_ptr<FailoverUnitProxy> && failoverUnitProxyWPtr)
    : ComServicePartitionBase(std::move(failoverUnitProxyWPtr)),
    replicaId_(replicaId),
    isServiceOpened_(false),
    createReplicatorAlreadyCalled_(false),
    partitionInfo_(partitionId, consistencyUnitDescription),
    hasPersistedState_(hasPersistedState),
    partitionId_(partitionId)
{
}

void ComStatefulServicePartition::ClosePartition()
{
    AcquireWriteLock grab(lock_);

    if(!isValidPartition_)
    {
        Assert::CodingError("ComStatefulServicePartition duplicate close call.");
    }

    isValidPartition_ = false;
}

void ComStatefulServicePartition::AssertIsValid(Common::Guid const & partitionId, FABRIC_REPLICA_ID replicaId, FailoverUnitProxy const & owner) const
{
    AcquireReadLock grab(lock_);
    ASSERT_IF(partitionId_ != partitionId, "PartitionId is invalid {0}", owner);
    ASSERT_IF(replicaId_ != replicaId, "ReplicaId is invalid {0}", owner);
    ASSERT_IF(!isValidPartition_, "Partition is closed {0}", owner);
}

HRESULT ComStatefulServicePartition::GetPartitionInfo(FABRIC_SERVICE_PARTITION_INFORMATION const **bufferedValue)
{
    if (!bufferedValue)
    {
        return ComUtility::OnPublicApiReturn(E_POINTER);
    }

    auto error = CheckIfOpen();
    if (!error.IsSuccess())
    {
        return ComUtility::OnPublicApiReturn(error);
    }

    *bufferedValue = partitionInfo_.Value;

    return ComUtility::OnPublicApiReturn(S_OK);
}

HRESULT ComStatefulServicePartition::GetStatus(
    AccessStatusType::Enum type,
    FABRIC_SERVICE_PARTITION_ACCESS_STATUS * valueOut)
{
    if (!valueOut)
    {
        return ComUtility::OnPublicApiReturn(E_POINTER);
    }

    auto error = ErrorCode::Success();
    AccessStatus::Enum accessStatus = AccessStatus::NotPrimary;

    {
        AcquireReadLock grab(lock_);
        error = CheckIfOpen(grab);
        if (!error.IsSuccess())
        {
            return ComUtility::OnPublicApiReturn(error);
        }

        // Read the value from the partition under the lock
        error = readWriteStatus_.TryGet(type, accessStatus);
        if (!error.IsSuccess())
        {
            return ComUtility::OnPublicApiReturn(error);
        }
    }

    if (accessStatus != AccessStatus::NotPrimary)
    {
        FailoverUnitProxySPtr failoverUnitProxy;
        error = LockFailoverUnitProxy(failoverUnitProxy);
        if (!error.IsSuccess())
        {
            return ComUtility::OnPublicApiReturn(error);
        }

        if (failoverUnitProxy->ApplicationHostObj.IsLeaseExpired())
        {
            /*
                This returns whether the lease has expired and not whether the lease has failed

                If the lease has expired then the node goes into arbitration. At this time the read/write status must be TRY_AGAIN (unless already not primary).

                If the node wins arbitration then the lease is no longer expired and the value will be whatever failover determines

                If the node loses arbitration it will go down. In the future we can add an optimization where during the time the node is going down we return NOT_PRIMARY
            */
            auto original = accessStatus;
            accessStatus = AccessStatus::TryAgain;

            RAPEventSource::Events->SFPartitionLeaseExpiredStatus(type == AccessStatusType::Read ? ReadStatusTag : WriteStatusTag, accessStatus, original);
        }
    }

    *valueOut = AccessStatus::ConvertToPublicAccessStatus(accessStatus);

    return ComUtility::OnPublicApiReturn(error);
}

HRESULT ComStatefulServicePartition::GetReadStatus(::FABRIC_SERVICE_PARTITION_ACCESS_STATUS *readStatus)
{
    auto hr = GetStatus(AccessStatusType::Read, readStatus);

    ASSERT_IF(SUCCEEDED(hr) && *readStatus == FABRIC_SERVICE_PARTITION_ACCESS_STATUS_INVALID, "Cannot return invalid read status");
    return hr;
}

HRESULT ComStatefulServicePartition::GetWriteStatus(::FABRIC_SERVICE_PARTITION_ACCESS_STATUS *writeStatus)
{
    auto hr = GetStatus(AccessStatusType::Write, writeStatus);

    ASSERT_IF(SUCCEEDED(hr) && *writeStatus == FABRIC_SERVICE_PARTITION_ACCESS_STATUS_INVALID, "Cannot return invalid write status");
    return hr;
}

ErrorCode ComStatefulServicePartition::Test_IsLeaseExpired(bool & isLeaseExpired)
{
    FailoverUnitProxySPtr failoverUnitProxy;
    auto error = LockFailoverUnitProxy(failoverUnitProxy);
    if (!error.IsSuccess())
    {
        return error;
    }

    isLeaseExpired = failoverUnitProxy->ApplicationHostObj.IsLeaseExpired();
    return error;
}

HRESULT ComStatefulServicePartition::CreateReplicator(
    __in ::IFabricStateProvider *stateProvider,
    __in_opt ::FABRIC_REPLICATOR_SETTINGS const *replicatorSettings,
    __out ::IFabricReplicator **replicator,
    __out ::IFabricStateReplicator **stateReplicator)
{
    FailoverUnitProxySPtr failoverUnitProxySPtr;
    HRESULT hr = PrepareToCreateReplicator(failoverUnitProxySPtr);

    if (!SUCCEEDED(hr))
    {
        return ComUtility::OnPublicApiReturn(hr);
    }

    ASSERT_IFNOT(failoverUnitProxySPtr, "FailoverUnit proxy should be valid");
    FailoverUnitProxySPtr forReplicator = failoverUnitProxySPtr;
    Common::ComPointer<::IFabricStateReplicator> localReplicator;

    hr = failoverUnitProxySPtr->ReplicatorFactory.CreateReplicator(
        replicaId_,
        this,
        stateProvider,
        replicatorSettings,
        hasPersistedState_,
        move(forReplicator),
        localReplicator.InitializationAddress());

    if(FAILED(hr))
    {
        RAPEventSource::Events->SFPartitionFailedToCreateReplicator(
            static_cast<_int64>(replicaId_),
            hr);
        return ComUtility::OnPublicApiReturn(hr);
    }

    hr = localReplicator->QueryInterface(::IID_IFabricReplicator, (LPVOID*) replicator);
    ASSERT_IFNOT(SUCCEEDED(hr), "Built-in replicator failed a QI for IFabricReplicator.");

    hr = localReplicator->QueryInterface(::IID_IFabricStateReplicator, (LPVOID*) stateReplicator);;
    ASSERT_IFNOT(SUCCEEDED(hr), "Built-in replicator failed a QI for IFabricStateReplicator.");

    return ComUtility::OnPublicApiReturn(S_OK);
}

HRESULT ComStatefulServicePartition::ReportLoad(ULONG metricCount, FABRIC_LOAD_METRIC const *metrics)
{
    return ComServicePartitionBase::ReportLoad(metricCount, metrics);
}

HRESULT ComStatefulServicePartition::ReportFault(FABRIC_FAULT_TYPE faultType)
{
    if (
        faultType != FABRIC_FAULT_TYPE_PERMANENT &&
        faultType != FABRIC_FAULT_TYPE_TRANSIENT)
    {
        return ComUtility::OnPublicApiReturn(ErrorCode(ErrorCodeValue::InvalidArgument));
    }

    FailoverUnitProxySPtr failoverUnitProxySPtr;
    auto error = CheckIfOpenAndLockFailoverUnitProxy(failoverUnitProxySPtr);
    if (!error.IsSuccess())
    {
        return ComUtility::OnPublicApiReturn(error);
    }

    error = failoverUnitProxySPtr->ReportFault(FaultType::FromPublicAPI(faultType));
    return ComUtility::OnPublicApiReturn(error);
}

HRESULT ComStatefulServicePartition::ReportReplicaHealth(FABRIC_HEALTH_INFORMATION const *healthInformation)
{
    return ReportReplicaHealth2(healthInformation, nullptr);
}

HRESULT ComStatefulServicePartition::ReportReplicaHealth2(
    FABRIC_HEALTH_INFORMATION const *healthInformation,
    FABRIC_HEALTH_REPORT_SEND_OPTIONS const *sendOptions)
{
    if (!healthInformation)
    {
        return ComUtility::OnPublicApiReturn(E_POINTER);
    }

    HealthInformation healthInfoObj;
    auto error = healthInfoObj.FromCommonPublicApi(*healthInformation);
    if (!error.IsSuccess())
    {
        return ComUtility::OnPublicApiReturn(move(error));
    }

    HealthReportSendOptionsUPtr sendOptionsObj;
    if (sendOptions != nullptr)
    {
        sendOptionsObj = make_unique<HealthReportSendOptions>();
        error = sendOptionsObj->FromPublicApi(*sendOptions);
        if (!error.IsSuccess())
        {
            return ComUtility::OnPublicApiReturn(move(error));
        }
    }

    {
        AcquireReadLock grab(lock_);
        if (!isValidPartition_)
        {
            return ComUtility::OnPublicApiReturn(ErrorCode(ErrorCodeValue::ObjectClosed));
        }
    }

    auto healthReport = ServiceModel::HealthReport::GenerateReplicaHealthReport(move(healthInfoObj), partitionId_, replicaId_);

    FailoverUnitProxySPtr failoverUnitProxySPtr = failoverUnitProxyWPtr_.lock();
    if (failoverUnitProxySPtr)
    {
        error = failoverUnitProxySPtr->ReportHealth(move(healthReport), move(sendOptionsObj));
        return ComUtility::OnPublicApiReturn(move(error));
    }

    return ComUtility::OnPublicApiReturn(FABRIC_E_COMMUNICATION_ERROR);
}

HRESULT ComStatefulServicePartition::ReportPartitionHealth(FABRIC_HEALTH_INFORMATION const *healthInformation)
{
    return ReportPartitionHealth2(healthInformation, nullptr);
}

HRESULT ComStatefulServicePartition::ReportPartitionHealth2(
    FABRIC_HEALTH_INFORMATION const *healthInformation,
    FABRIC_HEALTH_REPORT_SEND_OPTIONS const *sendOptions)
{
    if (!healthInformation)
    {
        return ComUtility::OnPublicApiReturn(E_POINTER);
    }

    HealthInformation healthInfoObj;
    auto error = healthInfoObj.FromCommonPublicApi(*healthInformation);
    if (!error.IsSuccess())
    {
        return ComUtility::OnPublicApiReturn(move(error));
    }

    HealthReportSendOptionsUPtr sendOptionsObj;
    if (sendOptions != nullptr)
    {
        sendOptionsObj = make_unique<HealthReportSendOptions>();
        error = sendOptionsObj->FromPublicApi(*sendOptions);
        if (!error.IsSuccess())
        {
            return ComUtility::OnPublicApiReturn(move(error));
        }
    }

    {
        AcquireReadLock grab(lock_);
        if (!isValidPartition_)
        {
            return ComUtility::OnPublicApiReturn(ErrorCode(ErrorCodeValue::ObjectClosed));
        }
    }

    auto healthReport = ServiceModel::HealthReport::GeneratePartitionHealthReport(move(healthInfoObj), partitionId_);

    FailoverUnitProxySPtr failoverUnitProxySPtr = failoverUnitProxyWPtr_.lock();
    if (failoverUnitProxySPtr)
    {
        error = failoverUnitProxySPtr->ReportHealth(move(healthReport), move(sendOptionsObj));
        return ComUtility::OnPublicApiReturn(move(error));
    }

    return ComUtility::OnPublicApiReturn(FABRIC_E_COMMUNICATION_ERROR);
}

HRESULT ComStatefulServicePartition::ReportMoveCost(FABRIC_MOVE_COST moveCost)
{
    FailoverUnitProxySPtr failoverUnitProxySPtr;
    auto error = CheckIfOpenAndLockFailoverUnitProxy(failoverUnitProxySPtr);
    if (!error.IsSuccess())
    {
        return ComUtility::OnPublicApiReturn(error);
    }

    vector<LoadBalancingComponent::LoadMetric> loadMetrics;
    std::wstring moveCostMetricName(*LoadBalancingComponent::Constants::MoveCostMetricName);
    loadMetrics.push_back(LoadBalancingComponent::LoadMetric(move(moveCostMetricName), moveCost));

    error = failoverUnitProxySPtr->ReportLoad(move(loadMetrics));
    return ComUtility::OnPublicApiReturn(error);
}

HRESULT ComStatefulServicePartition::CreateTransactionalReplicator(
    __in ::IFabricStateProvider2Factory * factory,
    __in ::IFabricDataLossHandler * dataLossHandler,
    __in_opt ::FABRIC_REPLICATOR_SETTINGS const *replicatorSettings,
    __in_opt ::TRANSACTIONAL_REPLICATOR_SETTINGS const * transactionalReplicatorSettings,
    __in_opt KTLLOGGER_SHARED_LOG_SETTINGS const * ktlloggerSharedSettings,
    __out ::IFabricPrimaryReplicator ** primaryReplicator,
    __out void ** transactionalReplicator)
{
    FailoverUnitProxySPtr failoverUnitProxySPtr;
    Common::ComPointer<IFabricCodePackageActivationContext> activationContext;

    HRESULT hr = PrepareToCreateReplicator(failoverUnitProxySPtr);

    if (!SUCCEEDED(hr))
    {
        return ComUtility::OnPublicApiReturn(hr);
    }

    ASSERT_IFNOT(failoverUnitProxySPtr, "FailoverUnit proxy should be valid");

    ErrorCode error = failoverUnitProxySPtr->ApplicationHostObj.GetCodePackageActivationContext(
        failoverUnitProxySPtr->RuntimeId,
        activationContext);

    if (!error.IsSuccess())
    {
        return ComUtility::OnPublicApiReturn(error);
    }

    FailoverUnitProxySPtr forReplicator = failoverUnitProxySPtr;

    hr = failoverUnitProxySPtr->TransactionalReplicatorFactory.CreateReplicator(
        replicaId_,
        failoverUnitProxySPtr->ReplicatorFactory,
        this,
        replicatorSettings,
        transactionalReplicatorSettings,
        ktlloggerSharedSettings,
        *activationContext.GetRawPointer(),
        hasPersistedState_,
        move(forReplicator),
        factory,
        dataLossHandler,
        primaryReplicator,
        (PHANDLE)transactionalReplicator);

    if (FAILED(hr))
    {
        RAPEventSource::Events->SFPartitionFailedToCreateReplicator(
            static_cast<_int64>(replicaId_),
            hr);
    }

    return ComUtility::OnPublicApiReturn(hr);
}

HRESULT ComStatefulServicePartition::CreateTransactionalReplicatorInternal(
    __in ::IFabricTransactionalReplicatorRuntimeConfigurations * runtimeConfigurations,
    __in ::IFabricStateProvider2Factory * factory,
    __in ::IFabricDataLossHandler * dataLossHandler,
    __in_opt ::FABRIC_REPLICATOR_SETTINGS const *replicatorSettings,
    __in_opt ::TRANSACTIONAL_REPLICATOR_SETTINGS const * transactionalReplicatorSettings,
    __in_opt KTLLOGGER_SHARED_LOG_SETTINGS const * ktlloggerSharedSettings,
    __out ::IFabricPrimaryReplicator ** primaryReplicator,
    __out void ** transactionalReplicator)
{
    if (!runtimeConfigurations)
    {
        return ComUtility::OnPublicApiReturn(E_POINTER);
    }

    FailoverUnitProxySPtr failoverUnitProxySPtr;
    HRESULT hr = PrepareToCreateReplicator(failoverUnitProxySPtr);

    if (!SUCCEEDED(hr))
    {
        return ComUtility::OnPublicApiReturn(hr);
    }

    FailoverUnitProxySPtr forReplicator = failoverUnitProxySPtr;

    hr = failoverUnitProxySPtr->TransactionalReplicatorFactory.CreateReplicator(
        replicaId_,
        failoverUnitProxySPtr->ReplicatorFactory,
        this,
        replicatorSettings,
        transactionalReplicatorSettings,
        ktlloggerSharedSettings,
        runtimeConfigurations,
        hasPersistedState_,
        move(forReplicator),
        factory,
        dataLossHandler,
        primaryReplicator,
        (PHANDLE)transactionalReplicator);

    if (FAILED(hr))
    {
        RAPEventSource::Events->SFPartitionFailedToCreateReplicator(
            static_cast<_int64>(replicaId_),
            hr);
    }

    return ComUtility::OnPublicApiReturn(hr);
}

HRESULT ComStatefulServicePartition::GetKtlSystem(
    __out void** ktlSystem)
{
    FailoverUnitProxySPtr failoverUnitProxySPtr = failoverUnitProxyWPtr_.lock();
    if (!failoverUnitProxySPtr)
    {
        RAPEventSource::Events->SFPartitionCouldNotGetFUP(static_cast<_int64>(replicaId_));
        return ComUtility::OnPublicApiReturn(ErrorCode(ErrorCodeValue::ObjectClosed));
    }

    KtlSystem * ktlSystemPtr = nullptr;
    ErrorCode error = failoverUnitProxySPtr->ApplicationHostObj.GetKtlSystem(&ktlSystemPtr);
    if (!error.IsSuccess())
    {
        return ComUtility::OnPublicApiReturn(error);
    }

    *ktlSystem = ktlSystemPtr;
    return ComUtility::OnPublicApiReturn(error);
}

void ComStatefulServicePartition::SetReadWriteStatus(ReadWriteStatusValue && value)
{
    AcquireWriteLock grab(lock_);
    readWriteStatus_ = move(value);
}

void ComStatefulServicePartition::OnServiceOpened()
{
    AcquireWriteLock grab(lock_);

    isServiceOpened_ = true;
}

FABRIC_SERVICE_PARTITION_ACCESS_STATUS ComStatefulServicePartition::GetReadStatusForQuery()
{
    FABRIC_SERVICE_PARTITION_ACCESS_STATUS rv = FABRIC_SERVICE_PARTITION_ACCESS_STATUS_INVALID;
    HRESULT hr = GetReadStatus(&rv);
    if (FAILED(hr))
    {
        return FABRIC_SERVICE_PARTITION_ACCESS_STATUS_INVALID;
    }

    return rv;
}

FABRIC_SERVICE_PARTITION_ACCESS_STATUS ComStatefulServicePartition::GetWriteStatusForQuery()
{
    FABRIC_SERVICE_PARTITION_ACCESS_STATUS rv = FABRIC_SERVICE_PARTITION_ACCESS_STATUS_INVALID;
    HRESULT hr = GetWriteStatus(&rv);
    if (FAILED(hr))
    {
        return FABRIC_SERVICE_PARTITION_ACCESS_STATUS_INVALID;
    }

    return rv;
}

HRESULT ComStatefulServicePartition::PrepareToCreateReplicator(__out FailoverUnitProxySPtr & failoverUnitProxySPtr)
{
    RAPEventSource::Events->SFPartitionCreatingReplicator(static_cast<_int64>(replicaId_));
    AcquireWriteLock grab(lock_);

    if (!isValidPartition_)
    {
        RAPEventSource::Events->SFPartitionInvalidReplica(static_cast<_int64>(replicaId_));
        return ErrorCode(ErrorCodeValue::ObjectClosed).ToHResult();
    }

    if (createReplicatorAlreadyCalled_ || isServiceOpened_)
    {
        RAPEventSource::Events->SFPartitionReplicaAlreadyOpen(
            static_cast<_int64>(replicaId_),
            isServiceOpened_,
            createReplicatorAlreadyCalled_);
        return ErrorCode(ErrorCodeValue::InvalidState).ToHResult();
    }

    createReplicatorAlreadyCalled_ = true;

    failoverUnitProxySPtr = failoverUnitProxyWPtr_.lock();

    if (!failoverUnitProxySPtr)
    {
        RAPEventSource::Events->SFPartitionCouldNotGetFUP(static_cast<_int64>(replicaId_));
        return ErrorCode(ErrorCodeValue::ObjectClosed).ToHResult();
    }

    return S_OK;
}