text:
package org.gnucash.android.ui.report.linechart;

import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.utils.LargeValueFormatter;

import org.gnucash.android.R;
import org.gnucash.android.db.adapter.AccountsDbAdapter;
import org.gnucash.android.db.adapter.TransactionsDbAdapter;
import org.gnucash.android.model.Account;
import org.gnucash.android.model.AccountType;
import org.gnucash.android.ui.report.BaseReportFragment;
import org.gnucash.android.ui.report.ReportType;
import org.gnucash.android.ui.report.ReportsActivity.GroupInterval;
import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import butterknife.BindView;

/**
 * Fragment for line chart reports
 *
 * @author Oleksandr Tyshkovets <olexandr.tyshkovets@gmail.com>
 * @author Ngewi Fet <ngewif@gmail.com>
 */
public class CashFlowLineChartFragment extends BaseReportFragment {

    private static final String X_AXIS_PATTERN = "MMM YY";
    private static final int ANIMATION_DURATION = 3000;
    private static final int NO_DATA_BAR_COUNTS = 5;
    private static final int[] COLORS = {
            Color.parseColor("#68F1AF"), Color.parseColor("#cc1f09"), Color.parseColor("#EE8600"),
            Color.parseColor("#1469EB"), Color.parseColor("#B304AD"),
    };
    private static final int[] FILL_COLORS = {
            Color.parseColor("#008000"), Color.parseColor("#FF0000"), Color.parseColor("#BE6B00"),
            Color.parseColor("#0065FF"), Color.parseColor("#8F038A"),
    };

    private AccountsDbAdapter mAccountsDbAdapter = AccountsDbAdapter.getInstance();
    private Map<AccountType, Long> mEarliestTimestampsMap = new HashMap<>();
    private Map<AccountType, Long> mLatestTimestampsMap = new HashMap<>();
    private long mEarliestTransactionTimestamp;
    private long mLatestTransactionTimestamp;
    private boolean mChartDataPresent = true;

    @BindView(R.id.line_chart) LineChart mChart;

    @Override
    public int getLayoutResource() {
        return R.layout.fragment_line_chart;
    }

    @Override
    public int getTitle() {
        return R.string.title_cash_flow_report;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        mChart.setOnChartValueSelectedListener(this);
        mChart.setDescription("");
        mChart.getXAxis().setDrawGridLines(false);
        mChart.getAxisRight().setEnabled(false);
        mChart.getAxisLeft().enableGridDashedLine(4.0f, 4.0f, 0);
        mChart.getAxisLeft().setValueFormatter(new LargeValueFormatter(mCommodity.getSymbol()));

        Legend legend = mChart.getLegend();
        legend.setPosition(Legend.LegendPosition.BELOW_CHART_CENTER);
        legend.setTextSize(16);
        legend.setForm(Legend.LegendForm.CIRCLE);

    }

    @Override
    public ReportType getReportType() {
        return ReportType.LINE_CHART;
    }

    /**
     * Returns a data object that represents a user data of the specified account types
     * @param accountTypeList account's types which will be displayed
     * @return a {@code LineData} instance that represents a user data
     */
    private LineData getData(List<AccountType> accountTypeList) {
        Log.w(TAG, "getData");
        calculateEarliestAndLatestTimestamps(accountTypeList);
        // LocalDateTime?
        LocalDate startDate;
        LocalDate endDate;
        if (mReportPeriodStart == -1 && mReportPeriodEnd == -1) {
            startDate = new LocalDate(mEarliestTransactionTimestamp).withDayOfMonth(1);
            endDate = new LocalDate(mLatestTransactionTimestamp).withDayOfMonth(1);
        } else {
            startDate = new LocalDate(mReportPeriodStart).withDayOfMonth(1);
            endDate = new LocalDate(mReportPeriodEnd).withDayOfMonth(1);
        }

        int count = getDateDiff(new LocalDateTime(startDate.toDate().getTime()), new LocalDateTime(endDate.toDate().getTime()));
        Log.d(TAG, "X-axis count" + count);
        List<String> xValues = new ArrayList<>();
        for (int i = 0; i <= count; i++) {
            switch (mGroupInterval) {
                case MONTH:
                    xValues.add(startDate.toString(X_AXIS_PATTERN));
                    Log.d(TAG, "X-axis " + startDate.toString("MM yy"));
                    startDate = startDate.plusMonths(1);
                    break;
                case QUARTER:
                    int quarter = getQuarter(new LocalDateTime(startDate.toDate().getTime()));
                    xValues.add("Q" + quarter + startDate.toString(" yy"));
                    Log.d(TAG, "X-axis " + "Q" + quarter + startDate.toString(" MM yy"));
                    startDate = startDate.plusMonths(3);
                    break;
                case YEAR:
                    xValues.add(startDate.toString("yyyy"));
                    Log.d(TAG, "X-axis " + startDate.toString("yyyy"));
                    startDate = startDate.plusYears(1);
                    break;
//                default:
            }
        }

        List<LineDataSet> dataSets = new ArrayList<>();
        for (AccountType accountType : accountTypeList) {
            LineDataSet set = new LineDataSet(getEntryList(accountType), accountType.toString());
            set.setDrawFilled(true);
            set.setLineWidth(2);
            set.setColor(COLORS[dataSets.size()]);
            set.setFillColor(FILL_COLORS[dataSets.size()]);

            dataSets.add(set);
        }

        LineData lineData = new LineData(xValues, dataSets);
        if (lineData.getYValueSum() == 0) {
            mChartDataPresent = false;
            return getEmptyData();
        }
        return lineData;
    }

    /**
     * Returns a data object that represents situation when no user data available
     * @return a {@code LineData} instance for situation when no user data available
     */
    private LineData getEmptyData() {
        List<String> xValues = new ArrayList<>();
        List<Entry> yValues = new ArrayList<>();
        for (int i = 0; i < NO_DATA_BAR_COUNTS; i++) {
            xValues.add("");
            yValues.add(new Entry(i % 2 == 0 ? 5f : 4.5f, i));
        }
        LineDataSet set = new LineDataSet(yValues, getResources().getString(R.string.label_chart_no_data));
        set.setDrawFilled(true);
        set.setDrawValues(false);
        set.setColor(NO_DATA_COLOR);
        set.setFillColor(NO_DATA_COLOR);

        return new LineData(xValues, Collections.singletonList(set));
    }

    /**
     * Returns entries which represent a user data of the specified account type
     * @param accountType account's type which user data will be processed
     * @return entries which represent a user data
     */
    private List<Entry> getEntryList(AccountType accountType) {
        List<String> accountUIDList = new ArrayList<>();
        for (Account account : mAccountsDbAdapter.getSimpleAccountList()) {
            if (account.getAccountType() == accountType
                    && !account.isPlaceholderAccount()
                    && account.getCommodity().equals(mCommodity)) {
                accountUIDList.add(account.getUID());
            }
        }

        LocalDateTime earliest;
        LocalDateTime latest;
        if (mReportPeriodStart == -1 && mReportPeriodEnd == -1) {
            earliest = new LocalDateTime(mEarliestTimestampsMap.get(accountType));
            latest = new LocalDateTime(mLatestTimestampsMap.get(accountType));
        } else {
            earliest = new LocalDateTime(mReportPeriodStart);
            latest = new LocalDateTime(mReportPeriodEnd);
        }
        Log.d(TAG, "Earliest " + accountType + " date " + earliest.toString("dd MM yyyy"));
        Log.d(TAG, "Latest " + accountType + " date " + latest.toString("dd MM yyyy"));

        int xAxisOffset = getDateDiff(new LocalDateTime(mEarliestTransactionTimestamp), earliest);
        int count = getDateDiff(earliest, latest);
        List<Entry> values = new ArrayList<>(count + 1);
        for (int i = 0; i <= count; i++) {
            long start = 0;
            long end = 0;
            switch (mGroupInterval) {
                case QUARTER:
                    int quarter = getQuarter(earliest);
                    start = earliest.withMonthOfYear(quarter * 3 - 2).dayOfMonth().withMinimumValue().millisOfDay().withMinimumValue().toDate().getTime();
                    end = earliest.withMonthOfYear(quarter * 3).dayOfMonth().withMaximumValue().millisOfDay().withMaximumValue().toDate().getTime();

                    earliest = earliest.plusMonths(3);
                    break;
                case MONTH:
                    start = earliest.dayOfMonth().withMinimumValue().millisOfDay().withMinimumValue().toDate().getTime();
                    end = earliest.dayOfMonth().withMaximumValue().millisOfDay().withMaximumValue().toDate().getTime();

                    earliest = earliest.plusMonths(1);
                    break;
                case YEAR:
                    start = earliest.dayOfYear().withMinimumValue().millisOfDay().withMinimumValue().toDate().getTime();
                    end = earliest.dayOfYear().withMaximumValue().millisOfDay().withMaximumValue().toDate().getTime();

                    earliest = earliest.plusYears(1);
                    break;
            }
            float balance = (float) mAccountsDbAdapter.getAccountsBalance(accountUIDList, start, end).asDouble();
            values.add(new Entry(balance, i + xAxisOffset));
            Log.d(TAG, accountType + earliest.toString(" MMM yyyy") + ", balance = " + balance);

        }

        return values;
    }

    /**
     * Calculates the earliest and latest transaction's timestamps of the specified account types
     * @param accountTypeList account's types which will be processed
     */
    private void calculateEarliestAndLatestTimestamps(List<AccountType> accountTypeList) {
        if (mReportPeriodStart != -1 && mReportPeriodEnd != -1) {
            mEarliestTransactionTimestamp = mReportPeriodStart;
            mLatestTransactionTimestamp = mReportPeriodEnd;
            return;
        }

        TransactionsDbAdapter dbAdapter = TransactionsDbAdapter.getInstance();
        for (Iterator<AccountType> iter = accountTypeList.iterator(); iter.hasNext();) {
            AccountType type = iter.next();
            long earliest = dbAdapter.getTimestampOfEarliestTransaction(type, mCommodity.getCurrencyCode());
            long latest = dbAdapter.getTimestampOfLatestTransaction(type, mCommodity.getCurrencyCode());
            if (earliest > 0 && latest > 0) {
                mEarliestTimestampsMap.put(type, earliest);
                mLatestTimestampsMap.put(type, latest);
            } else {
                iter.remove();
            }
        }

        if (mEarliestTimestampsMap.isEmpty() || mLatestTimestampsMap.isEmpty()) {
            return;
        }

        List<Long> timestamps = new ArrayList<>(mEarliestTimestampsMap.values());
        timestamps.addAll(mLatestTimestampsMap.values());
        Collections.sort(timestamps);
        mEarliestTransactionTimestamp = timestamps.get(0);
        mLatestTransactionTimestamp = timestamps.get(timestamps.size() - 1);
    }

    @Override
    public boolean requiresAccountTypeOptions() {
        return false;
    }

    @Override
    protected void generateReport() {
        LineData lineData = getData(new ArrayList<>(Arrays.asList(AccountType.INCOME, AccountType.EXPENSE)));
        if (lineData != null) {
            mChart.setData(lineData);
            mChartDataPresent = true;
        } else {
            mChartDataPresent = false;
        }
    }

    @Override
    protected void displayReport() {
        if (!mChartDataPresent) {
            mChart.getAxisLeft().setAxisMaxValue(10);
            mChart.getAxisLeft().setDrawLabels(false);
            mChart.getXAxis().setDrawLabels(false);
            mChart.setTouchEnabled(false);
            mSelectedValueTextView.setText(getResources().getString(R.string.label_chart_no_data));
        } else {
            mChart.animateX(ANIMATION_DURATION);
        }
        mChart.invalidate();
    }

    @Override
    public void onTimeRangeUpdated(long start, long end) {
        if (mReportPeriodStart != start || mReportPeriodEnd != end) {
            mReportPeriodStart = start;
            mReportPeriodEnd = end;
            mChart.setData(getData(new ArrayList<>(Arrays.asList(AccountType.INCOME, AccountType.EXPENSE))));
            mChart.invalidate();
        }
    }

    @Override
    public void onGroupingUpdated(GroupInterval groupInterval) {
        if (mGroupInterval != groupInterval) {
            mGroupInterval = groupInterval;
            mChart.setData(getData(new ArrayList<>(Arrays.asList(AccountType.INCOME, AccountType.EXPENSE))));
            mChart.invalidate();
        }
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        menu.findItem(R.id.menu_toggle_average_lines).setVisible(mChartDataPresent);
        // hide pie/bar chart specific menu items
        menu.findItem(R.id.menu_order_by_size).setVisible(false);
        menu.findItem(R.id.menu_toggle_labels).setVisible(false);
        menu.findItem(R.id.menu_percentage_mode).setVisible(false);
        menu.findItem(R.id.menu_group_other_slice).setVisible(false);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.isCheckable())
            item.setChecked(!item.isChecked());
        switch (item.getItemId()) {
            case R.id.menu_toggle_legend:
                mChart.getLegend().setEnabled(!mChart.getLegend().isEnabled());
                mChart.invalidate();
                return true;

            case R.id.menu_toggle_average_lines:
                if (mChart.getAxisLeft().getLimitLines().isEmpty()) {
                    for (LineDataSet set : mChart.getData().getDataSets()) {
                        LimitLine line = new LimitLine(set.getYValueSum() / set.getEntryCount(), set.getLabel());
                        line.enableDashedLine(10, 5, 0);
                        line.setLineColor(set.getColor());
                        mChart.getAxisLeft().addLimitLine(line);
                    }
                } else {
                    mChart.getAxisLeft().removeAllLimitLines();
                }
                mChart.invalidate();
                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onValueSelected(Entry e, int dataSetIndex, Highlight h) {
        if (e == null) return;
        String label = mChart.getData().getXVals().get(e.getXIndex());
        double value = e.getVal();
        double sum = mChart.getData().getDataSetByIndex(dataSetIndex).getYValueSum();
        mSelectedValueTextView.setText(String.format(SELECTED_VALUE_PATTERN, label, value, value / sum * 100));
    }

}


text:
using System;
using java = biz.ritter.javapi;

namespace biz.ritter.javapi.awt
{
    /**
     * @author Michael Danilov
     */

    public interface LayoutManager2 : LayoutManager
    {

        void addLayoutComponent(Component comp, Object constraints);

        float getLayoutAlignmentX(Container target);

        float getLayoutAlignmentY(Container target);

        void invalidateLayout(Container target);

        Dimension maximumLayoutSize(Container target);
    }

}

redpajama_set_name: RedPajamaGithub


text:
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Dapper;
using Dapper.Contrib.Extensions;
using GoldenEye.Dapper.Generators;
using GoldenEye.Dapper.Mappings;
using GoldenEye.Events;
using GoldenEye.Events.Aggregate;
using GoldenEye.Extensions.Basic;
using GoldenEye.Objects.General;
using GoldenEye.Repositories;

namespace GoldenEye.Dapper.Repositories;

public class DapperRepository<TEntity>: IRepository<TEntity>
    where TEntity : class, IHaveId
{
    private readonly IDapperSqlGenerator dapperSqlGenerator;
    private readonly IDbConnection dbConnection;
    private readonly IAggregateEventsPublisher aggregateEventsPublisher;

    public DapperRepository(IDbConnection dbConnection, IAggregateEventsPublisher aggregateEventsPublisher, IDapperSqlGenerator dapperSqlGenerator = null)
    {
        this.dbConnection = dbConnection ?? throw new ArgumentNullException(nameof(dbConnection));
        this.aggregateEventsPublisher = aggregateEventsPublisher;
        this.dapperSqlGenerator = dapperSqlGenerator;
    }

    public async Task<TEntity> FindById(object id, CancellationToken cancellationToken = default)
    {
        if (id == null)
            throw new ArgumentNullException(nameof(id), "Id needs to have value");

        var sql = dapperSqlGenerator?.FindById<TEntity>(id);

        if (!sql.IsNullOrEmpty())
            return (await dbConnection.QuerySingleOrDefaultAsync<TEntity>(sql, new {Id = id}));

        return await dbConnection.GetAsync<TEntity>(id);
    }

    public IQueryable<TEntity> Query()
    {
        var sql = dapperSqlGenerator?.Query<TEntity>();

        return !sql.IsNullOrEmpty()
            ? dbConnection.Query<TEntity>(sql).AsQueryable()
            : dbConnection.GetAll<TEntity>().AsQueryable();
    }

    public async Task<IReadOnlyCollection<TEntity>> RawQuery(string query,
        CancellationToken cancellationToken, params object[] queryParams)
    {
        if (query == null)
            throw new ArgumentNullException(nameof(query));

        if (queryParams == null)
            throw new ArgumentNullException(nameof(queryParams));

        return (await dbConnection.QueryAsync<TEntity>(query, queryParams.First())).ToList();
    }

    public async Task<TEntity> Add(TEntity entity, CancellationToken cancellationToken = default)
    {
        if (entity == null)
            throw new ArgumentNullException(nameof(entity));

        var sql = dapperSqlGenerator?.Add(entity);

        if (!sql.IsNullOrEmpty())
            await dbConnection.ExecuteAsync(sql, entity);
        else
            await dbConnection.InsertAsync(entity);

        aggregateEventsPublisher.TryEnqueueEventsFrom(entity, out _);

        return entity;
    }

    public async Task<TEntity> Update(TEntity entity, int? expectedVersion, CancellationToken cancellationToken = default)
    {
        if(expectedVersion.HasValue)
            throw new NotImplementedException();

        if (entity == null)
            throw new ArgumentNullException(nameof(entity));

        var sql = dapperSqlGenerator?.Update(entity);

        if (!sql.IsNullOrEmpty())
            await dbConnection.ExecuteAsync(sql, entity);
        else
            await dbConnection.UpdateAsync(entity);

        aggregateEventsPublisher.TryEnqueueEventsFrom(entity, out _);

        return entity;
    }

    public async Task<TEntity> Delete(TEntity entity, int? expectedVersion, CancellationToken cancellationToken = default)
    {
        if(expectedVersion.HasValue)
            throw new NotImplementedException();

        if (entity == null)
            throw new ArgumentNullException(nameof(entity));

        var sql = dapperSqlGenerator?.Delete(entity);

        if (!sql.IsNullOrEmpty())
            await dbConnection.ExecuteAsync(sql, entity);
        else
            await dbConnection.DeleteAsync(entity);

        aggregateEventsPublisher.TryEnqueueEventsFrom(entity, out _);

        return entity;
    }

    public async Task<bool> DeleteById(object id, int? expectedVersion, CancellationToken cancellationToken = default)
    {
        if(expectedVersion.HasValue)
            throw new NotImplementedException();

        if (id == null)
            throw new ArgumentNullException(nameof(id));

        var sql = dapperSqlGenerator?.Delete(id);

        if (!sql.IsNullOrEmpty())
            await dbConnection.ExecuteAsync(sql, id);
        else
            throw new NotImplementedException($"{nameof(DeleteById)} by convention is not supported - please provide sql script through {nameof(IDapperMapping)}");

        return true;
    }

    public Task SaveChanges(CancellationToken cancellationToken = default)
    {
        return aggregateEventsPublisher.Publish(cancellationToken);
    }
}


text:
Package.describe({
    name: "my-meteor-accounts-admin-ui-bootstrap-3",
    summary: "A roles based account management system using bootstrap 3",
    version: "0.2.7"
});

Package.on_use(function(api, where) {
    api.versionsFrom("METEOR@0.9.0");
    api.use('standard-app-packages', ['client', 'server']);
    api.use("alanning:roles@1.2.8", ['client', 'server']);

    api.add_files('libs/user_query.js', ['client', 'server']);

    api.add_files('client/startup.js', 'client');
    api.add_files('client/accounts_admin.html', 'client');
    api.add_files('client/accounts_admin.js', 'client');
    api.add_files('client/delete_account_modal.html', 'client');
    api.add_files('client/delete_account_modal.js', 'client');
    api.add_files('client/info_account_modal.html', 'client');
    api.add_files('client/info_account_modal.js', 'client');
    api.add_files('client/update_account_modal.html', 'client');
    api.add_files('client/update_account_modal.js', 'client');
    api.add_files('client/update_roles_modal.html', 'client');
    api.add_files('client/update_roles_modal.js', 'client');

    api.add_files('style/style.css', 'client');

    api.add_files('server/startup.js', 'server');
    api.add_files('server/publish.js', 'server');
    api.add_files('server/methods.js', 'server');
});


text: <?php require("quote.php"); ?>


text:
title: Extensões da Grid
---

**AJAX/HTML**
```php
array(
	'modalId' => 'dadosEmails',
	'class' => 'fidelize.grid.FModalColumn',
	'name' => 'emails',
	'iconClass' => 'icon-comment opacity50',
	'value' => '"Ver"',
	'tooltipText' => 'Ver endereços de e-mail',
	'modalTitle' => '\'Emails de \' . $data->nome',
	'modalAjaxContent' => 'Yii::app()->createUrl(\'medico/emails\', array(\'id\' => $data->medico->id, \'endereco\' => $data->id))',
	'htmlOptions' => array('style' => 'width: 50px; text-align: center;'),
),
```

**AJAX/JSON (uma função JS se encarrega de criar o HTML nesse caso)**
```php
array(
	'modalId' => 'historicoProcesso',
	'header' => Yii::t('Processo','Histórico do Processo'),
	'class' => 'fidelize.grid.FModalColumn',
	'iconClass' => 'icon-comment opacity50',
	'value' => '"Detalhar"',
	'modalTitle' => '\'Histórico do processo nº \' . $data->numero_sinistro',
	'tooltipText' => 'Ver histórico do Processo',
	'modalAjaxContent' => 'Yii::app()->createUrl("processo/historico", array("id" => $data->id))',
	'modalFunctionToProcessContent' => 'processaItensHistorico',
	'htmlOptions' => array('style' => 'width: 100px; text-align: center;'),
	'requestIsJSON' => true,
),
```


text:
using System;
using System.Collections.Generic;
using Moq;
using NUnit.Framework;
using XenAdmin.Alerts;
using XenAdmin.Core;
using XenAdmin.Network;
using XenAdminTests.UnitTests.UnitTestHelper;
using XenAPI;

namespace XenAdminTests.UnitTests.AlertTests
{
    [TestFixture, Category(TestCategories.Unit)]
    public class XenServerUpdateAlertTests
    {
        private Mock<IXenConnection> connA;
        private Mock<IXenConnection> connB;
        private Mock<Host> hostA;
        private Mock<Host> hostB;

        protected Cache cacheA;
        protected Cache cacheB;

        [Test]
        public void TestAlertWithConnectionAndHosts()
        {
            XenServerVersion ver = new XenServerVersion("1.2.3", "name", true, "http://url", new List<XenServerPatch>(), new List<XenServerPatch>(), new DateTime(2011, 4, 1).ToString(), "123");
            var alert = new XenServerVersionAlert(ver);
            alert.IncludeConnection(connA.Object);
            alert.IncludeConnection(connB.Object);
            alert.IncludeHosts(new List<Host>() { hostA.Object, hostB.Object });

            IUnitTestVerifier validator = new VerifyGetters(alert);

            validator.Verify(new AlertClassUnitTestData
            {
                AppliesTo = "HostAName, HostBName, ConnAName, ConnBName",
                FixLinkText = "Go to Web Page",
                HelpID = "XenServerUpdateAlert",
                Description = "name is now available. Download the latest at the " + XenAdmin.Branding.COMPANY_NAME_SHORT + " website.",
                HelpLinkText = "Help",
                Title = "name is now available",
                Priority = "Priority5"
            });

            Assert.IsFalse(alert.CanIgnore);

            VerifyConnExpectations(Times.Once);
            VerifyHostsExpectations(Times.Once);
        }

        [Test]
        public void TestAlertWithHostsAndNoConnection()
        {
            XenServerVersion ver = new XenServerVersion("1.2.3", "name", true, "http://url", new List<XenServerPatch>(), new List<XenServerPatch>(), new DateTime(2011, 4, 1).ToString(), "123");
            var alert = new XenServerVersionAlert(ver);
            alert.IncludeHosts(new List<Host> { hostA.Object, hostB.Object });

            IUnitTestVerifier validator = new VerifyGetters(alert);

            validator.Verify(new AlertClassUnitTestData
            {
                AppliesTo = "HostAName, HostBName",
                FixLinkText = "Go to Web Page",
                HelpID = "XenServerUpdateAlert",
                Description = "name is now available. Download the latest at the " + XenAdmin.Branding.COMPANY_NAME_SHORT + " website.",
                HelpLinkText = "Help",
                Title = "name is now available",
                Priority = "Priority5"
            });

            Assert.IsFalse(alert.CanIgnore);

            VerifyConnExpectations(Times.Never);
            VerifyHostsExpectations(Times.Once);
        }

        [Test]
        public void TestAlertWithConnectionAndNoHosts()
        {
            XenServerVersion ver = new XenServerVersion("1.2.3", "name", true, "http://url", new List<XenServerPatch>(), new List<XenServerPatch>(), new DateTime(2011, 4, 1).ToString(), "123");
            var alert = new XenServerVersionAlert(ver);
            alert.IncludeConnection(connA.Object);
            alert.IncludeConnection(connB.Object);

            IUnitTestVerifier validator = new VerifyGetters(alert);

            validator.Verify(new AlertClassUnitTestData
            {
                AppliesTo = "ConnAName, ConnBName",
                FixLinkText = "Go to Web Page",
                HelpID = "XenServerUpdateAlert",
                Description = "name is now available. Download the latest at the " + XenAdmin.Branding.COMPANY_NAME_SHORT + " website.",
                HelpLinkText = "Help",
                Title = "name is now available",
                Priority = "Priority5"
            });

            Assert.IsFalse(alert.CanIgnore);

            VerifyConnExpectations(Times.Once);
            VerifyHostsExpectations(Times.Never);
        }

        [Test]
        public void TestAlertWithNoConnectionAndNoHosts()
        {
            XenServerVersion ver = new XenServerVersion("1.2.3", "name", true, "http://url", new List<XenServerPatch>(), new List<XenServerPatch>(), new DateTime(2011, 4, 1).ToString(), "123");
            var alert = new XenServerVersionAlert(ver);

            IUnitTestVerifier validator = new VerifyGetters(alert);

            validator.Verify(new AlertClassUnitTestData
            {
                AppliesTo = string.Empty,
                FixLinkText = "Go to Web Page",
                HelpID = "XenServerUpdateAlert",
                Description = "name is now available. Download the latest at the " + XenAdmin.Branding.COMPANY_NAME_SHORT + " website.",
                HelpLinkText = "Help",
                Title = "name is now available",
                Priority = "Priority5"
            });

            Assert.IsTrue(alert.CanIgnore);

            VerifyConnExpectations(Times.Never);
            VerifyHostsExpectations(Times.Never);
        }

        [Test, ExpectedException(typeof(NullReferenceException))]
        public void TestAlertWithNullVersion()
        {
            var alert = new XenServerVersionAlert(null);
        }

        private void VerifyConnExpectations(Func<Times> times)
        {
            connA.VerifyGet(n => n.Name, times());
            connB.VerifyGet(n => n.Name, times());
        }

        private void VerifyHostsExpectations(Func<Times> times)
        {
            hostA.VerifyGet(n => n.Name, times());
            hostB.VerifyGet(n => n.Name, times());
        }

        [SetUp]
        public void TestSetUp()
        {
            connA = new Mock<IXenConnection>(MockBehavior.Strict);
            connA.Setup(n => n.Name).Returns("ConnAName");
            cacheA = new Cache();
            connA.Setup(x => x.Cache).Returns(cacheA);

            connB = new Mock<IXenConnection>(MockBehavior.Strict);
            connB.Setup(n => n.Name).Returns("ConnBName");
            cacheB = new Cache();
            connB.Setup(x => x.Cache).Returns(cacheB);

            hostA = new Mock<Host>(MockBehavior.Strict);
            hostA.Setup(n => n.Name).Returns("HostAName");
            hostA.Setup(n => n.Equals(It.IsAny<object>())).Returns((object o) => ReferenceEquals(o, hostA.Object));

            hostB = new Mock<Host>(MockBehavior.Strict);
            hostB.Setup(n => n.Name).Returns("HostBName");
            hostB.Setup(n => n.Equals(It.IsAny<object>())).Returns((object o) => ReferenceEquals(o, hostB.Object));
        }

        [TearDown]
        public void TestTearDown()
        {
            cacheA = null;
            cacheB = null;
            connA = null;
            connB = null;
            hostA = null;
            hostB = null;
        }
    }
}