text:
describe "brew prune", :integration_test do
  it "removes empty directories and broken symlinks" do
    share = (HOMEBREW_PREFIX/"share")

    (share/"pruneable/directory/here").mkpath
    (share/"notpruneable/file").write "I'm here"
    FileUtils.ln_s "/i/dont/exist/no/really/i/dont", share/"pruneable_symlink"

    expect { brew "prune", "--dry-run" }
      .to output(%r{Would remove \(empty directory\): .*/pruneable/directory/here}).to_stdout
      .and not_to_output.to_stderr
      .and be_a_success

    expect { brew "prune" }
      .to output(/Pruned 1 symbolic links and 3 directories/).to_stdout
      .and not_to_output.to_stderr
      .and be_a_success

    expect(share/"pruneable").not_to be_a_directory
    expect(share/"notpruneable").to be_a_directory
    expect(share/"pruneable_symlink").not_to be_a_symlink

    expect { brew "prune", "--verbose" }
      .to output(/Nothing pruned/).to_stdout
      .and not_to_output.to_stderr
      .and be_a_success
  end
end


text:
<script type="text/javascript">
	<bx_if:onsignal>
	/* One Signal  Push Notifications Init Begin */
		var OneSignal = window.OneSignal || [];
		OneSignal.push(["init", {
									appId: '__one_signal_api__',
									autoRegister: true, /* Set to true to automatically prompt visitors */
									subdomainName: '__short_name__', /* required only for http  sites */
									safari_web_id: '__safari_key__',
									persistNotification: false,
									welcomeNotification:{
															disable:false
															},
									httpPermissionRequest: {
															enable: true
														  },
									promptOptions: {
															/* These prompt options values configure both the HTTP prompt and the HTTP popup. */
															/* actionMessage limited to 90 characters */
															actionMessage: '__notification_request__',
															/* acceptButtonText limited to 15 characters */
															acceptButtonText: '__notification_request_yes__',
															/* cancelButtonText limited to 15 characters */
															cancelButtonText: '__notification_request_no__'
														}
								 }
					]);

		OneSignal.push(function() {
			var isPushSupported = OneSignal.isPushNotificationsSupported();
				OneSignal.setDefaultNotificationUrl('__jot_chat_page_url__');
				OneSignal.isPushNotificationsEnabled().then(
		        function(isEnabled) {
							OneSignal.sendTag('user', __profile_id__); // set tag for onesiganl, this tag will be used to send notification
									if (!isEnabled && isPushSupported)
												OneSignal.showHttpPermissionRequest();
				});
		});
	/*  One Signal Push Notifications Init End */
	</bx_if:onsignal>

	if (oRTWSF != undefined)
	{
			oRTWSF.init({
				server:'__server_url__',
				ip:'__ip__'
			});
	}

	oMessenger.init({
				emoji:{
						emojiable_selector: '[data-emojiable=true]',
						assetsPath: 'modules/boonex/messenger/template/images/emoji',
						popupButtonClasses: 'sys-icon smile-o',
						type_smiles:__smiles__
					  },
				oRTWSF:oRTWSF,
				user_id:__profile_id__,
				max:__message_length__
	});

	window.aDolLang	=	{
							'_bx_messenger_online':'__online__',
							'_bx_messenger_offline':'__offline__',
							'_bx_messenger_away':'__away__',
							'_bx_messenger_repost_message': '__repost_of_the_message__'
						}
</script>

redpajama_set_name: RedPajamaGithub


text:
namespace Construktion.Tests.Registry
{
    using System;
    using Shouldly;

    public class RegisteredInstanceTests
    {
        private readonly ConstruktionRegistry registry;
        private readonly Construktion construktion;

        public RegisteredInstanceTests()
        {
            registry = new ConstruktionRegistry();
            construktion = new Construktion();
        }

        public void should_register_instance_with_contract()
        {
            registry.Register<IFoo, Foo>();

            var result = construktion.Apply(registry).Construct<IFoo>();

            result.ShouldBeOfType<Foo>();
        }

        public void last_registered_instance_should_be_chosen()
        {
            registry.Register<IFoo, Foo>();
            registry.Register<IFoo, Foo2>();

            var result = construktion.Apply(registry).Construct<IFoo>();

            result.ShouldBeOfType<Foo2>();
        }

        public void should_register_scoped_instance()
        {
            var foo = new Foo { FooId = -1 };
            registry.UseInstance<IFoo>(foo);

            var result = construktion.Apply(registry).Construct<IFoo>();

            var fooResult = result.ShouldBeOfType<Foo>();
            fooResult.FooId.ShouldBe(-1);
            fooResult.GetHashCode().ShouldBe(foo.GetHashCode());
        }

        public void should_use_last_scoped_instance_registered()
        {
            var foo = new Foo();
            var foo2 = new Foo();
            registry.UseInstance<IFoo>(foo);
            registry.UseInstance<IFoo>(foo2);

            construktion.Apply(registry);

            var result = construktion.Construct<IFoo>();

            result.GetHashCode().ShouldBe(foo2.GetHashCode());
        }

        public void should_use_instance_across_graph()
        {
            var foo = new Foo();
            registry.UseInstance<IFoo>(foo);

            construktion.Apply(registry);

            var result = construktion.Construct<FooCollector>();

            result.CtorFoo.GetHashCode().ShouldBe(foo.GetHashCode());
            result.PropertyFoo.GetHashCode().ShouldBe(foo.GetHashCode());
        }

        public void should_throw_when_interface_isnt_registered()
        {
            //_blueprintRegistry.Register<IFoo, Foo>();

            Exception<Exception>.ShouldBeThrownBy(() => construktion.Apply(registry).Construct<IFoo>())
                                .Message
                                .ShouldContain("Cannot construct the interface IFoo.");
        }

        public interface IFoo { }

        public class Foo : IFoo
        {
            public int FooId { get; set; }
        }

        public class Foo2 : IFoo { }

        public class FooCollector
        {
            public IFoo CtorFoo { get; }
            public IFoo PropertyFoo { get; set; }

            public FooCollector(IFoo foo)
            {
                CtorFoo = foo;
            }
        }
    }
}


text:
// Copyright 2014 Google Inc.  All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License.  You may obtain a copy
// of the License at: http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distrib-
// uted 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
// specific language governing permissions and limitations under the License.

// Author: shakusa@google.com (Steve Hakusa)

function CreateTopicsCommandTest() {
  this.mapModel_ = cm.MapModel.newFromMapRoot({
    'id': 'map1',
    'layers': [
      {'id': '1', title: 'Layer One', type: 'KML'},
      {'id': '2', title: 'Layer Two', type: 'KML'}
    ],
    'topics': [
      {'id': 't1', 'title': 'Topic One', 'layer_ids': ['1']},
      {'id': 't2', 'title': 'Topic Two', 'layer_ids': ['2']}
    ]
  });
  this.appState_ = new cm.AppState();
}
registerTestSuite(CreateTopicsCommandTest);

/**
 * Test that execute() and undo() for a single topic.
 */
CreateTopicsCommandTest.prototype.testExecuteUndoSingle = function() {
  var command = new cm.CreateTopicsCommand({
    'title': 'Topic Three', 'layer_ids_': ['1', '2']
  });

  command.execute(this.appState_, this.mapModel_);
  expectThat(this.mapModel_.getTopic('topic_three'), not(isUndefined));
  expectThat(this.mapModel_.getTopicIds(),
      elementsAre(['t1', 't2', 'topic_three']));

  command.undo(this.appState_, this.mapModel_);
  expectThat(this.mapModel_.getTopic('topic_three'), isUndefined);
  expectThat(this.mapModel_.getTopicIds(), elementsAre(['t1', 't2']));

  // redo
  command.execute(this.appState_, this.mapModel_);
  expectThat(this.mapModel_.getTopic('topic_three'), not(isUndefined));
  expectThat(this.mapModel_.getTopicIds(),
      elementsAre(['t1', 't2', 'topic_three']));
};

/**
 * Test that execute() and undo() for multiple topics.
 */
CreateTopicsCommandTest.prototype.testExecuteMultiple = function() {
  var command = new cm.CreateTopicsCommand([
      {'title': 'Topic Four', 'layer_ids': ['2']},
      {'title': 'Topic Five', 'layer_ids': ['1', '2']}
  ]);

  command.execute(this.appState_, this.mapModel_);
  expectThat(this.mapModel_.getTopic('topic_four'), not(isUndefined));
  expectThat(this.mapModel_.getTopic('topic_five'), not(isUndefined));
  expectThat(this.mapModel_.getTopicIds(),
      elementsAre(['t1', 't2', 'topic_four', 'topic_five']));

  command.undo(this.appState_, this.mapModel_);
  expectThat(this.mapModel_.getTopic('topic_four'), isUndefined);
  expectThat(this.mapModel_.getTopic('topic_five'), isUndefined);
  expectThat(this.mapModel_.getTopicIds(), elementsAre(['t1', 't2']));

  // redo
  command.execute(this.appState_, this.mapModel_);
  expectThat(this.mapModel_.getTopic('topic_four'), not(isUndefined));
  expectThat(this.mapModel_.getTopic('topic_five'), not(isUndefined));
  expectThat(this.mapModel_.getTopicIds(),
      elementsAre(['t1', 't2', 'topic_four', 'topic_five']));
};


text:
/*
 * Created by SharpDevelop.
 * User: Number One
 * Date: 11/23/2014
 * Time: 9:51 PM
 *
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;

namespace Win32Wrapper
{
	public enum ThreadPriority
	{
		THREAD_MODE_BACKGROUND_BEGIN = 0x00010000,
		THREAD_MODE_BACKGROUND_END = 0x00020000,
		THREAD_PRIORITY_ABOVE_NORMAL = 1,
		THREAD_PRIORITY_BELOW_NORMAL = -1,
		THREAD_PRIORITY_HIGHEST = 2,
		THREAD_PRIORITY_IDLE = -15,
		THREAD_PRIORITY_LOWEST = -2,
		THREAD_PRIORITY_NORMAL = 0,
		THREAD_PRIORITY_TIME_CRITICAL = 15
	}
}


text:
layout: post
title: "[TT]Error Solving in Ruby on Rails Tutorial's Book"
date: 2015-01-10 15:05:17 +0700
comments: true
categories:
tags:
thumbnail:
---
 Postingan ini belum selesai

Beberapa kali saya menjumpai error atau ketidakberesan saat mengaplikasikan tutorial di buku Ruby on Rails Tutorials by Michael Hart. Untungnya saya punya pakar yang bisa ditanya-tanyain karena saya emang dudul banget dalam hal ini *lirik Tuan*, yah walau kadang kalo dia lagi sumpek saya jadi kena semprot sih muehehehehe
Baiklah, sebelum mengaplikasikan buku RoR ini, pastikan kamu memakai Rails version 3 dan Ruby version 1.9.3. Gimana ngeceknya? Ketik aja di terminal `rails -v` untuk ngecek versi Rails yang terinstall dan `ruby -v` untuk ngecek versi Ruby-nya. Supaya lebih gampang, semua project kamu jadikan satu folder tersendiri (kalau puya saya ebook_app), baru di dalamnya kamu isi dengan project-project yang ada di tutorial tersebut.


text:
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Serialization;
using Cuemon.Collections.Generic;
using Cuemon.Reflection;
using Cuemon.Xml.Linq;

namespace Cuemon.Xml.Serialization.Converters
{
    /// <summary>
    /// Provides a default way to convert objects to and from XML.
    /// </summary>
    public sealed class DefaultXmlConverter : XmlConverter
    {
        private const string EnumerableElementName = "Item";
        private const string XmlWriterMethod = "WriteXml";

        /// <summary>
        /// Initializes a new instance of the <see cref="DefaultXmlConverter"/> class.
        /// </summary>
        public DefaultXmlConverter(XmlQualifiedEntity rootName, IList<XmlConverter> converters)
        {
            RootName = rootName;
            Converters = converters ?? new List<XmlConverter>();
        }

        private XmlQualifiedEntity RootName { get; }

        private IList<XmlConverter> Converters { get; }

        /// <summary>
        /// Converts an object into its XML representation.
        /// </summary>
        /// <param name="writer">The <see cref="XmlWriter" /> stream to which the object is serialized.</param>
        /// <param name="value">The object to convert.</param>
        /// <param name="elementName">The element name to encapsulate around <paramref name="value" />.</param>
        /// <exception cref="InvalidOperationException">There is an error in the XML document.</exception>
        public override void WriteXml(XmlWriter writer, object value, XmlQualifiedEntity elementName = null)
        {
            Decorator.Enclose(writer).WriteXmlRootElement(value, WriteXmlNodes, elementName ?? RootName);
        }

        /// <summary>
        /// Generates an object from its XML representation.
        /// </summary>
        /// <param name="reader">The <see cref="XmlReader" /> stream from which the object is deserialized.</param>
        /// <param name="objectType">The <see cref="Type"/> of the object to generate.</param>
        /// <returns>The generated (deserialized) object.</returns>
        public override object ReadXml(XmlReader reader, Type objectType)
        {
            Validator.ThrowIfNull(reader, nameof(reader));
            Validator.ThrowIfNull(objectType, nameof(objectType));
            if (Decorator.Enclose(objectType).HasEnumerableImplementation() && objectType != typeof(string))
            {
                if (Decorator.Enclose(objectType).HasDictionaryImplementation())
                {
                    return ParseReadXmlDictionary(reader, objectType);
                }
                return ParseReadXmlEnumerable(reader, objectType);
            }
            var valueTypeInfo = objectType.GetTypeInfo();
            if (valueTypeInfo.IsPrimitive ||
                objectType == typeof(string) ||
                objectType == typeof(Guid) ||
                objectType == typeof(decimal))
            {
                return ParseReadXmlSimple(reader, objectType);
            }
            return ParseReadXmlDefault(reader, objectType);
        }

        /// <summary>
        /// Determines whether this instance can convert the specified object type.
        /// </summary>
        /// <param name="objectType">The <seealso cref="Type" /> of the object.</param>
        /// <returns><c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.</returns>
        public override bool CanConvert(Type objectType)
        {
            return true;
        }

        private static object ParseReadXmlDictionary(XmlReader reader, Type valueType)
        {
            var values = new Dictionary<string, string>();
            var hierarchy = Decorator.Enclose(reader).ToHierarchy();
            var items = Decorator.Enclose(hierarchy).Find(h => h.Instance.Name == EnumerableElementName && h.Depth == 1).ToList();
            foreach (var item in items)
            {
                if (item.HasChildren)
                {
                    try
                    {
                        var key = item.GetChildren().SingleOrDefault();
                        var value = key?.GetChildren().SingleOrDefault();
                        if (value != null)
                        {
                            values.Add(key.Instance.Value.ToString(), value.Instance.Value.ToString());
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new NotSupportedException("Deserialization of complex objects is not supported in this version.", ex);
                    }
                }
            }

            var dictionaryType = valueType.GetGenericArguments().Length > 0 ? valueType.GetGenericArguments() : new[] { typeof(object), typeof(object) };
            var dictionary = typeof(Dictionary<,>).MakeGenericType(dictionaryType);
            var castedValues = values.Select(pair => Template.CreateTwo(Decorator.Enclose(pair.Key).ChangeType(dictionaryType[0]), Decorator.Enclose(pair.Value).ChangeType(dictionaryType[1]))).ToList();
            var instance = Activator.CreateInstance(dictionary);
            var addMethod = valueType.GetMethod("Add");
            foreach (var item in castedValues)
            {
                addMethod.Invoke(instance, new[] { item.Arg1, item.Arg2 });
            }
            return instance;
        }

        private static object ParseReadXmlEnumerable(XmlReader reader, Type valueType)
        {
            var values = new List<KeyValuePair<string, string>>();
            var hierarchy = Decorator.Enclose(reader).ToHierarchy();
            var items = Decorator.Enclose(hierarchy).Find(h => h.Instance.Name == EnumerableElementName && h.Depth == 1).ToList();
            if (items.FirstOrDefault()?.HasChildren ?? false) { throw new NotSupportedException("Deserialization of complex objects is not supported in this version."); }
            values.AddRange(items.Select(h => new KeyValuePair<string, string>(h.Instance.Name, h.Instance.Value.ToString())));

            var enumerableType = valueType.GetGenericArguments().FirstOrDefault() ?? typeof(object);
            var listEnumerable = typeof(List<>).MakeGenericType(enumerableType);
            var castedValues = values.Where(pair => pair.Key == EnumerableElementName).Select(pair => Decorator.Enclose(pair.Value).ChangeType(enumerableType)).ToList();
            var instance = Activator.CreateInstance(listEnumerable);
            var addMethod = valueType.GetMethod("Add");
            foreach (var item in castedValues)
            {
                addMethod.Invoke(instance, new[] { item });
            }
            return instance;
        }

        private static object ParseReadXmlSimple(XmlReader reader, Type valueType)
        {
            string simpleValue = null;
            try
            {
                while (reader.Read())
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.CDATA:
                        case XmlNodeType.Text:
                            simpleValue = reader.Value;
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                throw new NotSupportedException("Deserialization of complex objects is not supported in this version.", ex);
            }
            return TypeDescriptor.GetConverter(valueType).ConvertFromInvariantString(simpleValue);
        }

        private static object ParseReadXmlDefault(XmlReader reader, Type valueType)
        {
            var key = "";
            var values = new Dictionary<string, string>();
            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Attribute:
                        values.Add(reader.Name, reader.Value);
                        while (reader.MoveToNextAttribute()) { goto case XmlNodeType.Attribute; }
                        reader.MoveToElement();
                        break;
                    case XmlNodeType.Element:
                        if (reader.Depth == 0) { continue; }
                        key = reader.Name;
                        if (reader.HasAttributes && reader.MoveToFirstAttribute()) { goto case XmlNodeType.Attribute; }
                        break;
                    case XmlNodeType.CDATA:
                    case XmlNodeType.Text:
                        Decorator.Enclose(values).AddOrUpdate(key, reader.Value);
                        break;
                }
            }

            var hasDefaultCtor = false;
            var constructors = valueType.GetConstructors(new MemberReflection(excludeStatic: true)).ToList();
            var properties = valueType.GetProperties(new MemberReflection(excludeStatic: true)).Where(info => info.CanWrite).ToDictionary(info => info.Name);
            var propertyNames = properties.Select(info => info.Key).Intersect(values.Select(pair => pair.Key), StringComparer.OrdinalIgnoreCase).ToList();

            var args = new List<object>();
            foreach (var ctr in constructors)
            {
                var arguments = ctr.GetParameters();
                var argumentsLength = arguments.Select(info => info.Name).Intersect(values.Select(pair => pair.Key), StringComparer.OrdinalIgnoreCase).Count();
                if (arguments.Length == argumentsLength)
                {
                    if (!hasDefaultCtor && argumentsLength == 0) { hasDefaultCtor = true; }
                    foreach (var arg in arguments)
                    {
                        args.Add(Decorator.Enclose(values.First(pair => pair.Key.Equals(arg.Name, StringComparison.OrdinalIgnoreCase)).Value).ChangeType(arg.ParameterType));
                    }
                    break;
                }
            }

            if (args.Count == 0)
            {
                var staticMethods = valueType.GetMethods(new MemberReflection(excludeInheritancePath: true)).Where(info => info.ReturnType == valueType && info.IsStatic && !info.IsSpecialName).ToList();
                foreach (var method in staticMethods)
                {
                    var arguments = method.GetParameters();
                    var argumentsLength = arguments.Select(info => info.Name).Intersect(values.Select(pair => pair.Key), StringComparer.OrdinalIgnoreCase).Count();
                    if (arguments.Length == argumentsLength)
                    {
                        foreach (var arg in arguments)
                        {
                            args.Add(Decorator.Enclose(values.First(pair => pair.Key.Equals(arg.Name, StringComparison.OrdinalIgnoreCase)).Value).ChangeType(arg.ParameterType));
                        }
                        return method.Invoke(null, args.ToArray());
                    }
                }
                if (!hasDefaultCtor) { throw new SerializationException("Unable to find a suitable constructor or static method for deserialization."); }
            }

            var instance = Activator.CreateInstance(valueType, args.ToArray());
            foreach (var propertyName in propertyNames)
            {
                var property = properties[propertyName];
                property.SetValue(instance, Decorator.Enclose(values.First(pair => pair.Key == propertyName).Value).ChangeType(property.PropertyType));
            }
            return instance;
        }

        private void WriteXmlNodes(XmlWriter writer, IHierarchy<object> node)
        {
            if (Decorator.Enclose(node).HasXmlIgnoreAttribute()) { return; }

            var writerMethod = node.InstanceType.GetMethod(XmlWriterMethod, new MemberReflection(excludeStatic: true));
            var useWriterMethod = (writerMethod != null) && Decorator.Enclose(node.InstanceType).HasInterface(typeof(IXmlSerializable));

            if (useWriterMethod)
            {
                writerMethod.Invoke(node.Instance, new object[] { writer });
            }
            else
            {
                Condition.FlipFlop(node.HasChildren, WriteXmlChildren, WriteXmlValue, writer, node);
            }
        }

        private void WriteXmlValue(XmlWriter writer, IHierarchy<object> node)
        {
            if (Decorator.Enclose(node).IsNodeEnumerable()) { return; }

            var hasTextAttribute = Decorator.Enclose(node).TryGetXmlTextAttribute(out _);
            var qualifiedEntity = Decorator.Enclose(node).GetXmlQualifiedEntity();
            var hasElementAttribute = qualifiedEntity.HasXmlElementDecoration;

            if (!qualifiedEntity.HasXmlAttributeDecoration && !qualifiedEntity.HasXmlElementDecoration && !hasTextAttribute)
            {
                hasElementAttribute = true; // default serialization value for legacy Cuemon
                var isType = node.Instance is Type;
                var nodeType = isType ? (Type)node.Instance : node.InstanceType;
                if ((!Decorator.Enclose(nodeType).IsComplex() || isType) && !node.HasChildren && isType)
                {
                    if (!node.HasParent)
                    {
                        hasElementAttribute = false;
                    }
                    hasTextAttribute = true;
                }
            }

            var value = Wrapper.ParseInstance(node);
            if (qualifiedEntity.HasXmlAttributeDecoration)
            {
                writer.WriteAttributeString(qualifiedEntity.Prefix, qualifiedEntity.LocalName, qualifiedEntity.Namespace, value);
            }
            else if (hasElementAttribute)
            {
                WriteXmlElement(writer, node, qualifiedEntity, value);
            }
            else if (hasTextAttribute) // catch all (eg. non-decorated properties or XmlTextAttribute)
            {
                writer.WriteString(value);
            }
        }

        private static void WriteXmlElement(XmlWriter writer, IHierarchy<object> node, XmlQualifiedEntity qualifiedEntity, string value)
        {
            if (node.HasMemberReference)
            {
                writer.WriteElementString(qualifiedEntity.Prefix, qualifiedEntity.LocalName, qualifiedEntity.Namespace, value);
            }
            else
            {
                if (Decorator.Enclose(value).IsXmlString())
                {
                    writer.WriteCData(value);
                }
                else
                {
                    writer.WriteString(value);
                }
            }
        }

        private void WriteXmlChildren(XmlWriter writer, IHierarchy<object> node)
        {
            foreach (var childNode in Decorator.Enclose(node.GetChildren()).OrderByXmlAttributes())
            {
                if (Decorator.Enclose(childNode).HasXmlIgnoreAttribute()) { continue; }
                if (!childNode.InstanceType.GetTypeInfo().IsValueType && childNode.Instance == null) { continue; }
                if (SkipIfNullOrEmptyEnumerable(childNode)) { continue; }
                var qualifiedEntity = Decorator.Enclose(childNode).GetXmlQualifiedEntity();
                if (qualifiedEntity.HasXmlAttributeDecoration && node.HasMemberReference)
                {
                    writer.WriteAttributeString(qualifiedEntity.Prefix, qualifiedEntity.LocalName, qualifiedEntity.Namespace, Wrapper.ParseInstance(childNode));
                }
                else
                {
                    WriteXmlChildrenEncapsulated(writer, childNode, qualifiedEntity);
                }
            }
        }

        private static bool SkipIfNullOrEmptyEnumerable(IHierarchy<object> childNode)
        {
            if (Decorator.Enclose(childNode.InstanceType).HasEnumerableImplementation() && childNode.InstanceType != typeof(string) && !Decorator.Enclose(childNode.InstanceType).HasDictionaryImplementation())
            {
                var i = childNode.Instance as IEnumerable;
                if (i == null || !i.Cast<object>().Any()) { return true; }
            }
            return false;
        }

        private void WriteXmlChildrenEncapsulated(XmlWriter writer, IHierarchy<object> childNode, XmlQualifiedEntity qualifiedEntity)
        {
            var encapsulate = childNode.HasChildren && Decorator.Enclose(childNode.InstanceType).IsComplex();
            if (encapsulate) { Decorator.Enclose(writer).WriteStartElement(qualifiedEntity); }
            var converter = Decorator.Enclose(Converters).FirstOrDefaultWriterConverter(childNode.InstanceType);
            if (converter != null && !qualifiedEntity.HasXmlAttributeDecoration)
            {
                converter.WriteXml(writer, childNode.Instance, qualifiedEntity);
            }
            else
            {
                WriteXmlNodes(writer, childNode);
            }
            if (encapsulate) { writer.WriteEndElement(); }
        }
    }
}


text:
package org.lastaflute.di.core.smart.hot;

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

import org.lastaflute.di.DisposableUtil;
import org.lastaflute.di.core.ComponentDef;
import org.lastaflute.di.core.LaContainer;
import org.lastaflute.di.core.creator.ComponentCreator;
import org.lastaflute.di.core.factory.SingletonLaContainerFactory;
import org.lastaflute.di.core.meta.impl.LaContainerBehavior.DefaultProvider;
import org.lastaflute.di.core.meta.impl.LaContainerImpl;
import org.lastaflute.di.core.util.ComponentUtil;
import org.lastaflute.di.helper.log.LaLogger;
import org.lastaflute.di.naming.NamingConvention;

/**
 * @author modified by jflute (originated in Seasar)
 */
public class HotdeployBehavior extends DefaultProvider {

    // ===================================================================================
    //                                                                          Definition
    //                                                                          ==========
    private static final LaLogger logger = LaLogger.getLogger(HotdeployBehavior.class);

    // ===================================================================================
    //                                                                           Attribute
    //                                                                           =========
    private ClassLoader originalClassLoader;
    private HotdeployClassLoader hotdeployClassLoader;
    private Map<Object, ComponentDef> componentDefCache = new HashMap<Object, ComponentDef>();
    private NamingConvention namingConvention;
    private ComponentCreator[] creators = new ComponentCreator[0];

    public static final String keep_BINDING = "bindingType=may";
    private boolean keep;

    // ===================================================================================
    //                                                                              Option
    //                                                                              ======
    public void setKeep(boolean keep) {
        this.keep = keep;
        if (hotdeployClassLoader != null) {
            finish();
        }
    }

    // ===================================================================================
    //                                                                       Determination
    //                                                                       =============
    public boolean isLaContainerHotdeploy() {
        return SingletonLaContainerFactory.getContainer().getClassLoader() instanceof HotdeployClassLoader;
    }

    public boolean isThreadContextHotdeploy() {
        return Thread.currentThread().getContextClassLoader() instanceof HotdeployClassLoader;
    }

    // ===================================================================================
    //                                                                      Start and Stop
    //                                                                      ==============
    public void start() {
        originalClassLoader = Thread.currentThread().getContextClassLoader();
        if (!keep || hotdeployClassLoader == null) {
            hotdeployClassLoader = new HotdeployClassLoader(originalClassLoader, namingConvention);
        }
        Thread.currentThread().setContextClassLoader(hotdeployClassLoader);
        LaContainer container = SingletonLaContainerFactory.getContainer();
        container.setClassLoader(hotdeployClassLoader);
    }

    public void stop() {
        if (!keep) {
            finish();
        }
        LaContainer container = SingletonLaContainerFactory.getContainer();
        container.setClassLoader(originalClassLoader);
        Thread.currentThread().setContextClassLoader(originalClassLoader);
        originalClassLoader = null;
    }

    public void finish() {
        componentDefCache.clear();
        hotdeployClassLoader = null;
        DisposableUtil.dispose();
    }

    // ===================================================================================
    //                                                                       Core Override
    //                                                                       =============
    @Override
    protected ComponentDef getComponentDef(LaContainer container, Object key) {
        synchronized (this) { // to avoid too-many registration of async hot-deploy (basically job)
            return doGetComponentDef(container, key);
        }
    }

    protected ComponentDef doGetComponentDef(LaContainer container, Object key) {
        ComponentDef cd = super.getComponentDef(container, key);
        if (cd != null) {
            return cd;
        }
        if (container != container.getRoot()) {
            return null;
        }
        cd = getComponentDefFromCache(key);
        if (cd != null) {
            return cd;
        }
        if (key instanceof Class<?>) {
            cd = createComponentDef((Class<?>) key);
        } else if (key instanceof String) {
            cd = createComponentDef((String) key);
            if (cd != null && !key.equals(cd.getComponentName())) {
                logger.log("WSSR0011", new Object[] { key, cd.getComponentClass().getName(), cd.getComponentName() });
                cd = null;
            }
        } else {
            throw new IllegalArgumentException("Illegal component key: " + key);
        }
        if (cd != null) {
            register(cd);
            ComponentUtil.putRegisterLog(cd);
            cd.init();
        }
        return cd;
    }

    protected ComponentDef getComponentDefFromCache(Object key) {
        return (ComponentDef) componentDefCache.get(key);
    }

    protected ComponentDef createComponentDef(Class<?> componentClass) {
        for (int i = 0; i < creators.length; ++i) {
            ComponentCreator creator = creators[i];
            ComponentDef cd = creator.createComponentDef(componentClass);
            if (cd != null) {
                return cd;
            }
        }
        return null;
    }

    protected ComponentDef createComponentDef(String componentName) {
        for (int i = 0; i < creators.length; ++i) {
            ComponentCreator creator = creators[i];
            ComponentDef cd = creator.createComponentDef(componentName);
            if (cd != null) {
                return cd;
            }
        }
        return null;
    }

    protected void register(ComponentDef componentDef) {
        componentDef.setContainer(SingletonLaContainerFactory.getContainer());
        registerByClass(componentDef);
        registerByName(componentDef);
    }

    protected void registerByClass(ComponentDef componentDef) {
        Class<?>[] classes = ComponentUtil.getAssignableClasses(componentDef.getComponentClass());
        for (int i = 0; i < classes.length; ++i) {
            registerMap(classes[i], componentDef);
        }
    }

    protected void registerByName(ComponentDef componentDef) {
        String componentName = componentDef.getComponentName();
        if (componentName != null) {
            registerMap(componentName, componentDef);
        }
    }

    protected void registerMap(Object key, ComponentDef componentDef) {
        ComponentDef previousCd = (ComponentDef) componentDefCache.get(key);
        if (previousCd == null) {
            componentDefCache.put(key, componentDef);
        } else {
            ComponentDef tmrcd = LaContainerImpl.createTooManyRegistration(key, previousCd, componentDef);
            componentDefCache.put(key, tmrcd);
        }
    }

    // ===================================================================================
    //                                                                            Accessor
    //                                                                            ========
    public NamingConvention getNamingConvention() {
        return namingConvention;
    }

    public void setNamingConvention(NamingConvention namingConvention) {
        this.namingConvention = namingConvention;
    }

    public ComponentCreator[] getCreators() {
        return creators;
    }

    public void setCreators(ComponentCreator[] creators) {
        this.creators = creators;
    }
}


text:
<?php
namespace User\Form\Validator;

use Zend\Validator\Exception;
use Zend\Stdlib\ArrayUtils;
use Doctrine\ORM\EntityManager;
use Zend\Validator\AbstractValidator;
use Zend\Validator\Exception\InvalidArgumentException;

/**
 * Class CouponCode
 *
 * @package User\Form\Validator
 */
class CouponCode extends AbstractValidator
{
    const ERROR_NO_RECORD_FOUND = 'noRecordFound';
    const ERROR_USED  = 'used';
    const ERROR_EXPIRED  = 'expired';

    private $entity;
    private $entityManager;

    /**
     * @var array Message templates
     */
    protected $messageTemplates = array(
        self::ERROR_NO_RECORD_FOUND => "Coupon code invalid.",
        self::ERROR_USED    => "Coupon code already used.",
        self::ERROR_EXPIRED    => "Coupon code is expired.",
    );

    /**
     * @param null $options
     *
     * @throws InvalidArgumentException
     */
    public function __construct($options = null)
    {
        //@todo: translate messages
        parent::__construct($options);

        if (!array_key_exists('adapter', $options)) {
            throw new InvalidArgumentException('No entity manager provided');
        }
        $this->entityManager = $options['adapter'];
    }

    /**
     * @param mixed $value
     *
     * @return bool
     */
    public function isValid($value)
    {
        $this->setValue($value);

        if ($this->isNotInDB()) {
            $this->error(self::ERROR_NO_RECORD_FOUND);
            return false;
        }
        if ($this->getEntity()->isUsed()) {
            $this->error(self::ERROR_USED);
            return false;
        }
        if ($this->getEntity()->isExpired()) {
            $this->error(self::ERROR_EXPIRED);
            return false;
        }

        return true;
    }

    /**
     * @return bool
     */
    private function isNotInDB()
    {
        return is_null($this->getEntity());
    }

    /**
     * @return EntityManager
     */
    public function getEntityManager()
    {
        return $this->entityManager;
    }

    /**
     * @return \User\Entity\Coupon
     */
    private function getEntity()
    {
        if (is_null($this->entity)) {

            $em = $this->getEntityManager();
            $qb = $em->createQueryBuilder('Coupon')
                ->select('c')
                ->from('User\Entity\Coupon', 'c')
                ->where('c.code = :code')
                ->setParameter('code', $this->getValue());

            $this->entity = $qb->getQuery()->getOneOrNullResult();
        }

        return $this->entity;
    }

}


text:
package org.apache.rave.portal.service;

import org.apache.rave.model.Widget;

public interface WidgetMetadataResolver {
    String getSupportedContext();
    Widget getMetadata(String url);
    Widget[] getMetadataGroup(String url);
    Widget publishRemote(String url);
}


text:
/*-------------------------------------------------------------------------
  Copyright 2008 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/
// .NAME vtkGeoTerrain2D - A 2D terrain model for the globe.
//
// .SECTION Description
// vtkGeoTerrain2D contains a multi-resolution tree of geometry representing
// the globe. It uses a vtkGeoSource subclass to generate the terrain, such
// as vtkGeoProjectionSource. This source must be set before using the
// terrain in a vtkGeoView2D. The terrain also contains an AddActors()
// method which updates the set of actors representing the globe given the
// current camera position.

#ifndef vtkGeoTerrain2D_h
#define vtkGeoTerrain2D_h

#include "vtkGeovisCoreModule.h" // For export macro
#include "vtkGeoTerrain.h"

class vtkAbstractTransform;
class vtkAssembly;
class vtkCollection;
class vtkGeoImageRepresentation;
class vtkGeoSource;
class vtkGeoTerrainNode;
class vtkRenderer;

class VTKGEOVISCORE_EXPORT vtkGeoTerrain2D : public vtkGeoTerrain
{
public:
  static vtkGeoTerrain2D *New();
  vtkTypeMacro(vtkGeoTerrain2D,vtkGeoTerrain);
  virtual void PrintSelf(ostream& os, vtkIndent indent);

  // Description:
  // The maximum size of a single texel in pixels.
  // Images will be refined if a texel becomes larger than the tolerance.
  vtkSetMacro(TextureTolerance, double);
  vtkGetMacro(TextureTolerance, double);

  // Description:
  // The maximum allowed deviation of geometry in pixels.
  // Geometry will be refined if the deviation is larger than the tolerance.
  vtkSetMacro(LocationTolerance, double);
  vtkGetMacro(LocationTolerance, double);

  // Description:
  // Return the projection transformation used by this 2D terrain.
  virtual vtkAbstractTransform* GetTransform();

protected:
  vtkGeoTerrain2D();
  ~vtkGeoTerrain2D();

  double LocationTolerance;
  double TextureTolerance;

  // Description:
  // AddActors() calls this to setup parameters for evaluating nodes.
  virtual void InitializeNodeAnalysis(vtkRenderer* ren);

  // Description:
  // AddActors() calls this to determine if a node is in the current
  // viewport.
  virtual bool NodeInViewport(vtkGeoTerrainNode* node);

  // Description:
  // AddActors() calls to to evaluate whether a node should be
  // refined (1), coarsened (-1), or remain at the same level (0).
  virtual int EvaluateNode(vtkGeoTerrainNode* node);

  double CameraBounds[4];
  double PixelSize;

private:
  vtkGeoTerrain2D(const vtkGeoTerrain2D&); // Not implemented
  void operator=(const vtkGeoTerrain2D&); // Not implemented
};

#endif


text:
RuleManager :: RuleManager()
{
	rules = NULL;
}

RuleManager :: ~RuleManager()
{
	rules->clear();
}

RuleManager :: RuleManager(const char *txt)
{
	if(!InitializeWithTXTFile(txt))
		rules = NULL;
}

bool RuleManager::InitializeWithTXTFile(const char *txt)
{
	std::string msg;
	std::ifstream txtIn(txt, std::ios::in);
	if(!txtIn.good())
	{
		LogManager::Alert(fromptf("The Indicated TXT File \"%s\" does not exist! Initialization of Rule Manager Aborted! ", txt));
		return false;
	}
	rules = new std::vector<Rule *>();
	LogManager::Alert(fromptf("TXT File \"%s\" is now being analyzed. Please standby ... ", txt));
	std::string i, s, a, r, c, e;
	while(txtIn >> i >> s >> a >> r >> c >> e)
	{
		rules->push_back(new Rule(i, s, a, r, c, e));
	}
	LogManager::Alert(fromptf("File Analysis is successful! %d entries have been read into the rules! ", rules->size()));
	return true;
}


text:
ACCEPTED

#### According to
International Plant Names Index

#### Published in
null

#### Original name
Solanum shanesii F.Muell.

### Remarks
null


text:
package com.wei.you.zhihu.spider.config;

import javax.servlet.annotation.WebFilter;

import org.springframework.web.filter.ShallowEtagHeaderFilter;

/**
 *
 */
@WebFilter(filterName = "etagFilter", urlPatterns = { "/**/favicon.ico", "/statics/*" })
public class EtagFilter extends ShallowEtagHeaderFilter {

}


text:
import * as React from 'react'

let Octicon = React.createClass({
	render() {
		return React.createElement('span', {className: 'octicon octicon-' + this.props.icon})
	}
})

export default Octicon
export {Octicon}


text:
package channeldb

import (
	"bytes"
	"crypto/rand"
	"crypto/sha256"
	"fmt"
	"io"
	"reflect"
	"testing"
	"time"

	"github.com/btcsuite/btcwallet/walletdb"
	"github.com/davecgh/go-spew/spew"
	"github.com/lightningnetwork/lnd/kvdb"
	"github.com/lightningnetwork/lnd/lntypes"
	"github.com/lightningnetwork/lnd/record"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func genPreimage() ([32]byte, error) {
	var preimage [32]byte
	if _, err := io.ReadFull(rand.Reader, preimage[:]); err != nil {
		return preimage, err
	}
	return preimage, nil
}

func genInfo() (*PaymentCreationInfo, *HTLCAttemptInfo,
	lntypes.Preimage, error) {

	preimage, err := genPreimage()
	if err != nil {
		return nil, nil, preimage, fmt.Errorf("unable to "+
			"generate preimage: %v", err)
	}

	rhash := sha256.Sum256(preimage[:])
	attempt := NewHtlcAttemptInfo(
		0, priv, *testRoute.Copy(), time.Time{}, nil,
	)
	return &PaymentCreationInfo{
		PaymentIdentifier: rhash,
		Value:             testRoute.ReceiverAmt(),
		CreationTime:      time.Unix(time.Now().Unix(), 0),
		PaymentRequest:    []byte("hola"),
	}, attempt, preimage, nil
}

// TestPaymentControlSwitchFail checks that payment status returns to Failed
// status after failing, and that InitPayment allows another HTLC for the
// same payment hash.
func TestPaymentControlSwitchFail(t *testing.T) {
	t.Parallel()

	db, cleanup, err := MakeTestDB()
	defer cleanup()
	require.NoError(t, err, "unable to init db")

	pControl := NewPaymentControl(db)

	info, attempt, preimg, err := genInfo()
	require.NoError(t, err, "unable to generate htlc message")

	// Sends base htlc message which initiate StatusInFlight.
	err = pControl.InitPayment(info.PaymentIdentifier, info)
	require.NoError(t, err, "unable to send htlc message")

	assertPaymentIndex(t, pControl, info.PaymentIdentifier)
	assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusInFlight)
	assertPaymentInfo(
		t, pControl, info.PaymentIdentifier, info, nil, nil,
	)

	// Fail the payment, which should moved it to Failed.
	failReason := FailureReasonNoRoute
	_, err = pControl.Fail(info.PaymentIdentifier, failReason)
	require.NoError(t, err, "unable to fail payment hash")

	// Verify the status is indeed Failed.
	assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusFailed)
	assertPaymentInfo(
		t, pControl, info.PaymentIdentifier, info, &failReason, nil,
	)

	// Lookup the payment so we can get its old sequence number before it is
	// overwritten.
	payment, err := pControl.FetchPayment(info.PaymentIdentifier)
	require.NoError(t, err)

	// Sends the htlc again, which should succeed since the prior payment
	// failed.
	err = pControl.InitPayment(info.PaymentIdentifier, info)
	require.NoError(t, err, "unable to send htlc message")

	// Check that our index has been updated, and the old index has been
	// removed.
	assertPaymentIndex(t, pControl, info.PaymentIdentifier)
	assertNoIndex(t, pControl, payment.SequenceNum)

	assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusInFlight)
	assertPaymentInfo(
		t, pControl, info.PaymentIdentifier, info, nil, nil,
	)

	// Record a new attempt. In this test scenario, the attempt fails.
	// However, this is not communicated to control tower in the current
	// implementation. It only registers the initiation of the attempt.
	_, err = pControl.RegisterAttempt(info.PaymentIdentifier, attempt)
	require.NoError(t, err, "unable to register attempt")

	htlcReason := HTLCFailUnreadable
	_, err = pControl.FailAttempt(
		info.PaymentIdentifier, attempt.AttemptID,
		&HTLCFailInfo{
			Reason: htlcReason,
		},
	)
	if err != nil {
		t.Fatal(err)
	}
	assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusInFlight)

	htlc := &htlcStatus{
		HTLCAttemptInfo: attempt,
		failure:         &htlcReason,
	}

	assertPaymentInfo(t, pControl, info.PaymentIdentifier, info, nil, htlc)

	// Record another attempt.
	attempt.AttemptID = 1
	_, err = pControl.RegisterAttempt(info.PaymentIdentifier, attempt)
	require.NoError(t, err, "unable to send htlc message")
	assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusInFlight)

	htlc = &htlcStatus{
		HTLCAttemptInfo: attempt,
	}

	assertPaymentInfo(
		t, pControl, info.PaymentIdentifier, info, nil, htlc,
	)

	// Settle the attempt and verify that status was changed to
	// StatusSucceeded.
	payment, err = pControl.SettleAttempt(
		info.PaymentIdentifier, attempt.AttemptID,
		&HTLCSettleInfo{
			Preimage: preimg,
		},
	)
	require.NoError(t, err, "error shouldn't have been received, got")

	if len(payment.HTLCs) != 2 {
		t.Fatalf("payment should have two htlcs, got: %d",
			len(payment.HTLCs))
	}

	err = assertRouteEqual(&payment.HTLCs[0].Route, &attempt.Route)
	if err != nil {
		t.Fatalf("unexpected route returned: %v vs %v: %v",
			spew.Sdump(attempt.Route),
			spew.Sdump(payment.HTLCs[0].Route), err)
	}

	assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusSucceeded)

	htlc.settle = &preimg
	assertPaymentInfo(
		t, pControl, info.PaymentIdentifier, info, nil, htlc,
	)

	// Attempt a final payment, which should now fail since the prior
	// payment succeed.
	err = pControl.InitPayment(info.PaymentIdentifier, info)
	if err != ErrAlreadyPaid {
		t.Fatalf("unable to send htlc message: %v", err)
	}
}

// TestPaymentControlSwitchDoubleSend checks the ability of payment control to
// prevent double sending of htlc message, when message is in StatusInFlight.
func TestPaymentControlSwitchDoubleSend(t *testing.T) {
	t.Parallel()

	db, cleanup, err := MakeTestDB()
	defer cleanup()

	require.NoError(t, err, "unable to init db")

	pControl := NewPaymentControl(db)

	info, attempt, preimg, err := genInfo()
	require.NoError(t, err, "unable to generate htlc message")

	// Sends base htlc message which initiate base status and move it to
	// StatusInFlight and verifies that it was changed.
	err = pControl.InitPayment(info.PaymentIdentifier, info)
	require.NoError(t, err, "unable to send htlc message")

	assertPaymentIndex(t, pControl, info.PaymentIdentifier)
	assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusInFlight)
	assertPaymentInfo(
		t, pControl, info.PaymentIdentifier, info, nil, nil,
	)

	// Try to initiate double sending of htlc message with the same
	// payment hash, should result in error indicating that payment has
	// already been sent.
	err = pControl.InitPayment(info.PaymentIdentifier, info)
	if err != ErrPaymentInFlight {
		t.Fatalf("payment control wrong behaviour: " +
			"double sending must trigger ErrPaymentInFlight error")
	}

	// Record an attempt.
	_, err = pControl.RegisterAttempt(info.PaymentIdentifier, attempt)
	require.NoError(t, err, "unable to send htlc message")
	assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusInFlight)

	htlc := &htlcStatus{
		HTLCAttemptInfo: attempt,
	}
	assertPaymentInfo(
		t, pControl, info.PaymentIdentifier, info, nil, htlc,
	)

	// Sends base htlc message which initiate StatusInFlight.
	err = pControl.InitPayment(info.PaymentIdentifier, info)
	if err != ErrPaymentInFlight {
		t.Fatalf("payment control wrong behaviour: " +
			"double sending must trigger ErrPaymentInFlight error")
	}

	// After settling, the error should be ErrAlreadyPaid.
	_, err = pControl.SettleAttempt(
		info.PaymentIdentifier, attempt.AttemptID,
		&HTLCSettleInfo{
			Preimage: preimg,
		},
	)
	require.NoError(t, err, "error shouldn't have been received, got")
	assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusSucceeded)

	htlc.settle = &preimg
	assertPaymentInfo(t, pControl, info.PaymentIdentifier, info, nil, htlc)

	err = pControl.InitPayment(info.PaymentIdentifier, info)
	if err != ErrAlreadyPaid {
		t.Fatalf("unable to send htlc message: %v", err)
	}
}

// TestPaymentControlSuccessesWithoutInFlight checks that the payment
// control will disallow calls to Success when no payment is in flight.
func TestPaymentControlSuccessesWithoutInFlight(t *testing.T) {
	t.Parallel()

	db, cleanup, err := MakeTestDB()
	defer cleanup()

	require.NoError(t, err, "unable to init db")

	pControl := NewPaymentControl(db)

	info, _, preimg, err := genInfo()
	require.NoError(t, err, "unable to generate htlc message")

	// Attempt to complete the payment should fail.
	_, err = pControl.SettleAttempt(
		info.PaymentIdentifier, 0,
		&HTLCSettleInfo{
			Preimage: preimg,
		},
	)
	if err != ErrPaymentNotInitiated {
		t.Fatalf("expected ErrPaymentNotInitiated, got %v", err)
	}

	assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusUnknown)
}

// TestPaymentControlFailsWithoutInFlight checks that a strict payment
// control will disallow calls to Fail when no payment is in flight.
func TestPaymentControlFailsWithoutInFlight(t *testing.T) {
	t.Parallel()

	db, cleanup, err := MakeTestDB()
	defer cleanup()

	require.NoError(t, err, "unable to init db")

	pControl := NewPaymentControl(db)

	info, _, _, err := genInfo()
	require.NoError(t, err, "unable to generate htlc message")

	// Calling Fail should return an error.
	_, err = pControl.Fail(info.PaymentIdentifier, FailureReasonNoRoute)
	if err != ErrPaymentNotInitiated {
		t.Fatalf("expected ErrPaymentNotInitiated, got %v", err)
	}

	assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusUnknown)
}

// TestPaymentControlDeleteNonInFlight checks that calling DeletePayments only
// deletes payments from the database that are not in-flight.
func TestPaymentControlDeleteNonInFlight(t *testing.T) {
	t.Parallel()

	db, cleanup, err := MakeTestDB()
	defer cleanup()

	require.NoError(t, err, "unable to init db")

	// Create a sequence number for duplicate payments that will not collide
	// with the sequence numbers for the payments we create. These values
	// start at 1, so 9999 is a safe bet for this test.
	var duplicateSeqNr = 9999

	pControl := NewPaymentControl(db)

	payments := []struct {
		failed       bool
		success      bool
		hasDuplicate bool
	}{
		{
			failed:       true,
			success:      false,
			hasDuplicate: false,
		},
		{
			failed:       false,
			success:      true,
			hasDuplicate: false,
		},
		{
			failed:       false,
			success:      false,
			hasDuplicate: false,
		},
		{
			failed:       false,
			success:      true,
			hasDuplicate: true,
		},
	}

	var numSuccess, numInflight int

	for _, p := range payments {
		info, attempt, preimg, err := genInfo()
		if err != nil {
			t.Fatalf("unable to generate htlc message: %v", err)
		}

		// Sends base htlc message which initiate StatusInFlight.
		err = pControl.InitPayment(info.PaymentIdentifier, info)
		if err != nil {
			t.Fatalf("unable to send htlc message: %v", err)
		}
		_, err = pControl.RegisterAttempt(info.PaymentIdentifier, attempt)
		if err != nil {
			t.Fatalf("unable to send htlc message: %v", err)
		}

		htlc := &htlcStatus{
			HTLCAttemptInfo: attempt,
		}

		if p.failed {
			// Fail the payment attempt.
			htlcFailure := HTLCFailUnreadable
			_, err := pControl.FailAttempt(
				info.PaymentIdentifier, attempt.AttemptID,
				&HTLCFailInfo{
					Reason: htlcFailure,
				},
			)
			if err != nil {
				t.Fatalf("unable to fail htlc: %v", err)
			}

			// Fail the payment, which should moved it to Failed.
			failReason := FailureReasonNoRoute
			_, err = pControl.Fail(info.PaymentIdentifier, failReason)
			if err != nil {
				t.Fatalf("unable to fail payment hash: %v", err)
			}

			// Verify the status is indeed Failed.
			assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusFailed)

			htlc.failure = &htlcFailure
			assertPaymentInfo(
				t, pControl, info.PaymentIdentifier, info,
				&failReason, htlc,
			)
		} else if p.success {
			// Verifies that status was changed to StatusSucceeded.
			_, err := pControl.SettleAttempt(
				info.PaymentIdentifier, attempt.AttemptID,
				&HTLCSettleInfo{
					Preimage: preimg,
				},
			)
			if err != nil {
				t.Fatalf("error shouldn't have been received, got: %v", err)
			}

			assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusSucceeded)

			htlc.settle = &preimg
			assertPaymentInfo(
				t, pControl, info.PaymentIdentifier, info, nil, htlc,
			)

			numSuccess++
		} else {
			assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusInFlight)
			assertPaymentInfo(
				t, pControl, info.PaymentIdentifier, info, nil, htlc,
			)

			numInflight++
		}

		// If the payment is intended to have a duplicate payment, we
		// add one.
		if p.hasDuplicate {
			appendDuplicatePayment(
				t, pControl.db, info.PaymentIdentifier,
				uint64(duplicateSeqNr), preimg,
			)
			duplicateSeqNr++
			numSuccess++
		}
	}

	// Delete all failed payments.
	if err := db.DeletePayments(true, false); err != nil {
		t.Fatal(err)
	}

	// This should leave the succeeded and in-flight payments.
	dbPayments, err := db.FetchPayments()
	if err != nil {
		t.Fatal(err)
	}

	if len(dbPayments) != numSuccess+numInflight {
		t.Fatalf("expected %d payments, got %d",
			numSuccess+numInflight, len(dbPayments))
	}

	var s, i int
	for _, p := range dbPayments {
		t.Log("fetch payment has status", p.Status)
		switch p.Status {
		case StatusSucceeded:
			s++
		case StatusInFlight:
			i++
		}
	}

	if s != numSuccess {
		t.Fatalf("expected %d succeeded payments , got %d",
			numSuccess, s)
	}
	if i != numInflight {
		t.Fatalf("expected %d in-flight payments, got %d",
			numInflight, i)
	}

	// Now delete all payments except in-flight.
	if err := db.DeletePayments(false, false); err != nil {
		t.Fatal(err)
	}

	// This should leave the in-flight payment.
	dbPayments, err = db.FetchPayments()
	if err != nil {
		t.Fatal(err)
	}

	if len(dbPayments) != numInflight {
		t.Fatalf("expected %d payments, got %d", numInflight,
			len(dbPayments))
	}

	for _, p := range dbPayments {
		if p.Status != StatusInFlight {
			t.Fatalf("expected in-fligth status, got %v", p.Status)
		}
	}

	// Finally, check that we only have a single index left in the payment
	// index bucket.
	var indexCount int
	err = kvdb.View(db, func(tx walletdb.ReadTx) error {
		index := tx.ReadBucket(paymentsIndexBucket)

		return index.ForEach(func(k, v []byte) error {
			indexCount++
			return nil
		})
	}, func() { indexCount = 0 })
	require.NoError(t, err)

	require.Equal(t, 1, indexCount)
}

// TestPaymentControlDeletePayments tests that DeletePayments correctly deletes
// information about completed payments from the database.
func TestPaymentControlDeletePayments(t *testing.T) {
	t.Parallel()

	db, cleanup, err := MakeTestDB()
	defer cleanup()
	require.NoError(t, err, "unable to init db")

	pControl := NewPaymentControl(db)

	// Register three payments:
	// 1. A payment with two failed attempts.
	// 2. A payment with one failed and one settled attempt.
	// 3. A payment with one failed and one in-flight attempt.
	payments := []*payment{
		{status: StatusFailed},
		{status: StatusSucceeded},
		{status: StatusInFlight},
	}

	// Use helper function to register the test payments in the data and
	// populate the data to the payments slice.
	createTestPayments(t, pControl, payments)

	// Check that all payments are there as we added them.
	assertPayments(t, db, payments)

	// Delete HTLC attempts for failed payments only.
	require.NoError(t, db.DeletePayments(true, true))

	// The failed payment is the only altered one.
	payments[0].htlcs = 0
	assertPayments(t, db, payments)

	// Delete failed attempts for all payments.
	require.NoError(t, db.DeletePayments(false, true))

	// The failed attempts should be deleted, except for the in-flight
	// payment, that shouldn't be altered until it has completed.
	payments[1].htlcs = 1
	assertPayments(t, db, payments)

	// Now delete all failed payments.
	require.NoError(t, db.DeletePayments(true, false))

	assertPayments(t, db, payments[1:])

	// Finally delete all completed payments.
	require.NoError(t, db.DeletePayments(false, false))

	assertPayments(t, db, payments[2:])
}

// TestPaymentControlDeleteSinglePayment tests that DeletePayment correctly
// deletes information about a completed payment from the database.
func TestPaymentControlDeleteSinglePayment(t *testing.T) {
	t.Parallel()

	db, cleanup, err := MakeTestDB()
	defer cleanup()
	require.NoError(t, err, "unable to init db")

	pControl := NewPaymentControl(db)

	// Register four payments:
	// All payments will have one failed HTLC attempt and one HTLC attempt
	// according to its final status.
	// 1. A payment with two failed attempts.
	// 2. Another payment with two failed attempts.
	// 3. A payment with one failed and one settled attempt.
	// 4. A payment with one failed and one in-flight attempt.

	// Initiate payments, which is a slice of payment that is used as
	// template to create the corresponding test payments in the database.
	//
	// Note: The payment id and number of htlc attempts of each payment will
	// be added to this slice when creating the payments below.
	// This allows the slice to be used directly for testing purposes.
	payments := []*payment{
		{status: StatusFailed},
		{status: StatusFailed},
		{status: StatusSucceeded},
		{status: StatusInFlight},
	}

	// Use helper function to register the test payments in the data and
	// populate the data to the payments slice.
	createTestPayments(t, pControl, payments)

	// Check that all payments are there as we added them.
	assertPayments(t, db, payments)

	// Delete HTLC attempts for first payment only.
	require.NoError(t, db.DeletePayment(payments[0].id, true))

	// The first payment is the only altered one as its failed HTLC should
	// have been removed but is still present as payment.
	payments[0].htlcs = 0
	assertPayments(t, db, payments)

	// Delete the first payment completely.
	require.NoError(t, db.DeletePayment(payments[0].id, false))

	// The first payment should have been deleted.
	assertPayments(t, db, payments[1:])

	// Now delete the second payment completely.
	require.NoError(t, db.DeletePayment(payments[1].id, false))

	// The Second payment should have been deleted.
	assertPayments(t, db, payments[2:])

	// Delete failed HTLC attempts for the third payment.
	require.NoError(t, db.DeletePayment(payments[2].id, true))

	// Only the successful HTLC attempt should be left for the third payment.
	payments[2].htlcs = 1
	assertPayments(t, db, payments[2:])

	// Now delete the third payment completely.
	require.NoError(t, db.DeletePayment(payments[2].id, false))

	// Only the last payment should be left.
	assertPayments(t, db, payments[3:])

	// Deleting HTLC attempts from InFlight payments should not work and an
	// error returned.
	require.Error(t, db.DeletePayment(payments[3].id, true))

	// The payment is InFlight and therefore should not have been altered.
	assertPayments(t, db, payments[3:])

	// Finally deleting the InFlight payment should also not work and an
	// error returned.
	require.Error(t, db.DeletePayment(payments[3].id, false))

	// The payment is InFlight and therefore should not have been altered.
	assertPayments(t, db, payments[3:])
}

// TestPaymentControlMultiShard checks the ability of payment control to
// have multiple in-flight HTLCs for a single payment.
func TestPaymentControlMultiShard(t *testing.T) {
	t.Parallel()

	// We will register three HTLC attempts, and always fail the second
	// one. We'll generate all combinations of settling/failing the first
	// and third HTLC, and assert that the payment status end up as we
	// expect.
	type testCase struct {
		settleFirst bool
		settleLast  bool
	}

	var tests []testCase
	for _, f := range []bool{true, false} {
		for _, l := range []bool{true, false} {
			tests = append(tests, testCase{f, l})
		}
	}

	runSubTest := func(t *testing.T, test testCase) {
		db, cleanup, err := MakeTestDB()
		defer cleanup()

		if err != nil {
			t.Fatalf("unable to init db: %v", err)
		}

		pControl := NewPaymentControl(db)

		info, attempt, preimg, err := genInfo()
		if err != nil {
			t.Fatalf("unable to generate htlc message: %v", err)
		}

		// Init the payment, moving it to the StatusInFlight state.
		err = pControl.InitPayment(info.PaymentIdentifier, info)
		if err != nil {
			t.Fatalf("unable to send htlc message: %v", err)
		}

		assertPaymentIndex(t, pControl, info.PaymentIdentifier)
		assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusInFlight)
		assertPaymentInfo(
			t, pControl, info.PaymentIdentifier, info, nil, nil,
		)

		// Create three unique attempts we'll use for the test, and
		// register them with the payment control. We set each
		// attempts's value to one third of the payment amount, and
		// populate the MPP options.
		shardAmt := info.Value / 3
		attempt.Route.FinalHop().AmtToForward = shardAmt
		attempt.Route.FinalHop().MPP = record.NewMPP(
			info.Value, [32]byte{1},
		)

		var attempts []*HTLCAttemptInfo
		for i := uint64(0); i < 3; i++ {
			a := *attempt
			a.AttemptID = i
			attempts = append(attempts, &a)

			_, err = pControl.RegisterAttempt(info.PaymentIdentifier, &a)
			if err != nil {
				t.Fatalf("unable to send htlc message: %v", err)
			}
			assertPaymentStatus(
				t, pControl, info.PaymentIdentifier, StatusInFlight,
			)

			htlc := &htlcStatus{
				HTLCAttemptInfo: &a,
			}
			assertPaymentInfo(
				t, pControl, info.PaymentIdentifier, info, nil, htlc,
			)
		}

		// For a fourth attempt, check that attempting to
		// register it will fail since the total sent amount
		// will be too large.
		b := *attempt
		b.AttemptID = 3
		_, err = pControl.RegisterAttempt(info.PaymentIdentifier, &b)
		if err != ErrValueExceedsAmt {
			t.Fatalf("expected ErrValueExceedsAmt, got: %v",
				err)
		}

		// Fail the second attempt.
		a := attempts[1]
		htlcFail := HTLCFailUnreadable
		_, err = pControl.FailAttempt(
			info.PaymentIdentifier, a.AttemptID,
			&HTLCFailInfo{
				Reason: htlcFail,
			},
		)
		if err != nil {
			t.Fatal(err)
		}

		htlc := &htlcStatus{
			HTLCAttemptInfo: a,
			failure:         &htlcFail,
		}
		assertPaymentInfo(
			t, pControl, info.PaymentIdentifier, info, nil, htlc,
		)

		// Payment should still be in-flight.
		assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusInFlight)

		// Depending on the test case, settle or fail the first attempt.
		a = attempts[0]
		htlc = &htlcStatus{
			HTLCAttemptInfo: a,
		}

		var firstFailReason *FailureReason
		if test.settleFirst {
			_, err := pControl.SettleAttempt(
				info.PaymentIdentifier, a.AttemptID,
				&HTLCSettleInfo{
					Preimage: preimg,
				},
			)
			if err != nil {
				t.Fatalf("error shouldn't have been "+
					"received, got: %v", err)
			}

			// Assert that the HTLC has had the preimage recorded.
			htlc.settle = &preimg
			assertPaymentInfo(
				t, pControl, info.PaymentIdentifier, info, nil, htlc,
			)
		} else {
			_, err := pControl.FailAttempt(
				info.PaymentIdentifier, a.AttemptID,
				&HTLCFailInfo{
					Reason: htlcFail,
				},
			)
			if err != nil {
				t.Fatalf("error shouldn't have been "+
					"received, got: %v", err)
			}

			// Assert the failure was recorded.
			htlc.failure = &htlcFail
			assertPaymentInfo(
				t, pControl, info.PaymentIdentifier, info, nil, htlc,
			)

			// We also record a payment level fail, to move it into
			// a terminal state.
			failReason := FailureReasonNoRoute
			_, err = pControl.Fail(info.PaymentIdentifier, failReason)
			if err != nil {
				t.Fatalf("unable to fail payment hash: %v", err)
			}

			// Record the reason we failed the payment, such that
			// we can assert this later in the test.
			firstFailReason = &failReason
		}

		// The payment should still be considered in-flight, since there
		// is still an active HTLC.
		assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusInFlight)

		// Try to register yet another attempt. This should fail now
		// that the payment has reached a terminal condition.
		b = *attempt
		b.AttemptID = 3
		_, err = pControl.RegisterAttempt(info.PaymentIdentifier, &b)
		if err != ErrPaymentTerminal {
			t.Fatalf("expected ErrPaymentTerminal, got: %v", err)
		}

		assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusInFlight)

		// Settle or fail the remaining attempt based on the testcase.
		a = attempts[2]
		htlc = &htlcStatus{
			HTLCAttemptInfo: a,
		}
		if test.settleLast {
			// Settle the last outstanding attempt.
			_, err = pControl.SettleAttempt(
				info.PaymentIdentifier, a.AttemptID,
				&HTLCSettleInfo{
					Preimage: preimg,
				},
			)
			if err != nil {
				t.Fatalf("error shouldn't have been "+
					"received, got: %v", err)
			}

			htlc.settle = &preimg
			assertPaymentInfo(
				t, pControl, info.PaymentIdentifier, info,
				firstFailReason, htlc,
			)
		} else {
			// Fail the attempt.
			_, err := pControl.FailAttempt(
				info.PaymentIdentifier, a.AttemptID,
				&HTLCFailInfo{
					Reason: htlcFail,
				},
			)
			if err != nil {
				t.Fatalf("error shouldn't have been "+
					"received, got: %v", err)
			}

			// Assert the failure was recorded.
			htlc.failure = &htlcFail
			assertPaymentInfo(
				t, pControl, info.PaymentIdentifier, info,
				firstFailReason, htlc,
			)

			// Check that we can override any perevious terminal
			// failure. This is to allow multiple concurrent shard
			// write a terminal failure to the database without
			// syncing.
			failReason := FailureReasonPaymentDetails
			_, err = pControl.Fail(info.PaymentIdentifier, failReason)
			if err != nil {
				t.Fatalf("unable to fail payment hash: %v", err)
			}
		}

		// If any of the two attempts settled, the payment should end
		// up in the Succeeded state. If both failed the payment should
		// also be Failed at this poinnt.
		finalStatus := StatusFailed
		if test.settleFirst || test.settleLast {
			finalStatus = StatusSucceeded
		}

		assertPaymentStatus(t, pControl, info.PaymentIdentifier, finalStatus)

		// Finally assert we cannot register more attempts.
		_, err = pControl.RegisterAttempt(info.PaymentIdentifier, &b)
		require.Equal(t, ErrPaymentTerminal, err)
	}

	for _, test := range tests {
		test := test
		subTest := fmt.Sprintf("first=%v, second=%v",
			test.settleFirst, test.settleLast)

		t.Run(subTest, func(t *testing.T) {
			runSubTest(t, test)
		})
	}
}

func TestPaymentControlMPPRecordValidation(t *testing.T) {
	t.Parallel()

	db, cleanup, err := MakeTestDB()
	defer cleanup()

	require.NoError(t, err, "unable to init db")

	pControl := NewPaymentControl(db)

	info, attempt, _, err := genInfo()
	require.NoError(t, err, "unable to generate htlc message")

	// Init the payment.
	err = pControl.InitPayment(info.PaymentIdentifier, info)
	require.NoError(t, err, "unable to send htlc message")

	// Create three unique attempts we'll use for the test, and
	// register them with the payment control. We set each
	// attempts's value to one third of the payment amount, and
	// populate the MPP options.
	shardAmt := info.Value / 3
	attempt.Route.FinalHop().AmtToForward = shardAmt
	attempt.Route.FinalHop().MPP = record.NewMPP(
		info.Value, [32]byte{1},
	)

	_, err = pControl.RegisterAttempt(info.PaymentIdentifier, attempt)
	require.NoError(t, err, "unable to send htlc message")

	// Now try to register a non-MPP attempt, which should fail.
	b := *attempt
	b.AttemptID = 1
	b.Route.FinalHop().MPP = nil
	_, err = pControl.RegisterAttempt(info.PaymentIdentifier, &b)
	if err != ErrMPPayment {
		t.Fatalf("expected ErrMPPayment, got: %v", err)
	}

	// Try to register attempt one with a different payment address.
	b.Route.FinalHop().MPP = record.NewMPP(
		info.Value, [32]byte{2},
	)
	_, err = pControl.RegisterAttempt(info.PaymentIdentifier, &b)
	if err != ErrMPPPaymentAddrMismatch {
		t.Fatalf("expected ErrMPPPaymentAddrMismatch, got: %v", err)
	}

	// Try registering one with a different total amount.
	b.Route.FinalHop().MPP = record.NewMPP(
		info.Value/2, [32]byte{1},
	)
	_, err = pControl.RegisterAttempt(info.PaymentIdentifier, &b)
	if err != ErrMPPTotalAmountMismatch {
		t.Fatalf("expected ErrMPPTotalAmountMismatch, got: %v", err)
	}

	// Create and init a new payment. This time we'll check that we cannot
	// register an MPP attempt if we already registered a non-MPP one.
	info, attempt, _, err = genInfo()
	require.NoError(t, err, "unable to generate htlc message")

	err = pControl.InitPayment(info.PaymentIdentifier, info)
	require.NoError(t, err, "unable to send htlc message")

	attempt.Route.FinalHop().MPP = nil
	_, err = pControl.RegisterAttempt(info.PaymentIdentifier, attempt)
	require.NoError(t, err, "unable to send htlc message")

	// Attempt to register an MPP attempt, which should fail.
	b = *attempt
	b.AttemptID = 1
	b.Route.FinalHop().MPP = record.NewMPP(
		info.Value, [32]byte{1},
	)

	_, err = pControl.RegisterAttempt(info.PaymentIdentifier, &b)
	if err != ErrNonMPPayment {
		t.Fatalf("expected ErrNonMPPayment, got: %v", err)
	}
}

// TestDeleteFailedAttempts checks that DeleteFailedAttempts properly removes
// failed HTLCs from finished payments.
func TestDeleteFailedAttempts(t *testing.T) {
	t.Parallel()

	t.Run("keep failed payment attempts", func(t *testing.T) {
		testDeleteFailedAttempts(t, true)
	})
	t.Run("remove failed payment attempts", func(t *testing.T) {
		testDeleteFailedAttempts(t, false)
	})
}

func testDeleteFailedAttempts(t *testing.T, keepFailedPaymentAttempts bool) {
	db, cleanup, err := MakeTestDB()
	defer cleanup()

	require.NoError(t, err, "unable to init db")
	db.keepFailedPaymentAttempts = keepFailedPaymentAttempts

	pControl := NewPaymentControl(db)

	// Register three payments:
	// All payments will have one failed HTLC attempt and one HTLC attempt
	// according to its final status.
	// 1. A payment with two failed attempts.
	// 2. A payment with one failed and one in-flight attempt.
	// 3. A payment with one failed and one settled attempt.

	// Initiate payments, which is a slice of payment that is used as
	// template to create the corresponding test payments in the database.
	//
	// Note: The payment id and number of htlc attempts of each payment will
	// be added to this slice when creating the payments below.
	// This allows the slice to be used directly for testing purposes.
	payments := []*payment{
		{status: StatusFailed},
		{status: StatusInFlight},
		{status: StatusSucceeded},
	}

	// Use helper function to register the test payments in the data and
	// populate the data to the payments slice.
	createTestPayments(t, pControl, payments)

	// Check that all payments are there as we added them.
	assertPayments(t, db, payments)

	// Calling DeleteFailedAttempts on a failed payment should delete all
	// HTLCs.
	require.NoError(t, pControl.DeleteFailedAttempts(payments[0].id))

	// Expect all HTLCs to be deleted if the config is set to delete them.
	if !keepFailedPaymentAttempts {
		payments[0].htlcs = 0
	}
	assertPayments(t, db, payments)

	// Calling DeleteFailedAttempts on an in-flight payment should return
	// an error.
	if keepFailedPaymentAttempts {
		require.NoError(t, pControl.DeleteFailedAttempts(payments[1].id))
	} else {
		require.Error(t, pControl.DeleteFailedAttempts(payments[1].id))
	}

	// Since DeleteFailedAttempts returned an error, we should expect the
	// payment to be unchanged.
	assertPayments(t, db, payments)

	// Cleaning up a successful payment should remove failed htlcs.
	require.NoError(t, pControl.DeleteFailedAttempts(payments[2].id))
	// Expect all HTLCs except for the settled one to be deleted if the
	// config is set to delete them.
	if !keepFailedPaymentAttempts {
		payments[2].htlcs = 1
	}
	assertPayments(t, db, payments)

	if keepFailedPaymentAttempts {
		// DeleteFailedAttempts is ignored, even for non-existent
		// payments, if the control tower is configured to keep failed
		// HTLCs.
		require.NoError(t, pControl.DeleteFailedAttempts(lntypes.ZeroHash))
	} else {
		// Attempting to cleanup a non-existent payment returns an error.
		require.Error(t, pControl.DeleteFailedAttempts(lntypes.ZeroHash))
	}
}

// assertPaymentStatus retrieves the status of the payment referred to by hash
// and compares it with the expected state.
func assertPaymentStatus(t *testing.T, p *PaymentControl,
	hash lntypes.Hash, expStatus PaymentStatus) {

	t.Helper()

	payment, err := p.FetchPayment(hash)
	if expStatus == StatusUnknown && err == ErrPaymentNotInitiated {
		return
	}
	if err != nil {
		t.Fatal(err)
	}

	if payment.Status != expStatus {
		t.Fatalf("payment status mismatch: expected %v, got %v",
			expStatus, payment.Status)
	}
}

type htlcStatus struct {
	*HTLCAttemptInfo
	settle  *lntypes.Preimage
	failure *HTLCFailReason
}

// assertPaymentInfo retrieves the payment referred to by hash and verifies the
// expected values.
func assertPaymentInfo(t *testing.T, p *PaymentControl, hash lntypes.Hash,
	c *PaymentCreationInfo, f *FailureReason, a *htlcStatus) {

	t.Helper()

	payment, err := p.FetchPayment(hash)
	if err != nil {
		t.Fatal(err)
	}

	if !reflect.DeepEqual(payment.Info, c) {
		t.Fatalf("PaymentCreationInfos don't match: %v vs %v",
			spew.Sdump(payment.Info), spew.Sdump(c))
	}

	if f != nil {
		if *payment.FailureReason != *f {
			t.Fatal("unexpected failure reason")
		}
	} else {
		if payment.FailureReason != nil {
			t.Fatal("unexpected failure reason")
		}
	}

	if a == nil {
		if len(payment.HTLCs) > 0 {
			t.Fatal("expected no htlcs")
		}
		return
	}

	htlc := payment.HTLCs[a.AttemptID]
	if err := assertRouteEqual(&htlc.Route, &a.Route); err != nil {
		t.Fatal("routes do not match")
	}

	if htlc.AttemptID != a.AttemptID {
		t.Fatalf("unnexpected attempt ID %v, expected %v",
			htlc.AttemptID, a.AttemptID)
	}

	if a.failure != nil {
		if htlc.Failure == nil {
			t.Fatalf("expected HTLC to be failed")
		}

		if htlc.Failure.Reason != *a.failure {
			t.Fatalf("expected HTLC failure %v, had %v",
				*a.failure, htlc.Failure.Reason)
		}
	} else if htlc.Failure != nil {
		t.Fatalf("expected no HTLC failure")
	}

	if a.settle != nil {
		if htlc.Settle.Preimage != *a.settle {
			t.Fatalf("Preimages don't match: %x vs %x",
				htlc.Settle.Preimage, a.settle)
		}
	} else if htlc.Settle != nil {
		t.Fatal("expected no settle info")
	}
}

// fetchPaymentIndexEntry gets the payment hash for the sequence number provided
// from our payment indexes bucket.
func fetchPaymentIndexEntry(_ *testing.T, p *PaymentControl,
	sequenceNumber uint64) (*lntypes.Hash, error) {

	var hash lntypes.Hash

	if err := kvdb.View(p.db, func(tx walletdb.ReadTx) error {
		indexBucket := tx.ReadBucket(paymentsIndexBucket)
		key := make([]byte, 8)
		byteOrder.PutUint64(key, sequenceNumber)

		indexValue := indexBucket.Get(key)
		if indexValue == nil {
			return errNoSequenceNrIndex
		}

		r := bytes.NewReader(indexValue)

		var err error
		hash, err = deserializePaymentIndex(r)
		return err
	}, func() {
		hash = lntypes.Hash{}
	}); err != nil {
		return nil, err
	}

	return &hash, nil
}

// assertPaymentIndex looks up the index for a payment in the db and checks
// that its payment hash matches the expected hash passed in.
func assertPaymentIndex(t *testing.T, p *PaymentControl,
	expectedHash lntypes.Hash) {

	// Lookup the payment so that we have its sequence number and check
	// that is has correctly been indexed in the payment indexes bucket.
	pmt, err := p.FetchPayment(expectedHash)
	require.NoError(t, err)

	hash, err := fetchPaymentIndexEntry(t, p, pmt.SequenceNum)
	require.NoError(t, err)
	assert.Equal(t, expectedHash, *hash)
}

// assertNoIndex checks that an index for the sequence number provided does not
// exist.
func assertNoIndex(t *testing.T, p *PaymentControl, seqNr uint64) {
	_, err := fetchPaymentIndexEntry(t, p, seqNr)
	require.Equal(t, errNoSequenceNrIndex, err)
}

// payment is a helper structure that holds basic information on a test payment,
// such as the payment id, the status and the total number of HTLCs attempted.
type payment struct {
	id     lntypes.Hash
	status PaymentStatus
	htlcs  int
}

// createTestPayments registers payments depending on the provided statuses in
// the payments slice. Each payment will receive one failed HTLC and another
// HTLC depending on the final status of the payment provided.
func createTestPayments(t *testing.T, p *PaymentControl, payments []*payment) {
	attemptID := uint64(0)

	for i := 0; i < len(payments); i++ {
		info, attempt, preimg, err := genInfo()
		require.NoError(t, err, "unable to generate htlc message")

		// Set the payment id accordingly in the payments slice.
		payments[i].id = info.PaymentIdentifier

		attempt.AttemptID = attemptID
		attemptID++

		// Init the payment.
		err = p.InitPayment(info.PaymentIdentifier, info)
		require.NoError(t, err, "unable to send htlc message")

		// Register and fail the first attempt for all payments.
		_, err = p.RegisterAttempt(info.PaymentIdentifier, attempt)
		require.NoError(t, err, "unable to send htlc message")

		htlcFailure := HTLCFailUnreadable
		_, err = p.FailAttempt(
			info.PaymentIdentifier, attempt.AttemptID,
			&HTLCFailInfo{
				Reason: htlcFailure,
			},
		)
		require.NoError(t, err, "unable to fail htlc")

		// Increase the HTLC counter in the payments slice for the
		// failed attempt.
		payments[i].htlcs++

		// Depending on the test case, fail or succeed the next
		// attempt.
		attempt.AttemptID = attemptID
		attemptID++

		_, err = p.RegisterAttempt(info.PaymentIdentifier, attempt)
		require.NoError(t, err, "unable to send htlc message")

		switch payments[i].status {
		// Fail the attempt and the payment overall.
		case StatusFailed:
			htlcFailure := HTLCFailUnreadable
			_, err = p.FailAttempt(
				info.PaymentIdentifier, attempt.AttemptID,
				&HTLCFailInfo{
					Reason: htlcFailure,
				},
			)
			require.NoError(t, err, "unable to fail htlc")

			failReason := FailureReasonNoRoute
			_, err = p.Fail(info.PaymentIdentifier,
				failReason)
			require.NoError(t, err, "unable to fail payment hash")

		// Settle the attempt
		case StatusSucceeded:
			_, err := p.SettleAttempt(
				info.PaymentIdentifier, attempt.AttemptID,
				&HTLCSettleInfo{
					Preimage: preimg,
				},
			)
			require.NoError(t, err, "no error should have been "+
				"received from settling a htlc attempt")

		// We leave the attempt in-flight by doing nothing.
		case StatusInFlight:
		}

		// Increase the HTLC counter in the payments slice for any
		// attempt above.
		payments[i].htlcs++
	}
}

// assertPayments is a helper function that given a slice of payment and
// indices for the slice asserts that exactly the same payments in the
// slice for the provided indices exist when fetching payments from the
// database.
func assertPayments(t *testing.T, db *DB, payments []*payment) {
	t.Helper()

	dbPayments, err := db.FetchPayments()
	require.NoError(t, err, "could not fetch payments from db")

	// Make sure that the number of fetched payments is the same
	// as expected.
	require.Len(t, dbPayments, len(payments), "unexpected number of payments")

	// Convert fetched payments of type MPPayment to our helper structure.
	p := make([]*payment, len(dbPayments))
	for i, dbPayment := range dbPayments {
		p[i] = &payment{
			id:     dbPayment.Info.PaymentIdentifier,
			status: dbPayment.Status,
			htlcs:  len(dbPayment.HTLCs),
		}
	}

	// Check that each payment we want to assert exists in the database.
	require.Equal(t, payments, p)
}


text:
extern "C" {
#endif // __cplusplus

#if (GSLC_FEATURE_COMPOUND)
// ============================================================================
// Extended Element: SelNum (Number Selector)
// - Demonstration of a compound element consisting of
//   a counter text field along with an increment and
//   decrement button.
// ============================================================================

// Define unique identifier for extended element type
// - Select any number above GSLC_TYPE_BASE_EXTEND
#define  GSLC_TYPEX_SELNUM GSLC_TYPE_BASE_EXTEND + 3

#define SELNUM_STR_LEN  6

// Extended element data structures
// - These data structures are maintained in the gslc_tsElem
//   structure via the pXData pointer
/// Extended data for SelNum element
typedef struct {

  // Core functionality for SelNum
  int16_t             nCounter;       ///< Counter for demo purposes

  // Internal sub-element members
  gslc_tsCollect      sCollect;       ///< Collection management for sub-elements
  gslc_tsElemRef      asElemRef[4];   ///< Storage for sub-element references
  gslc_tsElem         asElem[4];      ///< Storage for sub-elements

  #if (GSLC_LOCAL_STR == 0)
  // If elements don't provide their own internal string buffer, then
  // we need to provide storage here in the extended data of the compound
  // element. For now, simply provide a fixed-length memory buffer.
  char                acElemTxt[4][SELNUM_STR_LEN]; ///< Storage for strings
  #endif
} gslc_tsXSelNum;

///
/// Create a SelNum Element
///
/// \param[in]  pGui:        Pointer to GUI
/// \param[in]  nElemId:     Element ID to assign (0..16383 or GSLC_ID_AUTO to autogen)
/// \param[in]  nPage:       Page ID to attach element to
/// \param[in]  pXData:      Ptr to extended element data structure
/// \param[in]  rElem:       Rectangle coordinates defining element size
/// \param[in]  nFontId:     Font ID to use for drawing the element
///
/// \return Pointer to Element or NULL if failure
///
gslc_tsElemRef* gslc_ElemXSelNumCreate(gslc_tsGui* pGui,int16_t nElemId,int16_t nPage,
  gslc_tsXSelNum* pXData,gslc_tsRect rElem,int8_t nFontId);

///
/// Draw a SelNum element on the screen
/// - Called during redraw
///
/// \param[in]  pvGui:       Void ptr to GUI (typecast to gslc_tsGui*)
/// \param[in]  pvElemRef:   Void ptr to Element reference (typecast to gslc_tsElemRef*)
/// \param[in]  eRedraw:     Redraw mode
///
/// \return true if success, false otherwise
///
bool gslc_ElemXSelNumDraw(void* pvGui,void* pvElemRef,gslc_teRedrawType eRedraw);

///
/// Get the current counter associated with SelNum
///
/// \param[in]  pGui:        Ptr to GUI
/// \param[in]  pSelNum:     Ptr to Element
///
/// \return Current counter value
///
int gslc_ElemXSelNumGetCounter(gslc_tsGui* pGui,gslc_tsXSelNum* pSelNum);

///
/// Set the current counter associated with SelNum
///
/// \param[in]  pGui:        Pointer to GUI
/// \param[in]  pSelNum:     Ptr to Element
/// \param[in]  nCount:      New counter value
///
/// \return none
///
void gslc_ElemXSelNumSetCounter(gslc_tsGui* pGui,gslc_tsXSelNum* pSelNum,int16_t nCount);

///
/// Handle a click event within the SelNum
/// - This is called internally by the SelNum touch handler
///
/// \param[in]  pvGui:       Void ptr to GUI (typecast to gslc_tsGui*)
/// \param[in]  pvElemRef:   Void ptr to Element reference (typecast to gslc_tsElemRef*)
/// \param[in]  eTouch:      Touch event type
/// \param[in]  nX:          Touch X coord
/// \param[in]  nY:          Touch Y coord
///
/// \return none
///
bool gslc_ElemXSelNumClick(void* pvGui,void *pvElemRef,gslc_teTouch eTouch,int16_t nX,int16_t nY);

///
/// Handle touch (up,down,move) events to SelNum element
/// - Called from gslc_ElemSendEventTouch()
///
/// \param[in]  pvGui:       Void ptr to GUI (typecast to gslc_tsGui*)
/// \param[in]  pvElemRef:   Void ptr to Element reference (typecast to gslc_tsElemRef*)
/// \param[in]  eTouch:      Touch event type
/// \param[in]  nRelX:       Touch X coord relative to element
/// \param[in]  nRelY:       Touch Y coord relative to element
///
/// \return true if success, false otherwise
///
bool gslc_ElemXSelNumTouch(void* pvGui,void* pvElemRef,gslc_teTouch eTouch,int16_t nRelX,int16_t nRelY);
#endif // GLSC_COMPOUND

// ============================================================================

// ------------------------------------------------------------------------
// Read-only element macros
// ------------------------------------------------------------------------

// Macro initializers for Read-Only Elements in Flash/PROGMEM
//
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // _GUISLICE_EX_XSELNUM_H_


text:
package com.angkorteam.fintech.pages.staff;

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

import org.apache.wicket.WicketRuntimeException;
import org.apache.wicket.authroles.authorization.strategies.role.annotations.AuthorizeInstantiation;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.filter.FilterForm;
import com.angkorteam.fintech.widget.WebMarkupContainer;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.request.mapper.parameter.PageParameters;

import com.angkorteam.fintech.Page;
import com.angkorteam.fintech.ddl.MOffice;
import com.angkorteam.fintech.ddl.MStaff;
import com.angkorteam.fintech.dto.Function;
import com.angkorteam.fintech.layout.Size;
import com.angkorteam.fintech.pages.OrganizationDashboardPage;
import com.angkorteam.fintech.provider.JdbcProvider;
import com.angkorteam.fintech.table.BadgeCell;
import com.angkorteam.fintech.table.LinkCell;
import com.angkorteam.fintech.table.TextCell;
import com.angkorteam.fintech.widget.WebMarkupBlock;
import com.angkorteam.framework.BadgeType;
import com.angkorteam.framework.models.PageBreadcrumb;
import com.angkorteam.framework.wicket.extensions.markup.html.repeater.data.table.DataTable;
import com.angkorteam.framework.wicket.extensions.markup.html.repeater.data.table.DefaultDataTable;
import com.angkorteam.framework.wicket.extensions.markup.html.repeater.data.table.filter.FilterToolbar;
import com.angkorteam.framework.wicket.extensions.markup.html.repeater.data.table.filter.ItemClass;
import com.angkorteam.framework.wicket.extensions.markup.html.repeater.data.table.filter.ItemPanel;
import com.angkorteam.framework.wicket.extensions.markup.html.repeater.data.table.filter.TextFilterColumn;
import com.google.common.collect.Lists;

/**
 * Created by socheatkhauv on 6/26/17.
 */
@AuthorizeInstantiation(Function.ALL_FUNCTION)
public class StaffBrowsePage extends Page {

    protected WebMarkupBlock dataBlock;
    protected WebMarkupContainer dataIContainer;
    protected DataTable<Map<String, Object>, String> dataTable;
    protected JdbcProvider dataProvider;
    protected List<IColumn<Map<String, Object>, String>> dataColumn;
    protected FilterForm<Map<String, String>> dataFilterForm;

    protected BookmarkablePageLink<Void> createLink;

    @Override
    public IModel<List<PageBreadcrumb>> buildPageBreadcrumb() {
        List<PageBreadcrumb> BREADCRUMB = Lists.newArrayList();
        {
            PageBreadcrumb breadcrumb = new PageBreadcrumb();
            breadcrumb.setLabel("Admin");
            BREADCRUMB.add(breadcrumb);
        }
        {
            PageBreadcrumb breadcrumb = new PageBreadcrumb();
            breadcrumb.setLabel("Organization");
            breadcrumb.setPage(OrganizationDashboardPage.class);
            BREADCRUMB.add(breadcrumb);
        }
        {
            PageBreadcrumb breadcrumb = new PageBreadcrumb();
            breadcrumb.setLabel("Employee");
            BREADCRUMB.add(breadcrumb);
        }
        return Model.ofList(BREADCRUMB);
    }

    @Override
    protected void initData() {
    }

    @Override
    protected void initComponent() {
        initDataBlock();

        this.createLink = new BookmarkablePageLink<>("createLink", StaffCreatePage.class);
        add(this.createLink);
    }

    protected void initDataBlock() {
        this.dataBlock = new WebMarkupBlock("dataBlock", Size.Twelve_12);
        add(this.dataBlock);
        this.dataIContainer = new WebMarkupContainer("dataIContainer");
        this.dataBlock.add(this.dataIContainer);
        this.dataProvider = new JdbcProvider(MStaff.NAME);
        this.dataProvider.applyJoin("m_office", "LEFT JOIN " + MOffice.NAME + " ON " + MStaff.NAME + "." + MStaff.Field.OFFICE_ID + " = " + MOffice.NAME + "." + MOffice.Field.ID);
        this.dataProvider.boardField(MStaff.NAME + "." + MStaff.Field.ID, "id", Long.class);
        this.dataProvider.boardField(MStaff.NAME + "." + MStaff.Field.FIRST_NAME, "firstname", String.class);
        this.dataProvider.boardField(MStaff.NAME + "." + MStaff.Field.LAST_NAME, "lastname", String.class);
        this.dataProvider.boardField(MStaff.NAME + "." + MStaff.Field.IS_LOAN_OFFICER, "loan_officer", Boolean.class);
        this.dataProvider.boardField(MStaff.NAME + "." + MStaff.Field.IS_ACTIVE, "active", Boolean.class);
        this.dataProvider.boardField(MOffice.NAME + "." + MOffice.Field.NAME, "office", String.class);

        this.dataColumn = Lists.newArrayList();
        this.dataColumn.add(new TextFilterColumn(this.dataProvider, ItemClass.Long, Model.of("ID"), "id", "id", this::dataColumn));
        this.dataColumn.add(new TextFilterColumn(this.dataProvider, ItemClass.String, Model.of("First Name"), "firstname", "firstname", this::dataColumn));
        this.dataColumn.add(new TextFilterColumn(this.dataProvider, ItemClass.String, Model.of("Last Name"), "lastname", "lastname", this::dataColumn));
        this.dataColumn.add(new TextFilterColumn(this.dataProvider, ItemClass.Boolean, Model.of("Is Loan Officer"), "loan_officer", "loan_officer", this::dataColumn));
        this.dataColumn.add(new TextFilterColumn(this.dataProvider, ItemClass.Boolean, Model.of("Active"), "active", "active", this::dataColumn));
        this.dataColumn.add(new TextFilterColumn(this.dataProvider, ItemClass.String, Model.of("Office"), "office", "office", this::dataColumn));

        this.dataFilterForm = new FilterForm<>("dataFilterForm", this.dataProvider);
        this.dataIContainer.add(this.dataFilterForm);

        this.dataTable = new DefaultDataTable<>("dataTable", this.dataColumn, this.dataProvider, 20);
        this.dataTable.addTopToolbar(new FilterToolbar(this.dataTable, this.dataFilterForm));
        this.dataFilterForm.add(this.dataTable);
    }

    @Override
    protected void configureMetaData() {
    }

    protected ItemPanel dataColumn(String column, IModel<String> display, Map<String, Object> model) {
        if ("id".equals(column)) {
            Long value = (Long) model.get(column);
            PageParameters parameters = new PageParameters();
            parameters.add("staffId", model.get("id"));
            return new LinkCell(StaffModifyPage.class, parameters, value);
        } else if ("firstname".equals(column) || "lastname".equals(column) || "office".equals(column)) {
            String value = (String) model.get(column);
            return new TextCell(value);
        } else if ("loan_officer".equals(column)) {
            Boolean loanOfficer = (Boolean) model.get(column);
            if (loanOfficer != null && loanOfficer) {
                return new BadgeCell(BadgeType.Success, Model.of("Yes"));
            } else {
                return new BadgeCell(BadgeType.Danger, Model.of("No"));
            }
        } else if ("active".equals(column)) {
            Boolean active = (Boolean) model.get(column);
            if (active != null && active) {
                return new BadgeCell(BadgeType.Success, Model.of("Yes"));
            } else {
                return new BadgeCell(BadgeType.Danger, Model.of("No"));
            }
        }
        throw new WicketRuntimeException("Unknown " + column);
    }

}


text:
function ParticleEditorPlugin::initDefaultSettings( %this ) {
	Lab.addDefaultSetting( "selectedEmitter", PEE_EmitterSelector.getText() );
	Lab.addDefaultSetting( "selectedParticle", PEP_ParticleSelector.getText() );
	Lab.addDefaultSetting( "selectedTab", PE_TabBook.getSelectedPage() );
	Lab.addDefaultSetting( "DefaultEmitter", "DefaultEmitter" );
	Lab.addDefaultSetting( "DefaultParticle", "DefaultParticle" );
}

//==============================================================================
// Automated editor plugin setting interface
function ParticleEditorPlugin::buildParams(%this,%params ) {
// Group 1 Configuration
	%gid++;
	%pid = 0;
	%params.groupData[%gid] = "General settings" TAB "Params_Stack" TAB "Rollout";
	%params.groupParam[%gid,%pid++] = "DefaultEmitter"  TAB "" TAB "TextEdit";
	%params.groupParam[%gid,%pid++] = "DefaultParticle"  TAB "" TAB "TextEdit";
	return %params;
}
//------------------------------------------------------------------------------