text:
package com.google.leafcoin.protocols.channels;

import com.google.leafcoin.core.ECKey;
import com.google.leafcoin.core.InsufficientMoneyException;
import com.google.leafcoin.core.Sha256Hash;
import com.google.leafcoin.core.Wallet;
import com.google.leafcoin.net.NioClient;
import com.google.leafcoin.net.ProtobufParser;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import org.bitcoin.paymentchannel.Protos;

import java.io.IOException;
import java.math.BigInteger;
import java.net.InetSocketAddress;

/**
 * A simple utility class that runs the micropayment protocol over a raw TCP socket using NIO, standalone.
 */
public class PaymentChannelClientConnection {
    // Various futures which will be completed later
    private final SettableFuture<PaymentChannelClientConnection> channelOpenFuture = SettableFuture.create();

    private final PaymentChannelClient channelClient;
    private final ProtobufParser<Protos.TwoWayChannelMessage> wireParser;

    /**
     * Attempts to open a new connection to and open a payment channel with the given host and port, blocking until the
     * connection is open
     *
     * @param server The host/port pair where the server is listening.
     * @param timeoutSeconds The connection timeout and read timeout during initialization. This should be large enough
     *                       to accommodate ECDSA signature operations and network latency.
     * @param wallet The wallet which will be paid from, and where completed transactions will be committed.
     *               Must already have a {@link StoredPaymentChannelClientStates} object in its extensions set.
     * @param myKey A freshly generated keypair used for the multisig contract and refund output.
     * @param maxValue The maximum value this channel is allowed to request
     * @param serverId A unique ID which is used to attempt reopening of an existing channel.
     *                 This must be unique to the server, and, if your application is exposing payment channels to some
     *                 API, this should also probably encompass some caller UID to avoid applications opening channels
     *                 which were created by others.
     *
     * @throws IOException if there's an issue using the network.
     * @throws ValueOutOfRangeException if the balance of wallet is lower than maxValue.
     */
    public PaymentChannelClientConnection(InetSocketAddress server, int timeoutSeconds, Wallet wallet, ECKey myKey,
                                          BigInteger maxValue, String serverId) throws IOException, ValueOutOfRangeException {
        // Glue the object which vends/ingests protobuf messages in order to manage state to the network object which
        // reads/writes them to the wire in length prefixed form.
        channelClient = new PaymentChannelClient(wallet, myKey, maxValue, Sha256Hash.create(serverId.getBytes()),
              new PaymentChannelClient.ClientConnection() {
            @Override
            public void sendToServer(Protos.TwoWayChannelMessage msg) {
                wireParser.write(msg);
            }

            @Override
            public void destroyConnection(PaymentChannelCloseException.CloseReason reason) {
                channelOpenFuture.setException(new PaymentChannelCloseException("Payment channel client requested that the connection be closed: " + reason, reason));
                wireParser.closeConnection();
            }

            @Override
            public void channelOpen(boolean wasInitiated) {
                wireParser.setSocketTimeout(0);
                // Inform the API user that we're done and ready to roll.
                channelOpenFuture.set(PaymentChannelClientConnection.this);
            }
        });

        // And glue back in the opposite direction - network to the channelClient.
        wireParser = new ProtobufParser<Protos.TwoWayChannelMessage>(new ProtobufParser.Listener<Protos.TwoWayChannelMessage>() {
            @Override
            public void messageReceived(ProtobufParser handler, Protos.TwoWayChannelMessage msg) {
                try {
                    channelClient.receiveMessage(msg);
                } catch (InsufficientMoneyException e) {
                    // We should only get this exception during INITIATE, so channelOpen wasn't called yet.
                    channelOpenFuture.setException(e);
                }
            }

            @Override
            public void connectionOpen(ProtobufParser handler) {
                channelClient.connectionOpen();
            }

            @Override
            public void connectionClosed(ProtobufParser handler) {
                channelClient.connectionClosed();
                channelOpenFuture.setException(new PaymentChannelCloseException("The TCP socket died",
                        PaymentChannelCloseException.CloseReason.CONNECTION_CLOSED));
            }
        }, Protos.TwoWayChannelMessage.getDefaultInstance(), Short.MAX_VALUE, timeoutSeconds*1000);

        // Initiate the outbound network connection. We don't need to keep this around. The wireParser object will handle
        // things from here on out.
        new NioClient(server, wireParser, timeoutSeconds * 1000);
    }

    /**
     *
Gets a future which returns this when the channel is successfully opened, or throws an exception if there is
     * an error before the channel has reached the open state.

     *
     *
After this future completes successfully, you may call
     * {@link PaymentChannelClientConnection#incrementPayment(java.math.BigInteger)} to begin paying the server.

     */
    public ListenableFuture<PaymentChannelClientConnection> getChannelOpenFuture() {
        return channelOpenFuture;
    }

    /**
     * Increments the total value which we pay the server.
     *
     * @param size How many satoshis to increment the payment by (note: not the new total).
     * @throws ValueOutOfRangeException If the size is negative or would pay more than this channel's total value
     *                                  ({@link PaymentChannelClientConnection#state()}.getTotalValue())
     * @throws IllegalStateException If the channel has been closed or is not yet open
     *                               (see {@link PaymentChannelClientConnection#getChannelOpenFuture()} for the second)
     */
    public ListenableFuture<BigInteger> incrementPayment(BigInteger size) throws ValueOutOfRangeException, IllegalStateException {
        return channelClient.incrementPayment(size);
    }

    /**
     *
Gets the {@link PaymentChannelClientState} object which stores the current state of the connection with the
     * server.

     *
     *
Note that if you call any methods which update state directly the server will not be notified and channel
     * initialization logic in the connection may fail unexpectedly.

     */
    public PaymentChannelClientState state() {
        return channelClient.state();
    }

    /**
     * Closes the connection, notifying the server it should settle the channel by broadcasting the most recent payment
     * transaction.
     */
    public void settle() {
        // Shutdown is a little complicated.
        //
        // This call will cause the CLOSE message to be written to the wire, and then the destroyConnection() method that
        // we defined above will be called, which in turn will call wireParser.closeConnection(), which in turn will invoke
        // NioClient.closeConnection(), which will then close the socket triggering interruption of the network
        // thread it had created. That causes the background thread to die, which on its way out calls
        // ProtobufParser.connectionClosed which invokes the connectionClosed method we defined above which in turn
        // then configures the open-future correctly and closes the state object. Phew!
        try {
            channelClient.settle();
        } catch (IllegalStateException e) {
            // Already closed...oh well
        }
    }

    /**
     * Disconnects the network connection but doesn't request the server to settle the channel first (literally just
     * unplugs the network socket and marks the stored channel state as inactive).
     */
    public void disconnectWithoutSettlement() {
        wireParser.closeConnection();
    }
}


text:
package org.apache.camel.component.cxf.jaxws;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.ws.BindingProvider;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.component.cxf.common.CXFTestSupport;
import org.apache.camel.component.cxf.common.message.CxfConstants;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.message.Message;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

// We use context to change the producer's endpoint address here
public class CxfProducerContextTest extends CxfProducerTest {

    // *** This class extends CxfProducerTest, so see that class for other tests
    // run by this code

    private static final String TEST_KEY = "sendSimpleMessage-test";
    private static final String TEST_VALUE = "exchange property value should get passed through request context";

    @Test
    public void testExchangePropertyPropagation() throws Exception {
        Exchange exchange = sendSimpleMessage();

        // No direct access to native CXF Message but we can verify the
        // request context from the Camel exchange
        assertNotNull(exchange);
        String actualValue = (String) exchange.getProperties().get(TEST_KEY);
        assertEquals(TEST_VALUE, actualValue, "exchange property should get propagated to the request context");
    }

    @Override
    protected String getSimpleEndpointUri() {
        return "cxf://http://localhost:" + CXFTestSupport.getPort4()
               + "/CxfProducerContextTest/simple?serviceClass=org.apache.camel.component.cxf.jaxws.HelloService";
    }

    @Override
    protected String getJaxwsEndpointUri() {
        return "cxf://http://localhost:" + CXFTestSupport.getPort4()
               + "/CxfProducerContextTest/jaxws?serviceClass=org.apache.hello_world_soap_http.Greeter";
    }

    @Override
    protected Exchange sendSimpleMessage() {
        Exchange exchange = template.send(getSimpleEndpointUri(), new Processor() {
            public void process(final Exchange exchange) {
                final List<String> params = new ArrayList<>();
                params.add(TEST_MESSAGE);
                Map<String, Object> requestContext = new HashMap<>();
                requestContext.put(Message.ENDPOINT_ADDRESS, getSimpleServerAddress());
                exchange.getIn().setBody(params);
                exchange.getIn().setHeader(Client.REQUEST_CONTEXT, requestContext);
                exchange.getIn().setHeader(CxfConstants.OPERATION_NAME, ECHO_OPERATION);
                exchange.getIn().setHeader(Exchange.FILE_NAME, "testFile");
                exchange.getIn().setHeader("requestObject", new DefaultCxfBinding());
                exchange.getProperties().put(TEST_KEY, TEST_VALUE);
            }
        });
        return exchange;

    }

    @Override
    protected Exchange sendJaxWsMessage() {
        Exchange exchange = template.send(getJaxwsEndpointUri(), new Processor() {
            public void process(final Exchange exchange) {
                final List<String> params = new ArrayList<>();
                params.add(TEST_MESSAGE);
                Map<String, Object> requestContext = new HashMap<>();
                requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, getJaxWsServerAddress());
                exchange.getIn().setBody(params);
                exchange.getIn().setHeader(Client.REQUEST_CONTEXT, requestContext);
                exchange.getIn().setHeader(CxfConstants.OPERATION_NAME, GREET_ME_OPERATION);
                exchange.getIn().setHeader(Exchange.FILE_NAME, "testFile");
            }
        });
        return exchange;
    }

}

redpajama_set_name: RedPajamaGithub


text:
package com.intellij.openapi.roots.ui.configuration.classpath;

import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
import org.jetbrains.annotations.Nullable;

/**
* @author nik
*/
class ClasspathTableItem<T extends OrderEntry> {
  @Nullable protected final T myEntry;
  private final boolean myRemovable;

  @Nullable
  public static ClasspathTableItem<?> createItem(OrderEntry orderEntry, StructureConfigurableContext context) {
    if (orderEntry instanceof JdkOrderEntry) {
      return new ClasspathTableItem<OrderEntry>(orderEntry, false);
    }
    else if (orderEntry instanceof LibraryOrderEntry) {
      return createLibItem((LibraryOrderEntry)orderEntry, context);
    }
    else if (orderEntry instanceof ModuleOrderEntry) {
      return new ClasspathTableItem<OrderEntry>(orderEntry, true);
    }
    else if (orderEntry instanceof ModuleSourceOrderEntry) {
      return new ClasspathTableItem<OrderEntry>(orderEntry, false);
    }
    return null;
  }

  public static ClasspathTableItem<LibraryOrderEntry> createLibItem(final LibraryOrderEntry orderEntry, final StructureConfigurableContext context) {
    return new LibraryItem(orderEntry, context);
  }

  protected ClasspathTableItem(@Nullable T entry, boolean removable) {
    myEntry = entry;
    myRemovable = removable;
  }

  public final boolean isExportable() {
    return myEntry instanceof ExportableOrderEntry;
  }

  public final boolean isExported() {
    return myEntry instanceof ExportableOrderEntry && ((ExportableOrderEntry)myEntry).isExported();
  }

  public final void setExported(boolean isExported) {
    if (myEntry instanceof ExportableOrderEntry) {
      ((ExportableOrderEntry)myEntry).setExported(isExported);
    }
  }

  @Nullable
  public final DependencyScope getScope() {
    return myEntry instanceof ExportableOrderEntry ? ((ExportableOrderEntry) myEntry).getScope() : null;
  }

  public final void setScope(DependencyScope scope) {
    if (myEntry instanceof ExportableOrderEntry) {
      ((ExportableOrderEntry) myEntry).setScope(scope);
    }
  }

  @Nullable
  public final T getEntry() {
    return myEntry;
  }

  public boolean isRemovable() {
    return myRemovable;
  }

  public boolean isEditable() {
    return false;
  }

  @Nullable
  public String getTooltipText() {
    return null;
  }

}


text:
import React from 'react';
import { shallow } from 'enzyme';
import { expect } from 'chai';
import { Vehicles } from '../Vehicles';

describe('<Vehicles />', () => {
  it('should have a class .vehicles', () => {
    const props = {
      base: {
        isFetching: false,
        vehicles: []
      }
    };
    expect(shallow(<Vehicles {...props} />).is('.vehicles')).to.equal(true);
  });
});


text:
FROM golang:1.10.0-stretch

VOLUME ["/opt/go/src/github.com/diegobernardes/flare"]

WORKDIR /opt/go/src/github.com/diegobernardes/flare/service/flare/cmd

CMD go build -o /opt/flare/flare flare.go \
  && cd /opt/flare \
  && ./flare start


text:
enum errorcodes {
    OK = 0,

    //Twitter errors.

    EAUTHFL = 32, //Could not authenticate you.
    ENOEXST = 34, //Page does not exist
    ESUSPEN = 64, //Acct suspended
    EOLDAPI = 68, //REST API obsolete
    ERATELM = 88, //Rate limit exceeded
    EINVTKN = 89, //Invalid token
    ESSLREQ = 92, //SSL is required
    EOVERCP = 130, //Over capacity
    EINTERR = 131, //Internal error
    EAUTHTM = 135, //Invalid oauth timestamp
    ENOFLLW = 161, //Unable to follow more
    ESTATPR = 179, //Status protected
    EULIMIT = 185, //Over daily update limit
    EDUPLIC = 187, //Duplicate status
    EBADAUT = 215, //Bad auth data
    ESPAM = 226, //Could be automated
		//also results if you try to post anything with an old official Twitter client keys.

    EVERIFY = 231, //User must verify
    ERETIRE = 251, //Endpoint retired
    ERDONLY = 261, //App can't write
    EMTSELF = 271, //Can't mute self
    ENOMUTE = 272, //Not muting this user.

    //HTTP errors

    HTTPOK = 200, //OK

    ENOTMOD = 304, //Not Modified
    EBADREQ = 400, //Bad Request
    EUNAUTH = 401, //Unauthotized
    EFORBID = 403, //Forbidden
    ENOTFND = 404, //Not Found
    ENOTACC = 406, //Not Acceptable.
    EGONE = 410, //Gone.
    ESLOW = 420, //Slow down, please.
    EUNPROC = 422, //Unprocessable Entity
    EOVERLD = 429, //Too Many Requests
    EINTERN = 500, //Internal Server Error
    EBADGW = 502, //Bad Gateway
    EUAVAIL = 503, //Service Unavailable
    EGWTIME = 504, //Gateway Timeout
};

struct t_oauthkey; //oblique oauth data struct

struct t_account {
    //this structure refers to twitter log-in accounts
    char name[16]; //acct screen name
    uint64_t userid; //acct user id
    uint8_t auth; //is authorized(access token) or not(req token)?
    char show_in_timeline; //show this account's tweets in global timelines.
    struct t_oauthkey* key; //account's oauth data
    enum errorcodes t_errno; //HTTP or Twitter error code
};

// add or remove acct in acctlist
int add_acct(struct t_account* acct);
int del_acct(struct t_account* acct);

// return account specified or default account if NULL
struct t_account* def_acct(struct t_account* acct);

int acct_id(struct t_account* acct);

// returns an oauth-signed URL to use. the returned URL will be malloc'd, so don't forget to free() it.
char* acct_sign_url2(const char* url, char** postargs, OAuthMethod method, const char* http_method, struct t_account* acct);

#endif


text:
"""Provides a thread-local transactional wrapper around the root Engine class.

The ``threadlocal`` module is invoked when using the ``strategy="threadlocal"`` flag
with :func:`~sqlalchemy.engine.create_engine`.  This module is semi-private and is
invoked automatically when the threadlocal engine strategy is used.
"""

from sqlalchemy import util, event
from sqlalchemy.engine import base
import weakref

class TLConnection(base.Connection):
    def __init__(self, *arg, **kw):
        super(TLConnection, self).__init__(*arg, **kw)
        self.__opencount = 0

    def _increment_connect(self):
        self.__opencount += 1
        return self

    def close(self):
        if self.__opencount == 1:
            base.Connection.close(self)
        self.__opencount -= 1

    def _force_close(self):
        self.__opencount = 0
        base.Connection.close(self)

class TLEngine(base.Engine):
    """An Engine that includes support for thread-local managed transactions."""

    _tl_connection_cls = TLConnection

    def __init__(self, *args, **kwargs):
        super(TLEngine, self).__init__(*args, **kwargs)
        self._connections = util.threading.local()

    def contextual_connect(self, **kw):
        if not hasattr(self._connections, 'conn'):
            connection = None
        else:
            connection = self._connections.conn()

        if connection is None or connection.closed:
            # guards against pool-level reapers, if desired.
            # or not connection.connection.is_valid:
            connection = self._tl_connection_cls(self, self.pool.connect(), **kw)
            self._connections.conn = conn = weakref.ref(connection)

        return connection._increment_connect()

    def begin_twophase(self, xid=None):
        if not hasattr(self._connections, 'trans'):
            self._connections.trans = []
        self._connections.trans.append(self.contextual_connect().begin_twophase(xid=xid))
        return self

    def begin_nested(self):
        if not hasattr(self._connections, 'trans'):
            self._connections.trans = []
        self._connections.trans.append(self.contextual_connect().begin_nested())
        return self

    def begin(self):
        if not hasattr(self._connections, 'trans'):
            self._connections.trans = []
        self._connections.trans.append(self.contextual_connect().begin())
        return self

    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        if type is None:
            self.commit()
        else:
            self.rollback()

    def prepare(self):
        if not hasattr(self._connections, 'trans') or \
            not self._connections.trans:
            return
        self._connections.trans[-1].prepare()

    def commit(self):
        if not hasattr(self._connections, 'trans') or \
            not self._connections.trans:
            return
        trans = self._connections.trans.pop(-1)
        trans.commit()

    def rollback(self):
        if not hasattr(self._connections, 'trans') or \
            not self._connections.trans:
            return
        trans = self._connections.trans.pop(-1)
        trans.rollback()

    def dispose(self):
        self._connections = util.threading.local()
        super(TLEngine, self).dispose()

    @property
    def closed(self):
        return not hasattr(self._connections, 'conn') or \
                self._connections.conn() is None or \
                self._connections.conn().closed

    def close(self):
        if not self.closed:
            self.contextual_connect().close()
            connection = self._connections.conn()
            connection._force_close()
            del self._connections.conn
            self._connections.trans = []

    def __repr__(self):
        return 'TLEngine(%s)' % str(self.url)


text:
ACCEPTED

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
Bull. int. Acad. Sci. Lett. Cracovie, Cl. sci. math. nat. Sér. B, sci. nat. (1908)

#### Original name
Bacillopsis stylopygae Petsch., 1908

### Remarks
null


text:
<?php

namespace Ecailles\CallableObject;

/**
 * Class CallableObject
 *
 * @package Ecailles\CallableObject
 */
class CallableObject
{
    /**
     * @var callable The callable.
     */
    private $callable = null;

    /**
     * The constructor.
     *
     * @param callable $callable A callable.
     */
    public function __construct(callable $callable)
    {
        if (is_string($callable) && strpos($callable, '::') !== false) {
            $callable = explode('::', $callable);
        }

        $this->callable = $callable;
    }

    /**
     * Invokes the callable with parameter(s).
     *
     * @return mixed The return value.
     */
    public function __invoke()
    {
        return $this->invokeArgs(func_get_args());
    }

    /**
     * Invokes the callable with parameter(s).
     *
     * @return mixed The return value.
     */
    public function invoke()
    {
        return $this->invokeArgs(func_get_args());
    }

    /**
     * Invokes the callable with an array of parameter(s).
     *
     * @param array $parameters The parameter(s) to be passed to the callable.
     *
     * @return mixed The return value.
     */
    public function invokeArgs(array $parameters = [])
    {
        return call_user_func_array($this->callable, $parameters);
    }

    /**
     * Returns the raw callable.
     *
     * @return callable The callable.
     */
    public function get()
    {
        return $this->callable;
    }

    /**
     * Returns whether the callable is a function.
     *
     * @return bool True if it is a function, false otherwise.
     */
    public function isFunction()
    {
        return is_string($this->callable);
    }

    /**
     * Returns whether the callable is a closure.
     *
     * @return bool True if it is a Closure, false otherwise.
     */
    public function isClosure()
    {
        return is_object($this->callable);
    }

    /**
     * Returns whether the callable is an instance method.
     *
     * @return bool True if it is an instance method, false otherwise.
     */
    public function isInstanceMethod()
    {
        return is_array($this->callable) && is_object($this->callable[0]);
    }

    /**
     * Returns whether the callable is a class method.
     *
     * @return bool True if it is a class method, false otherwise.
     */
    public function isClassMethod()
    {
        return is_array($this->callable) && is_string($this->callable[0]);
    }
}


text:
@interface BookDetailViewController : UIViewController
@property (nonatomic) id bookId;
@property (nonatomic) id bookTitle;
@end


text:
layout: home
permalink: /articles/index.html
title: "Articles"
tags: [content technology, photography, cycling, product management]
---


text:
using System;
using System.Globalization;
using System.IO;
using System.Reactive.Concurrency;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Threading.Tasks;
using ReactiveGpio.Drivers;

namespace ReactiveGpio
{
    public class InputPort : IDisposable, IObservable<bool>
    {
        private readonly IGpioDriver _driver;
        private readonly string _pin;
        private int _pollFd;

        private IObservable<bool> _readings;

        private InputPort(int pin, IGpioDriver driver)
        {
            _driver = driver;
            _pin = pin.ToString(CultureInfo.InvariantCulture);
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        public IDisposable Subscribe(IObserver<bool> observer)
        {
            return _readings.Subscribe(observer);
        }

        public static async Task<InputPort> Create(int pin, GpioEdge edge, IGpioDriver driver = null)
        {
            var port = new InputPort(pin, driver ?? new FileDriver());

            // If port already exists delete and recreate it
            if (Directory.Exists(GpioPath.Path(pin)))
                await port.UnAssignPin();
            await port.AssignPin();

            await port.SetDirection();
            await port.SetEdge(edge);
            port.SetupInterrupt();

            return port;
        }

        private void SetupInterrupt()
        {
            _pollFd = _driver.SetupInterrupt(_pin);

            _readings = Observable.Create<bool>(o =>
            {
                var cancel = new CancellationDisposable();

                NewThreadScheduler.Default.Schedule(async () =>
                {
                    while (true)
                    {
                        if (cancel.Token.IsCancellationRequested)
                        {
                            o.OnCompleted();
                            return;
                        }

                        try
                        {
                            var wait = _driver.WaitOnInterrupt(_pollFd);
                            if (wait <= 0)
                                continue;

                            o.OnNext(await ReadAsync());
                        }
                        catch (Exception e)
                        {
                            o.OnError(e);
                        }
                    }
                });

                return cancel;
            });
        }

        private async Task AssignPin()
        {
            await _driver.AssignPin(_pin);
        }

        private async Task UnAssignPin()
        {
            await _driver.UnAssignPin(_pin);
        }

        private async Task SetDirection()
        {
            await _driver.SetDirection(_pin, GpioDirection.In);
        }

        private async Task SetEdge(GpioEdge edge)
        {
            await _driver.SetEdge(_pin, edge);
        }

        public async Task<bool> ReadAsync()
        {
            return await _driver.ReadAsync(_pin);
        }

        public bool Read()
        {
            return _driver.Read(_pin);
        }

        private void Dispose(bool disposing)
        {
            if (disposing)
            {
                _driver.CloseInterrupt(_pollFd);
                UnAssignPin().Wait();
            }
        }
    }
}


text:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.magmaelemental.andiquiz.QuizActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Quiz is here"
        android:id="@+id/textView"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="93dp" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Go to quiz"
        android:id="@+id/btn_go_to_quiz"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:onClick="goToQuiz"/>

</RelativeLayout>


text:
package pl.vgtworld.imagedraw.filters.watermark;

import static org.assertj.core.api.Assertions.assertThat;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.junit.Before;
import org.junit.Test;

import pl.vgtworld.imagedraw.ImageDrawEntity;
import pl.vgtworld.imagedraw.ImageType;

public class WatermarkFilterSingleTest {

	private ImageDrawEntity image;

	private ImageDrawEntity watermark;

	@Before
	public void init() throws IOException {
		image = loadImage("/image-100-100.jpg");
		watermark = loadImage("/alpha-test.png");
	}

	@Test
	public void shouldPlaceWatermarkInUpperLeftCorner() {
		WatermarkFilter filter = new WatermarkFilter.Builder()
				.setType(WatermarkFilterType.SINGLE)
				.setWatermark(watermark)
				.setLocation(WatermarkLocation.UPPER_LEFT)
				.build();

		filter.doFilter(image, 0, 0, image.getImage().getWidth(), image.getImage().getHeight());
		Color transparentPixel = new Color(image.getImage().getRGB(5, 5));
		Color redPixel = new Color(image.getImage().getRGB(15, 5));
		Color greenPixel = new Color(image.getImage().getRGB(15, 15));
		Color bluePixel = new Color(image.getImage().getRGB(5, 15));

		assertThat(transparentPixel).isNotIn(Color.RED, Color.GREEN, Color.BLUE);
		assertThat(redPixel).isEqualTo(Color.RED);
		assertThat(greenPixel).isEqualTo(Color.GREEN);
		assertThat(bluePixel).isEqualTo(Color.BLUE);
	}

	@Test
	public void shouldPlaceWatermarkInUpperLeftCornerWithMargin() {
		WatermarkFilter filter = new WatermarkFilter.Builder()
				.setType(WatermarkFilterType.SINGLE)
				.setWatermark(watermark)
				.setLocation(WatermarkLocation.UPPER_LEFT)
				.setMargin(10)
				.build();

		filter.doFilter(image, 0, 0, image.getImage().getWidth(), image.getImage().getHeight());
		Color transparentPixel = new Color(image.getImage().getRGB(15, 15));
		Color redPixel = new Color(image.getImage().getRGB(25, 15));
		Color greenPixel = new Color(image.getImage().getRGB(25, 25));
		Color bluePixel = new Color(image.getImage().getRGB(15, 25));

		assertThat(transparentPixel).isNotIn(Color.RED, Color.GREEN, Color.BLUE);
		assertThat(redPixel).isEqualTo(Color.RED);
		assertThat(greenPixel).isEqualTo(Color.GREEN);
		assertThat(bluePixel).isEqualTo(Color.BLUE);
	}

	@Test
	public void shouldPlaceWatermarkInUpperRightCorner() {
		WatermarkFilter filter = new WatermarkFilter.Builder()
				.setType(WatermarkFilterType.SINGLE)
				.setWatermark(watermark)
				.setLocation(WatermarkLocation.UPPER_RIGHT)
				.build();

		filter.doFilter(image, 0, 0, image.getImage().getWidth(), image.getImage().getHeight());
		Color transparentPixel = new Color(image.getImage().getRGB(85, 5));
		Color redPixel = new Color(image.getImage().getRGB(95, 5));
		Color greenPixel = new Color(image.getImage().getRGB(95, 15));
		Color bluePixel = new Color(image.getImage().getRGB(85, 15));

		assertThat(transparentPixel).isNotIn(Color.RED, Color.GREEN, Color.BLUE);
		assertThat(redPixel).isEqualTo(Color.RED);
		assertThat(greenPixel).isEqualTo(Color.GREEN);
		assertThat(bluePixel).isEqualTo(Color.BLUE);
	}

	@Test
	public void shouldPlaceWatermarkInUpperRightCornerWithMargin() {
		WatermarkFilter filter = new WatermarkFilter.Builder()
				.setType(WatermarkFilterType.SINGLE)
				.setWatermark(watermark)
				.setLocation(WatermarkLocation.UPPER_RIGHT)
				.setMargin(10)
				.build();

		filter.doFilter(image, 0, 0, image.getImage().getWidth(), image.getImage().getHeight());
		Color transparentPixel = new Color(image.getImage().getRGB(75, 15));
		Color redPixel = new Color(image.getImage().getRGB(85, 15));
		Color greenPixel = new Color(image.getImage().getRGB(85, 25));
		Color bluePixel = new Color(image.getImage().getRGB(75, 25));

		assertThat(transparentPixel).isNotIn(Color.RED, Color.GREEN, Color.BLUE);
		assertThat(redPixel).isEqualTo(Color.RED);
		assertThat(greenPixel).isEqualTo(Color.GREEN);
		assertThat(bluePixel).isEqualTo(Color.BLUE);
	}

	@Test
	public void shouldPlaceWatermarkInLowerLeftCorner() {
		WatermarkFilter filter = new WatermarkFilter.Builder()
				.setType(WatermarkFilterType.SINGLE)
				.setWatermark(watermark)
				.setLocation(WatermarkLocation.LOWER_LEFT)
				.build();

		filter.doFilter(image, 0, 0, image.getImage().getWidth(), image.getImage().getHeight());
		Color transparentPixel = new Color(image.getImage().getRGB(5, 85));
		Color redPixel = new Color(image.getImage().getRGB(15, 85));
		Color greenPixel = new Color(image.getImage().getRGB(15, 95));
		Color bluePixel = new Color(image.getImage().getRGB(5, 95));

		assertThat(transparentPixel).isNotIn(Color.RED, Color.GREEN, Color.BLUE);
		assertThat(redPixel).isEqualTo(Color.RED);
		assertThat(greenPixel).isEqualTo(Color.GREEN);
		assertThat(bluePixel).isEqualTo(Color.BLUE);
	}

	@Test
	public void shouldPlaceWatermarkInLowerLeftCornerWithMargin() {
		WatermarkFilter filter = new WatermarkFilter.Builder()
				.setType(WatermarkFilterType.SINGLE)
				.setWatermark(watermark)
				.setLocation(WatermarkLocation.LOWER_LEFT)
				.setMargin(10)
				.build();

		filter.doFilter(image, 0, 0, image.getImage().getWidth(), image.getImage().getHeight());
		Color transparentPixel = new Color(image.getImage().getRGB(15, 75));
		Color redPixel = new Color(image.getImage().getRGB(25, 75));
		Color greenPixel = new Color(image.getImage().getRGB(25, 85));
		Color bluePixel = new Color(image.getImage().getRGB(15, 85));

		assertThat(transparentPixel).isNotIn(Color.RED, Color.GREEN, Color.BLUE);
		assertThat(redPixel).isEqualTo(Color.RED);
		assertThat(greenPixel).isEqualTo(Color.GREEN);
		assertThat(bluePixel).isEqualTo(Color.BLUE);
	}

	@Test
	public void shouldPlaceWatermarkInLowerRightCorner() {
		WatermarkFilter filter = new WatermarkFilter.Builder()
				.setType(WatermarkFilterType.SINGLE)
				.setWatermark(watermark)
				.setLocation(WatermarkLocation.LOWER_RIGHT)
				.build();

		filter.doFilter(image, 0, 0, image.getImage().getWidth(), image.getImage().getHeight());
		Color transparentPixel = new Color(image.getImage().getRGB(85, 85));
		Color redPixel = new Color(image.getImage().getRGB(95, 85));
		Color greenPixel = new Color(image.getImage().getRGB(95, 95));
		Color bluePixel = new Color(image.getImage().getRGB(85, 95));

		assertThat(transparentPixel).isNotIn(Color.RED, Color.GREEN, Color.BLUE);
		assertThat(redPixel).isEqualTo(Color.RED);
		assertThat(greenPixel).isEqualTo(Color.GREEN);
		assertThat(bluePixel).isEqualTo(Color.BLUE);
	}

	@Test
	public void shouldPlaceWatermarkInLowerRightCornerWithMargin() {
		WatermarkFilter filter = new WatermarkFilter.Builder()
				.setType(WatermarkFilterType.SINGLE)
				.setWatermark(watermark)
				.setLocation(WatermarkLocation.LOWER_RIGHT)
				.setMargin(10)
				.build();

		filter.doFilter(image, 0, 0, image.getImage().getWidth(), image.getImage().getHeight());
		Color transparentPixel = new Color(image.getImage().getRGB(75, 75));
		Color redPixel = new Color(image.getImage().getRGB(85, 75));
		Color greenPixel = new Color(image.getImage().getRGB(85, 85));
		Color bluePixel = new Color(image.getImage().getRGB(75, 85));

		assertThat(transparentPixel).isNotIn(Color.RED, Color.GREEN, Color.BLUE);
		assertThat(redPixel).isEqualTo(Color.RED);
		assertThat(greenPixel).isEqualTo(Color.GREEN);
		assertThat(bluePixel).isEqualTo(Color.BLUE);
	}

	@Test
	public void shouldPlaceWatermarkInCenter() {
		WatermarkFilter filter = new WatermarkFilter.Builder()
				.setType(WatermarkFilterType.SINGLE)
				.setWatermark(watermark)
				.setLocation(WatermarkLocation.CENTER)
				.build();

		filter.doFilter(image, 0, 0, image.getImage().getWidth(), image.getImage().getHeight());
		Color transparentPixel = new Color(image.getImage().getRGB(45, 45));
		Color redPixel = new Color(image.getImage().getRGB(55, 45));
		Color greenPixel = new Color(image.getImage().getRGB(55, 55));
		Color bluePixel = new Color(image.getImage().getRGB(45, 55));

		assertThat(transparentPixel).isNotIn(Color.RED, Color.GREEN, Color.BLUE);
		assertThat(redPixel).isEqualTo(Color.RED);
		assertThat(greenPixel).isEqualTo(Color.GREEN);
		assertThat(bluePixel).isEqualTo(Color.BLUE);
	}

	private ImageDrawEntity loadImage(String path) throws IOException {
		BufferedImage imageData = ImageIO.read(getClass().getResourceAsStream(path));
		return new ImageDrawEntity(imageData, ImageType.JPEG);
	}
}


text:
#ifndef ARM_COMPUTE_UTILS_REQUIRES_H
#define ARM_COMPUTE_UTILS_REQUIRES_H

namespace arm_compute
{
namespace utils
{
namespace requires
{
// *INDENT-OFF*
// clang-format off
namespace detail
{
enum class enabler
{
};
} // namespace arm_compute

/** Requirements as template */
#define ARM_COMPUTE_REQUIRES_T(...) template <bool Cond = (__VA_ARGS__), typename std::enable_if<Cond, int>::type = 0>
/** Requirements as template argument */
#define ARM_COMPUTE_REQUIRES_TA(...) typename = typename std::enable_if<(__VA_ARGS__), arm_compute::utils::requires::detail::enabler>::type
// clang-format on
// *INDENT-ON*
} // namespace requires
} // namespace utils
} // namespace arm_compute
#endif /*ARM_COMPUTE_UTILS_REQUIRES_H */


text:
import re
import os
import sys
import xml.etree.ElementTree as ET
import extract_pages
import requests

'''
Converts html template table to plaintext table and saves it
'''
def render(template_name, text, dest_dir):
    parser = ET.XMLPullParser(events=("start", "end"))
    parser.feed('<fakeroot>')
    parser.feed(text)

    filename = os.path.join(dest_dir, template_name.replace('Шаблон:', '').replace('/', '%') + '.table')
    of = open(filename, 'w')

    table = False

    try:
        for event, elem in parser.read_events():
            if event == 'start' and elem.tag == 'table' and 'style' in elem.attrib and re.match('float *: *right;', elem.attrib['style']):
                table = True

            if table and event == 'end' and elem.tag == 'table':
                break

            if table and event == 'end' and elem.tag == 'tr':
                print('', file=of)

            if table and event == 'end' and (elem.tag == 'th' or elem.tag == 'td'):
                text = elem.text
                if text is None:
                    a = elem.find('a')
                    if a is not None: text = a.text
                if text is None:
                    text = ''
                print(text.strip(), '|', end=' ', file=of)

            if not table and event == 'end':
                elem.clear()
    except ET.ParseError as e:
        print(e)
        os.remove(filename)
        exit(1)

    of.close()

'''
Extracts template table pages, asks wiktionary.org to render it to html
and then converts html to plaintext
'''
def extract_and_render(filename='ruwiktionary.xml', dest_dir='tables'):
    print('Parsing wiktionary dump for templates, be patient')
    template_names = extract_pages.extract('Шаблон:(прич|сущ|гл|мест|прил|числ) ru', filename)

    if not os.path.exists(dest_dir):
        os.makedirs(dest_dir)

    for template_name in template_names:
        params = {
            'action': 'render',
            'title': template_name
        }
        print('Rendering html for', template_name)
        r = requests.get('http://ru.wiktionary.org/w/index.php', params=params)

        if r.status_code == 200:
            render(template_name, r.text, dest_dir)
        else:
            print("Can't get", template_name, "template from wiktionary =\\")

if __name__ == '__main__':
    import argparse

    parser = argparse.ArgumentParser(description='Extracts and renders template tables from ruwiktionary in plain text')
    parser.add_argument('-f', '--filename', default='ruwiktionary.xml', help='wiktionary dump file')
    parser.add_argument('-d', '--dest-dir', default='tables', help='directory to extract tables into')
    args = parser.parse_args()

    extract_and_render(args.filename, args.dest_dir)


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cairo;
using Pinta.Core;

namespace Pinta.Tools
{
	//The EditEngine was created for tools that wish to utilize any of the control point, line/curve, hover point (reacting to the mouse),
	//and etc. code that was originally used in the LineCurveTool for editability. If a class wishes to use it, it should create and instantiate
	//a protected instance of the EditEngine inside the class and then utilize it in a similar fashion to any of the editable tools.
	public abstract class BaseEditEngine
	{
		public enum ShapeTypes
		{
			OpenLineCurveSeries,
			ClosedLineCurveSeries,
			Ellipse,
			RoundedLineSeries
		}

		public static Dictionary<ShapeTypes, ShapeTool> CorrespondingTools = new Dictionary<ShapeTypes, ShapeTool> ();

		protected abstract string ShapeName { get; }

		protected readonly ShapeTool owner;

		protected bool is_drawing = false;

		protected Rectangle? last_dirty = null;

		protected PointD shape_origin;
		protected PointD current_point;

		public static Color OutlineColor {
			get { return PintaCore.Palette.PrimaryColor; }
			set { PintaCore.Palette.PrimaryColor = value; }
		}

		public static Color FillColor {
			get { return PintaCore.Palette.SecondaryColor; }
			set { PintaCore.Palette.SecondaryColor = value; }
		}

		// NRT - Created by HandleBuildToolBar
		protected ToolBarWidget<Gtk.SpinButton> brush_width = null!;
		protected ToolBarLabel brush_width_label = null!;
		protected ToolBarLabel fill_label = null!;
		protected ToolBarDropDownButton fill_button = null!;
		protected Gtk.SeparatorToolItem fill_sep = null!;

		protected ToolBarLabel shape_type_label = null!;
		protected ToolBarDropDownButton shape_type_button = null!;
		protected Gtk.SeparatorToolItem shape_type_sep = null!;

		protected DashPatternBox dash_pattern_box = new DashPatternBox ();
		private string prev_dash_pattern = "-";

		private bool prev_antialiasing = true;

		public int BrushWidth {
			get => brush_width?.Widget.ValueAsInt ?? BaseTool.DEFAULT_BRUSH_WIDTH;
			set {
				if (brush_width is not null)
					brush_width.Widget.Value = value;
			}
		}

		private int prev_brush_width = BaseTool.DEFAULT_BRUSH_WIDTH;

		private bool StrokeShape {
			get {
				if (fill_button.SelectedItem?.Tag is int value)
					return value % 2 == 0;

				return true;
			}
		}

		private bool FillShape {
			get {
				if (fill_button.SelectedItem?.Tag is int value)
					return value >= 1;

				return false;
			}
		}

		private ShapeTypes ShapeType {
			get {
				if (shape_type_button.SelectedItem?.Tag is int value)
					return (ShapeTypes) value;

				return 0;
			}
		}

		public const double ShapeClickStartingRange = 10d;
		public const double DefaultEndPointTension = 0d;
		public const double DefaultMidPointTension = 1d / 3d;

		public int SelectedPointIndex, SelectedShapeIndex;
		protected int prev_selected_shape_index;

		/// <summary>
		/// The selected ControlPoint.
		/// </summary>
		public ControlPoint? SelectedPoint {
			get {
				ShapeEngine? selEngine = SelectedShapeEngine;

				if (selEngine != null && selEngine.ControlPoints.Count > SelectedPointIndex) {
					return selEngine.ControlPoints[SelectedPointIndex];
				} else {
					return null;
				}
			}
		}

		/// <summary>
		/// The active shape's ShapeEngine. A point does not have to be selected here, only a shape. This can be null.
		/// </summary>
		public ShapeEngine? ActiveShapeEngine {
			get {
				if (SelectedShapeIndex > -1 && SEngines.Count > SelectedShapeIndex) {
					return SEngines[SelectedShapeIndex];
				} else {
					return null;
				}
			}
		}

		/// <summary>
		/// The selected shape's ShapeEngine. This requires that a point in the shape be selected and should be used in most cases. This can be null.
		/// </summary>
		public ShapeEngine? SelectedShapeEngine {
			get {
				if (SelectedPointIndex > -1) {
					return ActiveShapeEngine;
				} else {
					return null;
				}
			}
		}

		/// <summary>
		/// Display the handles for all active shape engines' control points, along with the hover position
		/// </summary>
		public IEnumerable<IToolHandle> Handles =>
			SEngines.SelectMany (engine => engine.ControlPointHandles).Append (hover_handle);
		private MoveHandle hover_handle = new ();

		private readonly Gdk.Cursor grab_cursor = new (Gdk.Display.Default, Pinta.Resources.StandardCursors.Grab);
		private readonly Gdk.Cursor grabbing_cursor = new (Gdk.Display.Default, Pinta.Resources.StandardCursors.Grabbing);

		protected bool changing_tension = false;
		protected PointD last_mouse_pos = new PointD (0d, 0d);

		//Helps to keep track of the first modification on a shape after the mouse is clicked, to prevent unnecessary history items.
		protected bool clicked_without_modifying = false;

		//Stores the editable shape data.
		public static ShapeEngineCollection SEngines = new ShapeEngineCollection ();

		#region ToolbarEventHandlers

		protected virtual void BrushMinusButtonClickedEvent (object? o, EventArgs args)
		{
			if (BrushWidth > 1)
				BrushWidth--;

			//No need to store previous settings or redraw, as this is done in the Changed event handler.
		}

		protected virtual void BrushPlusButtonClickedEvent (object? o, EventArgs args)
		{
			BrushWidth++;

			//No need to store previous settings or redraw, as this is done in the Changed event handler.
		}

		protected void Palette_PrimaryColorChanged (object? sender, EventArgs e)
		{
			ShapeEngine? activeEngine = ActiveShapeEngine;

			if (activeEngine != null) {
				activeEngine.OutlineColor = OutlineColor.Clone ();

				DrawActiveShape (false, false, true, false, false);
			}
		}

		protected void Palette_SecondaryColorChanged (object? sender, EventArgs e)
		{
			ShapeEngine? activeEngine = ActiveShapeEngine;

			if (activeEngine != null) {
				activeEngine.FillColor = FillColor.Clone ();

				DrawActiveShape (false, false, true, false, false);
			}
		}

		private void OnFillStyleChanged (object? sender, EventArgs e)
		{
			DrawActiveShape (false, false, true, false, false);
		}

		#endregion ToolbarEventHandlers

		public BaseEditEngine (ShapeTool passedOwner)
		{
			owner = passedOwner;

			ResetShapes ();
		}

		private string BRUSH_WIDTH_SETTING (string prefix) => $"{prefix}-brush-width";
		private string FILL_TYPE_SETTING (string prefix) => $"{prefix}-fill-style";
		private string SHAPE_TYPE_SETTING (string prefix) => $"{prefix}-shape-type";
		private string DASH_PATTERN_SETTING (string prefix) => $"{prefix}-dash-pattern";

		public virtual void OnSaveSettings (ISettingsService settings, string toolPrefix)
		{
			if (brush_width is not null)
				settings.PutSetting (BRUSH_WIDTH_SETTING (toolPrefix), (int) brush_width.Widget.Value);
			if (fill_button is not null)
				settings.PutSetting (FILL_TYPE_SETTING (toolPrefix), fill_button.SelectedIndex);
			if (shape_type_button is not null)
				settings.PutSetting (SHAPE_TYPE_SETTING (toolPrefix), shape_type_button.SelectedIndex);
			if (dash_pattern_box?.comboBox is not null)
				settings.PutSetting (DASH_PATTERN_SETTING (toolPrefix), dash_pattern_box.comboBox.ComboBox.ActiveText);
		}

		public virtual void HandleBuildToolBar (Gtk.Toolbar tb, ISettingsService settings, string toolPrefix)
		{
			if (brush_width_label == null)
				brush_width_label = new ToolBarLabel (string.Format (" {0}: ", Translations.GetString ("Brush width")));

			tb.AppendItem (brush_width_label);

			if (brush_width == null) {
				brush_width = new (new Gtk.SpinButton (1, 1e5, 1) { Value = settings.GetSetting (BRUSH_WIDTH_SETTING (toolPrefix), BaseTool.DEFAULT_BRUSH_WIDTH) });

				brush_width.Widget.ValueChanged += (o, e) => {
					ShapeEngine? selEngine = SelectedShapeEngine;

					if (selEngine != null) {
						selEngine.BrushWidth = BrushWidth;
						StorePreviousSettings ();
						DrawActiveShape (false, false, true, false, false);
					}
				};
			}

			tb.AppendItem (brush_width);

			if (fill_sep == null)
				fill_sep = new Gtk.SeparatorToolItem ();

			tb.AppendItem (fill_sep);

			if (fill_label == null)
				fill_label = new ToolBarLabel (string.Format (" {0}: ", Translations.GetString ("Fill Style")));

			tb.AppendItem (fill_label);

			if (fill_button == null) {
				fill_button = new ToolBarDropDownButton ();

				fill_button.AddItem (Translations.GetString ("Outline Shape"), Resources.Icons.FillStyleOutline, 0);
				fill_button.AddItem (Translations.GetString ("Fill Shape"), Resources.Icons.FillStyleFill, 1);
				fill_button.AddItem (Translations.GetString ("Fill and Outline Shape"), Resources.Icons.FillStyleOutlineFill, 2);

				fill_button.SelectedIndex = settings.GetSetting (FILL_TYPE_SETTING (toolPrefix), 0);
				fill_button.SelectedItemChanged += OnFillStyleChanged;
			}

			tb.AppendItem (fill_button);

			if (shape_type_sep == null)
				shape_type_sep = new Gtk.SeparatorToolItem ();

			tb.AppendItem (shape_type_sep);

			if (shape_type_label == null)
				shape_type_label = new ToolBarLabel (string.Format (" {0}: ", Translations.GetString ("Shape Type")));

			tb.AppendItem (shape_type_label);

			if (shape_type_button == null) {
				shape_type_button = new ToolBarDropDownButton ();

				shape_type_button.AddItem (Translations.GetString ("Open Line/Curve Series"), Resources.Icons.ToolLine, 0);
				shape_type_button.AddItem (Translations.GetString ("Closed Line/Curve Series"), Resources.Icons.ToolRectangle, 1);
				shape_type_button.AddItem (Translations.GetString ("Ellipse"), Resources.Icons.ToolEllipse, 2);
				shape_type_button.AddItem (Translations.GetString ("Rounded Line Series"), Resources.Icons.ToolRectangleRounded, 3);

				shape_type_button.SelectedIndex = settings.GetSetting (SHAPE_TYPE_SETTING (toolPrefix), 0);

				shape_type_button.SelectedItemChanged += (o, e) => {
					ShapeTypes newShapeType = ShapeType;
					ShapeEngine? selEngine = SelectedShapeEngine;

					//Verify that the tool needs to be switched.
					if (GetCorrespondingTool (newShapeType) != this.owner) {
						//if shape is selected it will be converted to new shape and shape type will be changed, otherwise only shape type will be changed.
						if (selEngine != null) {
							//Create a new ShapesModifyHistoryItem so that the changing of the shape type can be undone.
							PintaCore.Workspace.ActiveDocument.History.PushNewItem (new ShapesModifyHistoryItem (
								this, owner.Icon, Translations.GetString ("Changed Shape Type")));

							//Clone the old shape; it should be automatically garbage-collected. newShapeType already has the updated value.
							selEngine = selEngine.Convert (newShapeType, SelectedShapeIndex);

							int previousSSI = SelectedShapeIndex;
							ActivateCorrespondingTool (selEngine.ShapeType, true);
							SelectedShapeIndex = previousSSI;
							//Draw the updated shape with organized points generation (for mouse detection).
							DrawActiveShape (true, false, true, false, true);
						} else {
							ActivateCorrespondingTool (newShapeType, true);
						}

					}
				};
			}

			shape_type_button.SelectedItem = shape_type_button.Items[(int) owner.ShapeType];

			tb.AppendItem (shape_type_button);

			Gtk.ComboBoxText? dpbBox = dash_pattern_box.SetupToolbar (tb);

			if (dpbBox != null) {
				dpbBox.Entry.Text = settings.GetSetting (DASH_PATTERN_SETTING (toolPrefix), "-");

				dpbBox.Changed += (o, e) => {
					ShapeEngine? selEngine = SelectedShapeEngine;

					if (selEngine != null) {
						selEngine.DashPattern = dpbBox.ActiveText;
						StorePreviousSettings ();
						DrawActiveShape (false, false, true, false, false);
					}
				};
			}
		}

		public virtual void HandleActivated ()
		{
			RecallPreviousSettings ();

			PintaCore.Palette.PrimaryColorChanged += new EventHandler (Palette_PrimaryColorChanged);
			PintaCore.Palette.SecondaryColorChanged += new EventHandler (Palette_SecondaryColorChanged);
		}

		public virtual void HandleDeactivated (BaseTool? newTool)
		{
			SelectedPointIndex = -1;
			SelectedShapeIndex = -1;

			StorePreviousSettings ();

			//Determine if the tool being switched to will be another editable tool.
			if (PintaCore.Workspace.HasOpenDocuments && !(newTool?.IsEditableShapeTool == true)) {
				//The tool being switched to is not editable. Finalize every editable shape not yet finalized.
				FinalizeAllShapes ();
			}

			PintaCore.Palette.PrimaryColorChanged -= Palette_PrimaryColorChanged;
			PintaCore.Palette.SecondaryColorChanged -= Palette_SecondaryColorChanged;
		}

		public virtual void HandleAfterSave ()
		{
			//When saving, everything will be finalized, which is good; however, afterwards, the user will expect
			//everything to remain editable. Currently, a finalization history item will always be added.
			PintaCore.Actions.Edit.Undo.Activate ();

			//Redraw all of the editable shapes in case saving caused some extra/unexpected behavior.
			DrawAllShapes ();
		}

		public virtual void HandleCommit ()
		{
			//Finalize every editable shape not yet finalized.
			FinalizeAllShapes ();
		}

		public virtual bool HandleBeforeUndo ()
		{
			return false;
		}

		public virtual bool HandleBeforeRedo ()
		{
			return false;
		}

		public virtual void HandleAfterUndo ()
		{
			ShapeEngine? activeEngine = ActiveShapeEngine;

			if (activeEngine != null) {
				UpdateToolbarSettings (activeEngine);
			}

			//Draw the current state.
			DrawActiveShape (true, false, true, false, false);
		}

		public virtual void HandleAfterRedo ()
		{
			ShapeEngine? activeEngine = ActiveShapeEngine;

			if (activeEngine != null) {
				UpdateToolbarSettings (activeEngine);
			}

			//Draw the current state.
			DrawActiveShape (true, false, true, false, false);
		}

		public virtual bool HandleKeyDown (Document document, ToolKeyEventArgs e)
		{
			Gdk.Key keyPressed = e.Key;

			if (keyPressed == Gdk.Key.Delete) {
				if (SelectedPointIndex > -1) {
					List<ControlPoint> controlPoints = SelectedShapeEngine!.ControlPoints; // NRT - Code assumes this is not-null

					//Either delete a ControlPoint or an entire shape (if there's only 1 ControlPoint left).
					if (controlPoints.Count > 1) {
						//Create a new ShapesModifyHistoryItem so that the deletion of a control point can be undone.
						PintaCore.Workspace.ActiveDocument.History.PushNewItem (
							new ShapesModifyHistoryItem (this, owner.Icon, ShapeName + " " + Translations.GetString ("Point Deleted")));

						//Delete the selected point from the shape.
						controlPoints.RemoveAt (SelectedPointIndex);

						//Set the newly selected point to be the median-most point on the shape, order-wise.
						if (SelectedPointIndex > controlPoints.Count / 2) {
							--SelectedPointIndex;
						}
					} else {
						Document doc = PintaCore.Workspace.ActiveDocument;

						//Create a new ShapesHistoryItem so that the deletion of a shape can be undone.
						doc.History.PushNewItem (
							new ShapesHistoryItem (this, owner.Icon, ShapeName + " " + Translations.GetString ("Deleted"),
								doc.Layers.CurrentUserLayer.Surface.Clone (), doc.Layers.CurrentUserLayer, SelectedPointIndex, SelectedShapeIndex, false));

						//Since the shape itself will be deleted, remove its ReEditableLayer from the drawing loop.

						ReEditableLayer removeMe = SEngines.ElementAt (SelectedShapeIndex).DrawingLayer;

						if (removeMe.InTheLoop) {
							SEngines.ElementAt (SelectedShapeIndex).DrawingLayer.TryRemoveLayer ();
						}

						//Delete the selected shape.
						SEngines.RemoveAt (SelectedShapeIndex);

						//Redraw the workspace.
						doc.Workspace.Invalidate ();

						SelectedPointIndex = -1;
						SelectedShapeIndex = -1;
					}

					DrawActiveShape (true, false, true, false, false);
				}

				return true;
			} else if (keyPressed == Gdk.Key.Return || keyPressed == Gdk.Key.KP_Enter) {
				//Finalize every editable shape not yet finalized.
				FinalizeAllShapes ();

				return true;
			} else if (keyPressed == Gdk.Key.space) {
				ControlPoint? selPoint = SelectedPoint;

				if (selPoint != null) {
					//This can be assumed not to be null since selPoint was not null.
					ShapeEngine selEngine = SelectedShapeEngine!; // NRT - ^^

					//Create a new ShapesModifyHistoryItem so that the adding of a control point can be undone.
					PintaCore.Workspace.ActiveDocument.History.PushNewItem (
								    new ShapesModifyHistoryItem (this, owner.Icon, ShapeName + " " + Translations.GetString ("Point Added")));

					bool shiftKey = e.IsShiftPressed;
					bool ctrlKey = e.IsControlPressed;

					PointD newPointPos;

					if (ctrlKey) {
						//Ctrl + space combo: same position as currently selected point.
						newPointPos = new PointD (selPoint.Position.X, selPoint.Position.Y);
					} else {
						shape_origin = new PointD (selPoint.Position.X, selPoint.Position.Y);

						if (shiftKey) {
							CalculateModifiedCurrentPoint ();
						}

						//Space only: position of mouse (after any potential shift alignment).
						newPointPos = new PointD (current_point.X, current_point.Y);
					}

					//Place the new point on the outside-most end, order-wise.
					if ((double) SelectedPointIndex < (double) selEngine.ControlPoints.Count / 2d) {
						selEngine.ControlPoints.Insert (SelectedPointIndex,
						    new ControlPoint (new PointD (newPointPos.X, newPointPos.Y), DefaultMidPointTension));
					} else {
						selEngine.ControlPoints.Insert (SelectedPointIndex + 1,
						    new ControlPoint (new PointD (newPointPos.X, newPointPos.Y), DefaultMidPointTension));

						++SelectedPointIndex;
					}

					DrawActiveShape (true, false, true, shiftKey, false);
				}

				return true;
			} else if (keyPressed == Gdk.Key.Up) {
				//Make sure a control point is selected.
				if (SelectedPointIndex > -1) {
					//Move the selected control point.
					SelectedPoint!.Position.Y -= 1d; // NRT - Checked by SelectedPointIndex

					DrawActiveShape (true, false, true, false, false);
				}

				return true;
			} else if (keyPressed == Gdk.Key.Down) {
				//Make sure a control point is selected.
				if (SelectedPointIndex > -1) {
					//Move the selected control point.
					SelectedPoint!.Position.Y += 1d; // NRT - Checked by SelectedPointIndex

					DrawActiveShape (true, false, true, false, false);
				}

				return true;
			} else if (keyPressed == Gdk.Key.Left) {
				//Make sure a control point is selected.
				if (SelectedPointIndex > -1) {
					if (e.IsControlPressed) {
						//Change the selected control point to be the previous one.

						--SelectedPointIndex;

						if (SelectedPointIndex < 0) {
							ShapeEngine? activeEngine = ActiveShapeEngine;

							if (activeEngine != null) {
								SelectedPointIndex = activeEngine.ControlPoints.Count - 1;
							}
						}
					} else {
						//Move the selected control point.
						SelectedPoint!.Position.X -= 1d; // NRT - Checked by SelectedPointIndex
					}

					DrawActiveShape (true, false, true, false, false);
				}

				return true;
			} else if (keyPressed == Gdk.Key.Right) {
				//Make sure a control point is selected.
				if (SelectedPointIndex > -1) {
					if (e.IsControlPressed) {
						//Change the selected control point to be the following one.

						ShapeEngine? activeEngine = ActiveShapeEngine;

						if (activeEngine != null) {
							++SelectedPointIndex;

							if (SelectedPointIndex > activeEngine.ControlPoints.Count - 1) {
								SelectedPointIndex = 0;
							}
						}
					} else {
						//Move the selected control point.
						SelectedPoint!.Position.X += 1d; // NRT - Checked by SelectedPointIndex
					}

					DrawActiveShape (true, false, true, false, false);
				}

				return true;
			} else {
				return false;
			}
		}

		public virtual bool HandleKeyUp (Document document, ToolKeyEventArgs e)
		{
			Gdk.Key keyReleased = e.Key;

			if (keyReleased == Gdk.Key.Delete || keyReleased == Gdk.Key.Return || keyReleased == Gdk.Key.KP_Enter
			    || keyReleased == Gdk.Key.space || keyReleased == Gdk.Key.Up || keyReleased == Gdk.Key.Down
			    || keyReleased == Gdk.Key.Left || keyReleased == Gdk.Key.Right) {
				return true;
			} else {
				return false;
			}
		}

		public virtual void HandleMouseDown (Document document, ToolMouseEventArgs e)
		{
			var point = e.PointDouble;

			//If we are already drawing, ignore any additional mouse down events.
			if (is_drawing) {
				return;
			}

			//Redraw the previously (and possibly currently) active shape without any control points in case another shape is made active.
			DrawActiveShape (false, false, false, false, false);

			Document doc = PintaCore.Workspace.ActiveDocument;

			shape_origin = new PointD (Utility.Clamp (point.X, 0, doc.ImageSize.Width - 1), Utility.Clamp (point.Y, 0, doc.ImageSize.Height - 1));
			current_point = shape_origin;

			bool shiftKey = e.IsShiftPressed;

			if (shiftKey) {
				CalculateModifiedCurrentPoint ();
			}

			is_drawing = true;

			//Right clicking changes tension.
			if (e.MouseButton == MouseButton.Left) {
				changing_tension = false;
			} else {
				changing_tension = true;
			}

			bool ctrlKey = e.IsControlPressed;

			int closestCPIndex, closestCPShapeIndex;
			ControlPoint? closestControlPoint;
			double closestCPDistance;

			SEngines.FindClosestControlPoint (current_point,
				out closestCPShapeIndex, out closestCPIndex, out closestControlPoint, out closestCPDistance);

			int closestShapeIndex, closestPointIndex;
			PointD closestPoint;
			double closestDistance;

			OrganizedPointCollection.FindClosestPoint (SEngines, current_point,
			    out closestShapeIndex, out closestPointIndex, out closestPoint, out closestDistance);

			bool clicked_control_point = false;
			bool clicked_generated_point = false;
			{
				var current_window_point = PintaCore.Workspace.CanvasPointToWindow (current_point);
				var test_handle = new MoveHandle ();

				// Check if the user is directly clicking on a control point.
				if (closestControlPoint != null) {
					test_handle.CanvasPosition = closestControlPoint.Position;
					clicked_control_point = test_handle.ContainsPoint (current_window_point);
					if (clicked_control_point) {
						SelectedPointIndex = closestCPIndex;
						SelectedShapeIndex = closestCPShapeIndex;
					}
				}

				// Otherwise, the user might have clicked on a generated point.
				if (!clicked_control_point) {
					test_handle.CanvasPosition = closestPoint;
					clicked_generated_point = test_handle.ContainsPoint (current_window_point);
				}
			}

			clicked_without_modifying = clicked_control_point;

			if (!changing_tension && clicked_generated_point) {
				//Determine if the currently active tool matches the clicked on shape's corresponding tool, and if not, switch to it.
				if (ActivateCorrespondingTool (closestShapeIndex, true) != null) {
					//Pass on the event and its data to the newly activated tool.
					PintaCore.Tools.DoMouseDown (document, e);

					//Don't do anything else here once the tool is switched and the event is passed on.
					return;
				}

				//The currently active tool matches the clicked on shape's corresponding tool.

				//Only create a new shape if the user isn't holding the control key down.
				if (!ctrlKey) {
					//Create a new ShapesModifyHistoryItem so that the adding of a control point can be undone.
					doc.History.PushNewItem (new ShapesModifyHistoryItem (this, owner.Icon, ShapeName + " " + Translations.GetString ("Point Added")));

					SEngines[closestShapeIndex].ControlPoints.Insert (closestPointIndex,
						new ControlPoint (new PointD (current_point.X, current_point.Y), DefaultMidPointTension));
				}

				//These should be set after creating the history item.
				SelectedPointIndex = closestPointIndex;
				SelectedShapeIndex = closestShapeIndex;

				ShapeEngine? activeEngine = ActiveShapeEngine;

				if (activeEngine != null) {
					UpdateToolbarSettings (activeEngine);
				}
			}

			//Create a new shape if the user control + clicks on a shape or if the user simply clicks outside of any shapes.
			if (!changing_tension && (ctrlKey || (!clicked_control_point && !clicked_generated_point))) {
				//Verify that the user clicked inside the image bounds or that the user is
				//holding the Ctrl key (to ignore the Image bounds and draw on the edge).
				if ((point.X == shape_origin.X && point.Y == shape_origin.Y) || ctrlKey) {
					PointD prevSelPoint;

					//First, store the position of the currently selected point.
					if (SelectedPoint != null && ctrlKey) {
						prevSelPoint = new PointD (SelectedPoint.Position.X, SelectedPoint.Position.Y);
					} else {
						//This doesn't matter, other than the fact that it gets set to a value in order for the code to build.
						prevSelPoint = new PointD (0d, 0d);
					}

					//Create a new ShapesHistoryItem so that the creation of a new shape can be undone.
					doc.History.PushNewItem (new ShapesHistoryItem (this, owner.Icon, ShapeName + " " + Translations.GetString ("Added"),
						doc.Layers.CurrentUserLayer.Surface.Clone (), doc.Layers.CurrentUserLayer, SelectedPointIndex, SelectedShapeIndex, false));

					//Create the shape, add its starting points, and add it to SEngines.
					SEngines.Add (CreateShape (ctrlKey, clicked_control_point, prevSelPoint));

					//Select the new shape.
					SelectedShapeIndex = SEngines.Count - 1;

					ShapeEngine? activeEngine = ActiveShapeEngine;

					if (activeEngine != null) {
						//Set the AntiAliasing.
						activeEngine.AntiAliasing = owner.UseAntialiasing;
					}

					StorePreviousSettings ();
				}
			} else if (clicked_control_point) {
				//Since the user is not creating a new shape or control point but rather modifying an existing control point, it should be determined
				//whether the currently active tool matches the clicked on shape's corresponding tool, and if not, switch to it.
				if (ActivateCorrespondingTool (SelectedShapeIndex, true) != null) {
					//Pass on the event and its data to the newly activated tool.
					PintaCore.Tools.DoMouseDown (document, e);

					//Don't do anything else here once the tool is switched and the event is passed on.
					return;
				}

				//The currently active tool matches the clicked on shape's corresponding tool.

				ShapeEngine? activeEngine = ActiveShapeEngine;

				if (activeEngine != null) {
					UpdateToolbarSettings (activeEngine);
				}
			}

			//Determine if the user right clicks outside of any shapes (neither on their control points nor on their generated points).
			if ((!clicked_control_point && !clicked_generated_point) && changing_tension) {
				clicked_without_modifying = true;
			}

			DrawActiveShape (false, false, true, shiftKey, false);
		}

		public virtual void HandleMouseUp (Document document, ToolMouseEventArgs e)
		{
			is_drawing = false;

			changing_tension = false;

			DrawActiveShape (true, false, true, e.IsShiftPressed, false);
		}

		public virtual void HandleMouseMove (Document document, ToolMouseEventArgs e)
		{
			Document doc = document;
			var point = e.PointDouble;

			current_point = new PointD (Utility.Clamp (point.X, 0, doc.ImageSize.Width - 1), Utility.Clamp (point.Y, 0, doc.ImageSize.Height - 1));

			bool shiftKey = e.IsShiftPressed;

			if (shiftKey) {
				CalculateModifiedCurrentPoint ();
			}

			if (!is_drawing) {
				//Redraw the active shape to show a (temporary) highlighted control point (over any shape) when applicable.
				DrawActiveShape (false, false, true, shiftKey, false);
			} else {
				ControlPoint? selPoint = SelectedPoint;

				//Make sure a control point is selected.
				if (selPoint != null) {
					if (clicked_without_modifying) {
						//Create a new ShapesModifyHistoryItem so that the modification of the shape can be undone.
						doc.History.PushNewItem (
										new ShapesModifyHistoryItem (this, owner.Icon, ShapeName + " " + Translations.GetString ("Modified")));

						clicked_without_modifying = false;
					}

					List<ControlPoint> controlPoints = SelectedShapeEngine!.ControlPoints; // NRT - Code assumes this is not-null

					if (!changing_tension) {
						//Moving a control point.

						//Make sure the control point was moved.
						if (current_point.X != selPoint.Position.X || current_point.Y != selPoint.Position.Y) {
							MovePoint (controlPoints);
						}
					} else {
						//Changing a control point's tension.

						//Unclamp the mouse position when changing tension.
						current_point = new PointD (point.X, point.Y);

						//Calculate the new tension based off of the movement of the mouse that's
						//perpendicular to the previous and following control points.

						PointD curPoint = selPoint.Position;
						PointD prevPoint, nextPoint;

						//Calculate the previous control point.
						if (SelectedPointIndex > 0) {
							prevPoint = controlPoints[SelectedPointIndex - 1].Position;
						} else {
							//There is none.
							prevPoint = curPoint;
						}

						//Calculate the following control point.
						if (SelectedPointIndex < controlPoints.Count - 1) {
							nextPoint = controlPoints[SelectedPointIndex + 1].Position;
						} else {
							//There is none.
							nextPoint = curPoint;
						}

						//The x and y differences are used as factors for the x and y change in the mouse position.
						double xDiff = prevPoint.X - nextPoint.X;
						double yDiff = prevPoint.Y - nextPoint.Y;
						double totalDiff = xDiff + yDiff;

						//Calculate the midpoint in between the previous and following points.
						PointD midPoint = new PointD ((prevPoint.X + nextPoint.X) / 2d, (prevPoint.Y + nextPoint.Y) / 2d);

						double xChange = 0d, yChange = 0d;

						//Calculate the x change in the mouse position.
						if (curPoint.X <= midPoint.X) {
							xChange = current_point.X - last_mouse_pos.X;
						} else {
							xChange = last_mouse_pos.X - current_point.X;
						}

						//Calculate the y change in the mouse position.
						if (curPoint.Y <= midPoint.Y) {
							yChange = current_point.Y - last_mouse_pos.Y;
						} else {
							yChange = last_mouse_pos.Y - current_point.Y;
						}

						//Update the control point's tension.

						//Note: the difference factors are to be inverted for x and y change because this is perpendicular motion.
						controlPoints[SelectedPointIndex].Tension +=
						    Math.Round (Utility.Clamp ((xChange * yDiff + yChange * xDiff) / totalDiff, -1d, 1d)) / 50d;

						//Restrict the new tension to range from 0d to 1d.
						controlPoints[SelectedPointIndex].Tension =
										Utility.Clamp (selPoint.Tension, 0d, 1d);
					}

					DrawActiveShape (false, false, true, shiftKey, false);
				}
			}

			last_mouse_pos = current_point;
		}

		/// <summary>
		/// Draw the currently active shape.
		/// </summary>
		/// <param name="calculateOrganizedPoints">Whether to calculate the spatially organized
		/// points for mouse detection after drawing the shape.</param>
		/// <param name="finalize">Whether to finalize the drawing.</param>
		/// <param name="drawHoverSelection">Whether to draw any hover point or selected point.</param>
		/// <param name="shiftKey">Whether the shift key is being pressed. This is for width/height constraining/equalizing.</param>
		/// <param name="preventSwitchBack">Whether to prevent switching back to the old tool if a tool change is necessary.</param>
		public void DrawActiveShape (bool calculateOrganizedPoints, bool finalize, bool drawHoverSelection, bool shiftKey, bool preventSwitchBack)
		{
			ShapeTool? oldTool = BaseEditEngine.ActivateCorrespondingTool (SelectedShapeIndex, calculateOrganizedPoints);

			//First, determine if the currently active tool matches the shape's corresponding tool, and if not, switch to it.
			if (oldTool != null) {
				//The tool has switched, so call DrawActiveShape again but inside that tool.
				if (PintaCore.Tools.CurrentTool is ShapeTool tool)
					tool.EditEngine.DrawActiveShape (
					calculateOrganizedPoints, finalize, drawHoverSelection, shiftKey, preventSwitchBack);

				//Afterwards, switch back to the old tool, unless specified otherwise.
				if (!preventSwitchBack) {
					ActivateCorrespondingTool (oldTool.ShapeType, true);
				}

				return;
			}

			//The currently active tool should now match the shape's corresponding tool.

			BeforeDraw ();

			ShapeEngine? activeEngine = ActiveShapeEngine;

			if (activeEngine == null) {
				//No shape will be drawn; however, the hover point still needs to be drawn if drawHoverSelection is true.
				UpdateHoverHandle (drawHoverSelection);
			} else {
				//Clear any temporary drawing, because something new will be drawn.
				activeEngine.DrawingLayer.Layer.Clear ();

				Rectangle dirty;

				//Determine if the drawing should be for finalizing the shape onto the image or drawing it temporarily.
				if (finalize) {
					dirty = DrawFinalized (activeEngine, true, shiftKey);
				} else {
					dirty = DrawUnfinalized (activeEngine, drawHoverSelection, shiftKey);
				}

				//Determine if the organized (spatially hashed) points should be generated. This is for mouse interaction detection after drawing.
				if (calculateOrganizedPoints) {
					OrganizePoints (activeEngine);
				}

				InvalidateAfterDraw (dirty);
			}
		}

		/// <summary>
		/// Do not call. Use DrawActiveShape.
		/// </summary>
		private void BeforeDraw ()
		{
			//Check to see if a new shape is selected.
			if (prev_selected_shape_index != SelectedShapeIndex) {
				//A new shape is selected, so clear the previous dirty Rectangle.
				last_dirty = null;

				prev_selected_shape_index = SelectedShapeIndex;
			}
		}

		/// <summary>
		/// Do not call. Use DrawActiveShape.
		/// </summary>
		/// <param name="engine"></param>
		/// <param name="dirty"></param>
		/// <param name="shiftKey"></param>
		private Rectangle DrawFinalized (ShapeEngine engine, bool createHistoryItem, bool shiftKey)
		{
			Document doc = PintaCore.Workspace.ActiveDocument;

			//Finalize the shape onto the CurrentUserLayer.

			ImageSurface? undoSurface = null;

			if (createHistoryItem) {
				//We only need to create a history item if there was a previous shape.
				if (engine.ControlPoints.Count > 0) {
					undoSurface = doc.Layers.CurrentUserLayer.Surface.Clone ();
				}
			}

			//Draw the finalized shape.
			Rectangle dirty = DrawShape (engine, doc.Layers.CurrentUserLayer, false, false);

			if (createHistoryItem) {
				//Make sure that the undo surface isn't null.
				if (undoSurface != null) {
					//Create a new ShapesHistoryItem so that the finalization of the shape can be undone.
					doc.History.PushNewItem (new ShapesHistoryItem (this, owner.Icon, ShapeName + " " + Translations.GetString ("Finalized"),
						undoSurface, doc.Layers.CurrentUserLayer, SelectedPointIndex, SelectedShapeIndex, false));
				}
			}

			return dirty;
		}

		/// <summary>
		/// Do not call. Use DrawActiveShape.
		/// </summary>
		/// <param name="engine"></param>
		/// <param name="dirty"></param>
		/// <param name="drawHoverSelection"></param>
		/// <param name="shiftKey"></param>
		private Rectangle DrawUnfinalized (ShapeEngine engine, bool drawHoverSelection, bool shiftKey)
		{
			//Draw the shape onto the temporary DrawingLayer.
			return DrawShape (engine, engine.DrawingLayer.Layer, true, drawHoverSelection);
		}

		/// <summary>
		/// Do not call. Use DrawActiveShape.
		/// </summary>
		/// <param name="engine"></param>
		private void OrganizePoints (ShapeEngine engine)
		{
			Document doc = PintaCore.Workspace.ActiveDocument;

			//Organize the generated points for quick mouse interaction detection.

			//First, clear the previously organized points, if any.
			engine.OrganizedPoints.ClearCollection ();

			foreach (GeneratedPoint gp in engine.GeneratedPoints) {
				//For each generated point on the shape, calculate the spatial hashing for it and then store this information for later usage.
				engine.OrganizedPoints.StoreAndOrganizePoint (new OrganizedPoint (new PointD (gp.Position.X, gp.Position.Y), gp.ControlPointIndex));
			}
		}

		private void InvalidateAfterDraw (Rectangle dirty)
		{
			Document doc = PintaCore.Workspace.ActiveDocument;

			// Increase the size of the dirty rect to account for antialiasing.
			if (owner.UseAntialiasing) {
				dirty = dirty.Inflate (1, 1);
			}

			//Combine, clamp, and invalidate the dirty Rectangle.
			if (((Rectangle?) dirty).UnionRectangles (last_dirty) is Rectangle r)
				dirty = r;

			dirty = dirty.Clamp ();
			doc.Workspace.Invalidate (dirty.ToGdkRectangle ());

			last_dirty = dirty;
		}

		protected Rectangle DrawShape (ShapeEngine engine, Layer l, bool drawCP, bool drawHoverSelection)
		{
			Document doc = PintaCore.Workspace.ActiveDocument;

			Rectangle? dirty = null;

			ShapeEngine? activeEngine = ActiveShapeEngine;

			if (activeEngine != null) {
				using (Context g = new Context (l.Surface)) {
					g.AppendPath (doc.Selection.SelectionPath);
					g.FillRule = FillRule.EvenOdd;
					g.Clip ();

					g.Antialias = activeEngine.AntiAliasing ? Antialias.Subpixel : Antialias.None;

					g.SetDash (DashPatternBox.GenerateDashArray (activeEngine.DashPattern, activeEngine.BrushWidth), 0.0);

					g.LineWidth = activeEngine.BrushWidth;

					//Draw the shape.
					if (activeEngine.ControlPoints.Count > 0) {
						//Generate the points that make up the shape.
						activeEngine.GeneratePoints (activeEngine.BrushWidth);

						PointD[] points = activeEngine.GetActualPoints ();

						//Expand the invalidation rectangle as necessary.

						if (FillShape) {
							Color fill_color = StrokeShape ? activeEngine.FillColor : activeEngine.OutlineColor;
							dirty = dirty.UnionRectangles (g.FillPolygonal (points, fill_color));
						}

						if (StrokeShape) {
							dirty = dirty.UnionRectangles (g.DrawPolygonal (points, activeEngine.OutlineColor));
						}
					}

					g.SetDash (new double[] { }, 0.0);

					//Draw anything extra (that not every shape has), like arrows.
					DrawExtras (ref dirty, g, engine);

					DrawControlPoints (g, activeEngine, drawCP, drawHoverSelection);
				}
			}

			return dirty ?? new Rectangle (0d, 0d, 0d, 0d);
		}

		private void DrawControlPoints (Context g, ShapeEngine shape, bool draw_controls, bool draw_selection)
		{
			Gdk.Rectangle dirty = MoveHandle.UnionInvalidateRects (shape.ControlPointHandles);
			shape.ControlPointHandles.Clear ();

			if (draw_controls) {
				UpdateHoverHandle (draw_selection);

				foreach (ControlPoint point in shape.ControlPoints) {
					//Skip drawing the control point if it is being hovered over.
					if (draw_selection && hover_handle.Active && hover_handle.CanvasPosition.Distance (point.Position) < 1d) {
						continue;
					}

					shape.ControlPointHandles.Add (new MoveHandle () {
						Active = true,
						CanvasPosition = point.Position,
						Selected = (point == SelectedPoint) && draw_selection
					});
				}

				dirty = dirty.Union (MoveHandle.UnionInvalidateRects (shape.ControlPointHandles));
			}

			PintaCore.Workspace.InvalidateWindowRect (dirty);
		}

		/// <summary>
		/// Update the hover handle's position and redraw it.
		/// </summary>
		protected void UpdateHoverHandle (bool draw_selection)
		{
			Gdk.Rectangle dirty = Gdk.Rectangle.Zero;
			if (hover_handle.Active)
				dirty = hover_handle.InvalidateRect;

			// Don't show the hover handle while the user is changing a control point's tension.
			hover_handle.Active = hover_handle.Selected = false;

			if (!changing_tension && draw_selection) {
				var current_window_point = PintaCore.Workspace.CanvasPointToWindow (current_point);

				int closestCPIndex, closestCPShapeIndex;
				ControlPoint? closestControlPoint;
				double closestCPDistance;
				SEngines.FindClosestControlPoint (current_point,
					out closestCPShapeIndex, out closestCPIndex, out closestControlPoint, out closestCPDistance);

				// Check if the user is directly hovering over a control point.
				if (closestControlPoint != null) {
					hover_handle.CanvasPosition = closestControlPoint.Position;
					hover_handle.Active = hover_handle.Selected = hover_handle.ContainsPoint (current_window_point);
				}

				// Otherwise, the user may be hovering over a generated point.
				if (!hover_handle.Active) {
					int closestShapeIndex, closestPointIndex;
					PointD closestPoint;
					double closestDistance;
					OrganizedPointCollection.FindClosestPoint (SEngines, current_point,
						out closestShapeIndex, out closestPointIndex, out closestPoint, out closestDistance);

					hover_handle.CanvasPosition = closestPoint;
					hover_handle.Active = hover_handle.ContainsPoint (current_window_point);
				}

				if (hover_handle.Active)
					dirty = dirty.Union (hover_handle.InvalidateRect);
			}

			// Update the tool's cursor if we are hovering over or dragging a control point.
			var tool = PintaCore.Tools.CurrentTool!;
			if (hover_handle.Selected)
				tool.SetCursor (is_drawing ? grabbing_cursor : grab_cursor);
			else
				tool.SetCursor (tool.DefaultCursor);

			PintaCore.Workspace.InvalidateWindowRect (dirty);
		}

		/// <summary>
		/// Go through every editable shape and draw it.
		/// </summary>
		public void DrawAllShapes ()
		{
			Document doc = PintaCore.Workspace.ActiveDocument;

			//Store the SelectedShapeIndex value for later restoration.
			int previousToolSI = SelectedShapeIndex;

			//Draw all of the shapes.
			for (SelectedShapeIndex = 0; SelectedShapeIndex < SEngines.Count; ++SelectedShapeIndex) {
				//Only draw the selected point for the selected shape.
				DrawActiveShape (true, false, previousToolSI == SelectedShapeIndex, false, true);
			}

			//Restore the previous SelectedShapeIndex value.
			SelectedShapeIndex = previousToolSI;

			//Determine if the currently active tool matches the shape's corresponding tool, and if not, switch to it.
			BaseEditEngine.ActivateCorrespondingTool (SelectedShapeIndex, false);

			//The currently active tool should now match the shape's corresponding tool.
		}

		/// <summary>
		/// Go through every editable shape not yet finalized and finalize it.
		/// </summary>
		protected void FinalizeAllShapes ()
		{
			if (SEngines.Count == 0)
				return;

			Document doc = PintaCore.Workspace.ActiveDocument;

			ImageSurface undoSurface = doc.Layers.CurrentUserLayer.Surface.Clone ();

			int previousSelectedPointIndex = SelectedPointIndex;

			Rectangle? dirty = null;

			//Finalize all of the shapes.
			for (SelectedShapeIndex = 0; SelectedShapeIndex < SEngines.Count; ++SelectedShapeIndex) {
				//Get a reference to each shape's corresponding tool.
				ShapeTool? correspondingTool = GetCorrespondingTool (SEngines[SelectedShapeIndex].ShapeType);

				if (correspondingTool != null) {
					//Finalize the now active shape using its corresponding tool's EditEngine.

					BaseEditEngine correspondingEngine = correspondingTool.EditEngine;

					correspondingEngine.SelectedShapeIndex = SelectedShapeIndex;

					correspondingEngine.BeforeDraw ();

					//Clear any temporary drawing, because something new will be drawn.
					SEngines[SelectedShapeIndex].DrawingLayer.Layer.Clear ();

					//Draw the current shape with the corresponding tool's EditEngine.
					dirty = dirty.UnionRectangles ((Rectangle?) correspondingEngine.DrawFinalized (
						SEngines[SelectedShapeIndex], false, false));
				}
			}

			//Make sure that the undo surface isn't null.
			if (undoSurface != null) {
				//Create a new ShapesHistoryItem so that the finalization of the shapes can be undone.
				doc.History.PushNewItem (new ShapesHistoryItem (this, owner.Icon, Translations.GetString ("Finalized"),
					undoSurface, doc.Layers.CurrentUserLayer, previousSelectedPointIndex, prev_selected_shape_index, true));
			}

			if (dirty.HasValue) {
				InvalidateAfterDraw (dirty.Value);
			}

			//Clear out all of the data.
			ResetShapes ();
		}

		/// <summary>
		/// Constrain the current point to snap to fixed angles from the previous point, or to
		/// produce a square / circle when drawing those shape types.
		/// </summary>
		protected void CalculateModifiedCurrentPoint ()
		{
			ShapeEngine? selEngine = SelectedShapeEngine;

			//Don't bother calculating a modified point if there is no selected shape.
			if (selEngine != null) {
				if (ShapeType != ShapeTypes.OpenLineCurveSeries && selEngine.ControlPoints.Count == 4) {
					// Constrain to a square / circle.
					var origin = selEngine.ControlPoints[(SelectedPointIndex + 2) % 4].Position;

					var dx = current_point.X - origin.X;
					var dy = current_point.Y - origin.Y;
					var length = Math.Max (Math.Abs (dx), Math.Abs (dy));
					dx = length * Math.Sign (dx);
					dy = length * Math.Sign (dy);
					current_point = new PointD (origin.X + dx, origin.Y + dy);
				} else {
					// Calculate the modified position of currentPoint such that the angle between the adjacent point
					// (if any) and currentPoint is snapped to the closest angle out of a certain number of angles.
					ControlPoint adjacentPoint;

					if (SelectedPointIndex > 0) {
						//Previous point.
						adjacentPoint = selEngine.ControlPoints[SelectedPointIndex - 1];
					} else if (selEngine.ControlPoints.Count > 1) {
						//Previous point (looping around to the end) if there is more than 1 point.
						adjacentPoint = selEngine.ControlPoints[selEngine.ControlPoints.Count - 1];
					} else {
						//Don't bother calculating a modified point because there is no reference point to align it with (there is only 1 point).
						return;
					}

					PointD dir = new PointD (current_point.X - adjacentPoint.Position.X, current_point.Y - adjacentPoint.Position.Y);
					double theta = Math.Atan2 (dir.Y, dir.X);
					double len = Math.Sqrt (dir.X * dir.X + dir.Y * dir.Y);

					theta = Math.Round (12 * theta / Math.PI) * Math.PI / 12;
					current_point = new PointD ((adjacentPoint.Position.X + len * Math.Cos (theta)), (adjacentPoint.Position.Y + len * Math.Sin (theta)));
				}
			}
		}

		/// <summary>
		/// Resets the editable data.
		/// </summary>
		protected void ResetShapes ()
		{
			SEngines = new ShapeEngineCollection ();

			//The fields are modified instead of the properties here because a redraw call is undesired (for speed/efficiency).
			SelectedPointIndex = -1;
			SelectedShapeIndex = -1;

			is_drawing = false;

			last_dirty = null;
		}

		/// <summary>
		/// Activates the corresponding tool to the given shapeIndex value if the tool is not already active, and then returns the previous tool
		/// if a tool switch has occurred or null otherwise. If a switch did occur and this was called in e.g. an event handler, it should most
		/// likely pass the event data on to the newly activated tool (accessing it using PintaCore.Tools.CurrentTool) and then return.
		/// </summary>
		/// <param name="shapeIndex">The index of the shape in SEngines to find the corresponding tool to and switch to.</param>
		/// <param name="permanentSwitch">Whether the tool switch is permanent or just temporary (for drawing).</param>
		/// <returns>The *previous* tool if a tool switch has occurred or null otherwise.</returns>
		public static ShapeTool? ActivateCorrespondingTool (int shapeIndex, bool permanentSwitch)
		{
			//First make sure that there is a validly selectable tool.
			if (shapeIndex > -1 && SEngines.Count > shapeIndex) {
				return ActivateCorrespondingTool (SEngines[shapeIndex].ShapeType, permanentSwitch);
			}

			//Let the caller know that the active tool has not been switched.
			return null;
		}

		/// <summary>
		/// Activates the corresponding tool to the given shapeType value if the tool is not already active, and then returns the previous tool
		/// if a tool switch has occurred or null otherwise. If a switch did occur and this was called in e.g. an event handler, it should most
		/// likely pass the event data on to the newly activated tool (accessing it using PintaCore.Tools.CurrentTool) and then return.
		/// </summary>
		/// <param name="shapeType">The index of the shape in SEngines to find the corresponding tool to and switch to.</param>
		/// <param name="permanentSwitch">Whether the tool switch is permanent or just temporary (for drawing).</param>
		/// <returns>The *previous* tool if a tool switch has occurred or null otherwise.</returns>
		public static ShapeTool? ActivateCorrespondingTool (ShapeTypes shapeType, bool permanentSwitch)
		{
			ShapeTool? correspondingTool = GetCorrespondingTool (shapeType);

			//Verify that the corresponding tool is valid and that it doesn't match the currently active tool.
			if (correspondingTool != null && PintaCore.Tools.CurrentTool != correspondingTool) {
				ShapeTool? oldTool = PintaCore.Tools.CurrentTool as ShapeTool;

				int oldToolSPI = -1;
				int oldToolSSI = -1;
				//SetCurrentTool sets oldTool's SelectedPointIndex and SelectedShapeIndex to -1 so their value has to be saved before this happens.
				if (oldTool != null && oldTool.IsEditableShapeTool && permanentSwitch) {
					oldToolSPI = oldTool.EditEngine.SelectedPointIndex;
					oldToolSSI = oldTool.EditEngine.SelectedShapeIndex;
				}

				//The active tool needs to be switched to the corresponding tool.
				PintaCore.Tools.SetCurrentTool (correspondingTool);
				var newTool = (ShapeTool?) PintaCore.Tools.CurrentTool;

				// This shouldn't be possible, but we need a null check.
				if (newTool is null)
					return null;

				//What happens next depends on whether the old tool was an editable ShapeTool.
				if (oldTool != null && oldTool.IsEditableShapeTool) {
					if (permanentSwitch) {
						//Set the new tool's active shape and point to the old shape and point.
						newTool.EditEngine.SelectedPointIndex = oldToolSPI;
						newTool.EditEngine.SelectedShapeIndex = oldToolSSI;

						//Make sure neither tool thinks it is drawing anything.
						newTool.EditEngine.is_drawing = false;
						oldTool.EditEngine.is_drawing = false;
					}

					ShapeEngine? activeEngine = newTool.EditEngine.ActiveShapeEngine;

					if (activeEngine != null) {
						newTool.EditEngine.UpdateToolbarSettings (activeEngine);
					}
				} else {
					if (permanentSwitch) {
						//Make sure that the new tool doesn't think it is drawing anything.
						newTool.EditEngine.is_drawing = false;
					}
				}

				//Let the caller know that the active tool has been switched.
				return oldTool;
			}

			//Let the caller know that the active tool has not been switched.
			return null;
		}

		/// <summary>
		/// Gets the corresponding tool to the given shape type and then returns that tool.
		/// </summary>
		/// <param name="ShapeType">The shape type to find the corresponding tool to.</param>
		/// <returns>The corresponding tool to the given shape type.</returns>
		public static ShapeTool? GetCorrespondingTool (ShapeTypes shapeType)
		{
			ShapeTool? correspondingTool = null;

			//Get the corresponding BaseTool reference to the shape type.
			CorrespondingTools.TryGetValue (shapeType, out correspondingTool);

			return correspondingTool;
		}

		/// <summary>
		/// Copy the given shape's settings to the toolbar settings. Calls StorePreviousSettings.
		/// </summary>
		/// <param name="engine"></param>
		public virtual void UpdateToolbarSettings (ShapeEngine engine)
		{
			if (engine != null) {
				owner.UseAntialiasing = engine.AntiAliasing;

				//Update the DashPatternBox to represent the current shape's DashPattern.
				dash_pattern_box.comboBox!.ComboBox.Entry.Text = engine.DashPattern; // NRT - Code assumes this is not-null

				OutlineColor = engine.OutlineColor.Clone ();
				FillColor = engine.FillColor.Clone ();

				BrushWidth = engine.BrushWidth;

				StorePreviousSettings ();
			}
		}

		/// <summary>
		/// Copy the previous settings to the toolbar settings.
		/// </summary>
		protected virtual void RecallPreviousSettings ()
		{
			if (dash_pattern_box.comboBox != null) {
				dash_pattern_box.comboBox.ComboBox.Entry.Text = prev_dash_pattern;
			}

			owner.UseAntialiasing = prev_antialiasing;
			BrushWidth = prev_brush_width;
		}

		/// <summary>
		/// Copy the toolbar settings to the previous settings.
		/// </summary>
		protected virtual void StorePreviousSettings ()
		{
			if (dash_pattern_box.comboBox != null) {
				prev_dash_pattern = dash_pattern_box.comboBox.ComboBox.Entry.Text;
			}

			prev_antialiasing = owner.UseAntialiasing;
			prev_brush_width = BrushWidth;
		}

		/// <summary>
		/// Creates a new shape, adds its starting points, and returns it.
		/// </summary>
		/// <param name="ctrlKey"></param>
		/// <param name="clickedOnControlPoint"></param>
		/// <param name="prevSelPoint"></param>
		protected abstract ShapeEngine CreateShape (bool ctrlKey, bool clickedOnControlPoint, PointD prevSelPoint);

		protected virtual void MovePoint (List<ControlPoint> controlPoints)
		{
			//Update the control point's position.
			controlPoints.ElementAt (SelectedPointIndex).Position = new PointD (current_point.X, current_point.Y);
		}

		protected virtual void DrawExtras (ref Rectangle? dirty, Context g, ShapeEngine engine)
		{

		}

		protected void AddLinePoints (bool ctrlKey, bool clickedOnControlPoint, ShapeEngine selEngine, PointD prevSelPoint)
		{
			PointD startingPoint;

			//Create the initial points of the shape. The second point will follow the mouse around until released.
			if (ctrlKey && clickedOnControlPoint) {
				startingPoint = prevSelPoint;

				clicked_without_modifying = false;
			} else {
				startingPoint = shape_origin;
			}

			selEngine.ControlPoints.Add (new ControlPoint (new PointD (startingPoint.X, startingPoint.Y), DefaultEndPointTension));
			selEngine.ControlPoints.Add (
				new ControlPoint (new PointD (startingPoint.X + .01d, startingPoint.Y + .01d), DefaultEndPointTension));

			SelectedPointIndex = 1;
			SelectedShapeIndex = SEngines.Count - 1;
		}

		protected void AddRectanglePoints (bool ctrlKey, bool clickedOnControlPoint, ShapeEngine selEngine, PointD prevSelPoint)
		{
			PointD startingPoint;

			//Create the initial points of the shape. The second point will follow the mouse around until released.
			if (ctrlKey && clickedOnControlPoint) {
				startingPoint = prevSelPoint;

				clicked_without_modifying = false;
			} else {
				startingPoint = shape_origin;
			}

			selEngine.ControlPoints.Add (new ControlPoint (new PointD (startingPoint.X, startingPoint.Y), 0.0));
			selEngine.ControlPoints.Add (
				new ControlPoint (new PointD (startingPoint.X, startingPoint.Y + .01d), 0.0));
			selEngine.ControlPoints.Add (
				new ControlPoint (new PointD (startingPoint.X + .01d, startingPoint.Y + .01d), 0.0));
			selEngine.ControlPoints.Add (
				new ControlPoint (new PointD (startingPoint.X + .01d, startingPoint.Y), 0.0));

			SelectedPointIndex = 2;
			SelectedShapeIndex = SEngines.Count - 1;
		}

		protected void MoveRectangularPoint (List<ControlPoint> controlPoints)
		{
			ShapeEngine? selEngine = SelectedShapeEngine;

			if (selEngine != null && selEngine.Closed && controlPoints.Count == 4) {
				//Figure out the indeces of the surrounding points. The lowest point index should be 0 and the highest 3.

				int previousPointIndex = SelectedPointIndex - 1;
				int nextPointIndex = SelectedPointIndex + 1;
				int oppositePointIndex = SelectedPointIndex + 2;

				if (previousPointIndex < 0) {
					previousPointIndex = controlPoints.Count - 1;
				}

				if (nextPointIndex >= controlPoints.Count) {
					nextPointIndex = 0;
					oppositePointIndex = 1;
				} else if (oppositePointIndex >= controlPoints.Count) {
					oppositePointIndex = 0;
				}

				ControlPoint previousPoint = controlPoints.ElementAt (previousPointIndex);
				ControlPoint oppositePoint = controlPoints.ElementAt (oppositePointIndex);
				ControlPoint nextPoint = controlPoints.ElementAt (nextPointIndex);

				//Now that we know the indexed order of the points, we can align everything properly.
				if (SelectedPointIndex == 2 || SelectedPointIndex == 0) {
					//Control point visual order (counter-clockwise order always goes selectedPoint, previousPoint, oppositePoint, nextPoint,
					//where moving point == selectedPoint):
					//
					//static (opposite) point		horizontally aligned point
					//vertically aligned point		moving point
					//OR
					//moving point					vertically aligned point
					//horizontally aligned point	static (opposite) point

					//Update the previous control point's position.
					previousPoint.Position = new PointD (previousPoint.Position.X, current_point.Y);

					//Update the next control point's position.
					nextPoint.Position = new PointD (current_point.X, nextPoint.Position.Y);

					//Even though it's supposed to be static, just in case the points get out of order
					//(they do sometimes), update the opposite control point's position.
					oppositePoint.Position = new PointD (previousPoint.Position.X, nextPoint.Position.Y);
				} else {
					//Control point visual order (counter-clockwise order always goes selectedPoint, previousPoint, oppositePoint, nextPoint,
					//where moving point == selectedPoint):
					//
					//horizontally aligned point	static (opposite) point
					//moving point					vertically aligned point
					//OR
					//vertically aligned point		moving point
					//static (opposite) point		horizontally aligned point

					//Update the previous control point's position.
					previousPoint.Position = new PointD (current_point.X, previousPoint.Position.Y);

					//Update the next control point's position.
					nextPoint.Position = new PointD (nextPoint.Position.X, current_point.Y);

					//Even though it's supposed to be static, just in case the points get out of order
					//(they do sometimes), update the opposite control point's position.
					oppositePoint.Position = new PointD (nextPoint.Position.X, previousPoint.Position.Y);
				}
			}
		}
	}
}


text:
SYNONYM

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
O. Beccari & J. D. Hooker, Fl. Brit. India 6:427. 1892

#### Original name
null

### Remarks
null