text:
namespace Microsoft.Azure.Management.Automation
{
    using Microsoft.Rest;
    using Microsoft.Rest.Azure;
    using Microsoft.Rest.Azure.OData;
    using Models;
    using System.Threading;
    using System.Threading.Tasks;

    /// <summary>
    /// Extension methods for JobScheduleOperations.
    /// </summary>
    public static partial class JobScheduleOperationsExtensions
    {
            /// <summary>
            /// Delete the job schedule identified by job schedule name.
            /// <see href="http://aka.ms/azureautomationsdk/jobscheduleoperations" />
            /// </summary>
            /// <param name='operations'>
            /// The operations group for this extension method.
            /// </param>
            /// <param name='resourceGroupName'>
            /// Name of an Azure Resource group.
            /// </param>
            /// <param name='automationAccountName'>
            /// The name of the automation account.
            /// </param>
            /// <param name='jobScheduleId'>
            /// The job schedule name.
            /// </param>
            public static void Delete(this IJobScheduleOperations operations, string resourceGroupName, string automationAccountName, System.Guid jobScheduleId)
            {
                operations.DeleteAsync(resourceGroupName, automationAccountName, jobScheduleId).GetAwaiter().GetResult();
            }

            /// <summary>
            /// Delete the job schedule identified by job schedule name.
            /// <see href="http://aka.ms/azureautomationsdk/jobscheduleoperations" />
            /// </summary>
            /// <param name='operations'>
            /// The operations group for this extension method.
            /// </param>
            /// <param name='resourceGroupName'>
            /// Name of an Azure Resource group.
            /// </param>
            /// <param name='automationAccountName'>
            /// The name of the automation account.
            /// </param>
            /// <param name='jobScheduleId'>
            /// The job schedule name.
            /// </param>
            /// <param name='cancellationToken'>
            /// The cancellation token.
            /// </param>
            public static async Task DeleteAsync(this IJobScheduleOperations operations, string resourceGroupName, string automationAccountName, System.Guid jobScheduleId, CancellationToken cancellationToken = default(CancellationToken))
            {
                (await operations.DeleteWithHttpMessagesAsync(resourceGroupName, automationAccountName, jobScheduleId, null, cancellationToken).ConfigureAwait(false)).Dispose();
            }

            /// <summary>
            /// Retrieve the job schedule identified by job schedule name.
            /// <see href="http://aka.ms/azureautomationsdk/jobscheduleoperations" />
            /// </summary>
            /// <param name='operations'>
            /// The operations group for this extension method.
            /// </param>
            /// <param name='resourceGroupName'>
            /// Name of an Azure Resource group.
            /// </param>
            /// <param name='automationAccountName'>
            /// The name of the automation account.
            /// </param>
            /// <param name='jobScheduleId'>
            /// The job schedule name.
            /// </param>
            public static JobSchedule Get(this IJobScheduleOperations operations, string resourceGroupName, string automationAccountName, System.Guid jobScheduleId)
            {
                return operations.GetAsync(resourceGroupName, automationAccountName, jobScheduleId).GetAwaiter().GetResult();
            }

            /// <summary>
            /// Retrieve the job schedule identified by job schedule name.
            /// <see href="http://aka.ms/azureautomationsdk/jobscheduleoperations" />
            /// </summary>
            /// <param name='operations'>
            /// The operations group for this extension method.
            /// </param>
            /// <param name='resourceGroupName'>
            /// Name of an Azure Resource group.
            /// </param>
            /// <param name='automationAccountName'>
            /// The name of the automation account.
            /// </param>
            /// <param name='jobScheduleId'>
            /// The job schedule name.
            /// </param>
            /// <param name='cancellationToken'>
            /// The cancellation token.
            /// </param>
            public static async Task<JobSchedule> GetAsync(this IJobScheduleOperations operations, string resourceGroupName, string automationAccountName, System.Guid jobScheduleId, CancellationToken cancellationToken = default(CancellationToken))
            {
                using (var _result = await operations.GetWithHttpMessagesAsync(resourceGroupName, automationAccountName, jobScheduleId, null, cancellationToken).ConfigureAwait(false))
                {
                    return _result.Body;
                }
            }

            /// <summary>
            /// Create a job schedule.
            /// <see href="http://aka.ms/azureautomationsdk/jobscheduleoperations" />
            /// </summary>
            /// <param name='operations'>
            /// The operations group for this extension method.
            /// </param>
            /// <param name='resourceGroupName'>
            /// Name of an Azure Resource group.
            /// </param>
            /// <param name='automationAccountName'>
            /// The name of the automation account.
            /// </param>
            /// <param name='jobScheduleId'>
            /// The job schedule name.
            /// </param>
            /// <param name='parameters'>
            /// The parameters supplied to the create job schedule operation.
            /// </param>
            public static JobSchedule Create(this IJobScheduleOperations operations, string resourceGroupName, string automationAccountName, System.Guid jobScheduleId, JobScheduleCreateParameters parameters)
            {
                return operations.CreateAsync(resourceGroupName, automationAccountName, jobScheduleId, parameters).GetAwaiter().GetResult();
            }

            /// <summary>
            /// Create a job schedule.
            /// <see href="http://aka.ms/azureautomationsdk/jobscheduleoperations" />
            /// </summary>
            /// <param name='operations'>
            /// The operations group for this extension method.
            /// </param>
            /// <param name='resourceGroupName'>
            /// Name of an Azure Resource group.
            /// </param>
            /// <param name='automationAccountName'>
            /// The name of the automation account.
            /// </param>
            /// <param name='jobScheduleId'>
            /// The job schedule name.
            /// </param>
            /// <param name='parameters'>
            /// The parameters supplied to the create job schedule operation.
            /// </param>
            /// <param name='cancellationToken'>
            /// The cancellation token.
            /// </param>
            public static async Task<JobSchedule> CreateAsync(this IJobScheduleOperations operations, string resourceGroupName, string automationAccountName, System.Guid jobScheduleId, JobScheduleCreateParameters parameters, CancellationToken cancellationToken = default(CancellationToken))
            {
                using (var _result = await operations.CreateWithHttpMessagesAsync(resourceGroupName, automationAccountName, jobScheduleId, parameters, null, cancellationToken).ConfigureAwait(false))
                {
                    return _result.Body;
                }
            }

            /// <summary>
            /// Retrieve a list of job schedules.
            /// <see href="http://aka.ms/azureautomationsdk/jobscheduleoperations" />
            /// </summary>
            /// <param name='operations'>
            /// The operations group for this extension method.
            /// </param>
            /// <param name='resourceGroupName'>
            /// Name of an Azure Resource group.
            /// </param>
            /// <param name='automationAccountName'>
            /// The name of the automation account.
            /// </param>
            /// <param name='odataQuery'>
            /// OData parameters to apply to the operation.
            /// </param>
            public static IPage<JobSchedule> ListByAutomationAccount(this IJobScheduleOperations operations, string resourceGroupName, string automationAccountName, ODataQuery<JobSchedule> odataQuery = default(ODataQuery<JobSchedule>))
            {
                return operations.ListByAutomationAccountAsync(resourceGroupName, automationAccountName, odataQuery).GetAwaiter().GetResult();
            }

            /// <summary>
            /// Retrieve a list of job schedules.
            /// <see href="http://aka.ms/azureautomationsdk/jobscheduleoperations" />
            /// </summary>
            /// <param name='operations'>
            /// The operations group for this extension method.
            /// </param>
            /// <param name='resourceGroupName'>
            /// Name of an Azure Resource group.
            /// </param>
            /// <param name='automationAccountName'>
            /// The name of the automation account.
            /// </param>
            /// <param name='odataQuery'>
            /// OData parameters to apply to the operation.
            /// </param>
            /// <param name='cancellationToken'>
            /// The cancellation token.
            /// </param>
            public static async Task<IPage<JobSchedule>> ListByAutomationAccountAsync(this IJobScheduleOperations operations, string resourceGroupName, string automationAccountName, ODataQuery<JobSchedule> odataQuery = default(ODataQuery<JobSchedule>), CancellationToken cancellationToken = default(CancellationToken))
            {
                using (var _result = await operations.ListByAutomationAccountWithHttpMessagesAsync(resourceGroupName, automationAccountName, odataQuery, null, cancellationToken).ConfigureAwait(false))
                {
                    return _result.Body;
                }
            }

            /// <summary>
            /// Retrieve a list of job schedules.
            /// <see href="http://aka.ms/azureautomationsdk/jobscheduleoperations" />
            /// </summary>
            /// <param name='operations'>
            /// The operations group for this extension method.
            /// </param>
            /// <param name='nextPageLink'>
            /// The NextLink from the previous successful call to List operation.
            /// </param>
            public static IPage<JobSchedule> ListByAutomationAccountNext(this IJobScheduleOperations operations, string nextPageLink)
            {
                return operations.ListByAutomationAccountNextAsync(nextPageLink).GetAwaiter().GetResult();
            }

            /// <summary>
            /// Retrieve a list of job schedules.
            /// <see href="http://aka.ms/azureautomationsdk/jobscheduleoperations" />
            /// </summary>
            /// <param name='operations'>
            /// The operations group for this extension method.
            /// </param>
            /// <param name='nextPageLink'>
            /// The NextLink from the previous successful call to List operation.
            /// </param>
            /// <param name='cancellationToken'>
            /// The cancellation token.
            /// </param>
            public static async Task<IPage<JobSchedule>> ListByAutomationAccountNextAsync(this IJobScheduleOperations operations, string nextPageLink, CancellationToken cancellationToken = default(CancellationToken))
            {
                using (var _result = await operations.ListByAutomationAccountNextWithHttpMessagesAsync(nextPageLink, null, cancellationToken).ConfigureAwait(false))
                {
                    return _result.Body;
                }
            }

    }
}


text:
namespace client {

namespace {

const char kPromptTextId[] = "cef_prompt_text";

// If there's a text entry in the dialog, get the text from the first one and
// return it.
std::string GetPromptText(GtkDialog* dialog) {
  GtkWidget* widget = static_cast<GtkWidget*>(
      g_object_get_data(G_OBJECT(dialog), kPromptTextId));
  if (widget)
    return gtk_entry_get_text(GTK_ENTRY(widget));
  return std::string();
}

std::string GetDescriptionFromMimeType(const std::string& mime_type) {
  // Check for wild card mime types and return an appropriate description.
  static const struct {
    const char* mime_type;
    const char* label;
  } kWildCardMimeTypes[] = {
    { "audio", "Audio Files" },
    { "image", "Image Files" },
    { "text", "Text Files" },
    { "video", "Video Files" },
  };

  for (size_t i = 0;
       i < sizeof(kWildCardMimeTypes) / sizeof(kWildCardMimeTypes[0]); ++i) {
    if (mime_type == std::string(kWildCardMimeTypes[i].mime_type) + "/*")
      return std::string(kWildCardMimeTypes[i].label);
  }

  return std::string();
}

void AddFilters(GtkFileChooser* chooser,
                const std::vector<CefString>& accept_filters,
                bool include_all_files,
                std::vector<GtkFileFilter*>* filters) {
  bool has_filter = false;

  for (size_t i = 0; i < accept_filters.size(); ++i) {
    const std::string& filter = accept_filters[i];
    if (filter.empty())
      continue;

    std::vector<std::string> extensions;
    std::string description;

    size_t sep_index = filter.find('|');
    if (sep_index != std::string::npos) {
      // Treat as a filter of the form "Filter Name|.ext1;.ext2;.ext3".
      description = filter.substr(0, sep_index);

      const std::string& exts = filter.substr(sep_index + 1);
      size_t last = 0;
      size_t size = exts.size();
      for (size_t i = 0; i <= size; ++i) {
        if (i == size || exts[i] == ';') {
          std::string ext(exts, last, i - last);
          if (!ext.empty() && ext[0] == '.')
            extensions.push_back(ext);
          last = i + 1;
        }
      }
    } else if (filter[0] == '.') {
      // Treat as an extension beginning with the '.' character.
      extensions.push_back(filter);
    } else {
      // Otherwise convert mime type to one or more extensions.
      description = GetDescriptionFromMimeType(filter);

      std::vector<CefString> ext;
      CefGetExtensionsForMimeType(filter, ext);
      for (size_t x = 0; x < ext.size(); ++x)
        extensions.push_back("." + ext[x].ToString());
    }

    if (extensions.empty())
      continue;

    GtkFileFilter* gtk_filter = gtk_file_filter_new();

    std::string ext_str;
    for (size_t x = 0; x < extensions.size(); ++x) {
      const std::string& pattern = "*" + extensions[x];
      if (x != 0)
        ext_str += ";";
      ext_str += pattern;
      gtk_file_filter_add_pattern(gtk_filter, pattern.c_str());
    }

    if (description.empty())
      description = ext_str;
    else
      description += " (" + ext_str + ")";

    gtk_file_filter_set_name(gtk_filter, description.c_str());
    gtk_file_chooser_add_filter(chooser, gtk_filter);
    if (!has_filter)
      has_filter = true;

    filters->push_back(gtk_filter);
  }

  // Add the *.* filter, but only if we have added other filters (otherwise it
  // is implied).
  if (include_all_files && has_filter) {
    GtkFileFilter* filter = gtk_file_filter_new();
    gtk_file_filter_add_pattern(filter, "*");
    gtk_file_filter_set_name(filter, "All Files (*)");
    gtk_file_chooser_add_filter(chooser, filter);
  }
}

GtkWindow* GetWindow(CefRefPtr<CefBrowser> browser) {
  scoped_refptr<RootWindow> root_window =
      RootWindow::GetForBrowser(browser->GetIdentifier());
  if (root_window) {
    GtkWindow* window = GTK_WINDOW(root_window->GetWindowHandle());
    if (!window)
      LOG(ERROR) << "No GtkWindow for browser";
    return window;
  }
  return NULL;
}

}  // namespace

ClientDialogHandlerGtk::ClientDialogHandlerGtk()
    : gtk_dialog_(NULL) {
}

bool ClientDialogHandlerGtk::OnFileDialog(
    CefRefPtr<CefBrowser> browser,
    FileDialogMode mode,
    const CefString& title,
    const CefString& default_file_path,
    const std::vector<CefString>& accept_filters,
    int selected_accept_filter,
    CefRefPtr<CefFileDialogCallback> callback) {
  std::vector<CefString> files;

  GtkFileChooserAction action;
  const gchar* accept_button;

  // Remove any modifier flags.
  FileDialogMode mode_type =
     static_cast<FileDialogMode>(mode & FILE_DIALOG_TYPE_MASK);

  if (mode_type == FILE_DIALOG_OPEN || mode_type == FILE_DIALOG_OPEN_MULTIPLE) {
    action = GTK_FILE_CHOOSER_ACTION_OPEN;
    accept_button = GTK_STOCK_OPEN;
  } else if (mode_type == FILE_DIALOG_OPEN_FOLDER) {
    action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
    accept_button = GTK_STOCK_OPEN;
  } else if (mode_type == FILE_DIALOG_SAVE) {
    action = GTK_FILE_CHOOSER_ACTION_SAVE;
    accept_button = GTK_STOCK_SAVE;
  } else {
    NOTREACHED();
    return false;
  }

  std::string title_str;
  if (!title.empty()) {
    title_str = title;
  } else {
    switch (mode_type) {
      case FILE_DIALOG_OPEN:
        title_str = "Open File";
        break;
      case FILE_DIALOG_OPEN_MULTIPLE:
        title_str = "Open Files";
        break;
      case FILE_DIALOG_OPEN_FOLDER:
        title_str = "Open Folder";
        break;
      case FILE_DIALOG_SAVE:
        title_str = "Save File";
        break;
      default:
        break;
    }
  }

  GtkWindow* window = GetWindow(browser);
  if (!window)
    return false;

  GtkWidget* dialog = gtk_file_chooser_dialog_new(
      title_str.c_str(),
      GTK_WINDOW(window),
      action,
      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
      accept_button, GTK_RESPONSE_ACCEPT,
      NULL);

  if (mode_type == FILE_DIALOG_OPEN_MULTIPLE)
    gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);

  if (mode_type == FILE_DIALOG_SAVE) {
    gtk_file_chooser_set_do_overwrite_confirmation(
        GTK_FILE_CHOOSER(dialog),
        !!(mode & FILE_DIALOG_OVERWRITEPROMPT_FLAG));
  }

  gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(dialog),
                                   !(mode & FILE_DIALOG_HIDEREADONLY_FLAG));

  if (!default_file_path.empty() && mode_type == FILE_DIALOG_SAVE) {
    const std::string& file_path = default_file_path;
    bool exists = false;

    struct stat sb;
    if (stat(file_path.c_str(), &sb) == 0 && S_ISREG(sb.st_mode)) {
      // Use the directory and name of the existing file.
      gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog),
                                    file_path.data());
      exists = true;
    }

    if (!exists) {
      // Set the current file name but let the user choose the directory.
      std::string file_name_str = file_path;
      const char* file_name = basename(const_cast<char*>(file_name_str.data()));
      gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), file_name);
    }
  }

  std::vector<GtkFileFilter*> filters;
  AddFilters(GTK_FILE_CHOOSER(dialog), accept_filters, true, &filters);
  if (selected_accept_filter < static_cast<int>(filters.size())) {
    gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog),
                                filters[selected_accept_filter]);
  }

  bool success = false;

  if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
    if (mode_type == FILE_DIALOG_OPEN || mode_type == FILE_DIALOG_OPEN_FOLDER ||
        mode_type == FILE_DIALOG_SAVE) {
      char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
      files.push_back(std::string(filename));
      success = true;
    } else if (mode_type == FILE_DIALOG_OPEN_MULTIPLE) {
      GSList* filenames =
          gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
      if (filenames) {
        for (GSList* iter = filenames; iter != NULL;
             iter = g_slist_next(iter)) {
          std::string path(static_cast<char*>(iter->data));
          g_free(iter->data);
          files.push_back(path);
        }
        g_slist_free(filenames);
        success = true;
      }
    }
  }

  int filter_index = selected_accept_filter;
  if (success) {
    GtkFileFilter* selected_filter =
        gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog));
    if (selected_filter != NULL) {
      for (size_t x = 0; x < filters.size(); ++x) {
        if (filters[x] == selected_filter) {
          filter_index = x;
          break;
        }
      }
    }
  }

  gtk_widget_destroy(dialog);

  if (success)
    callback->Continue(filter_index, files);
  else
    callback->Cancel();

  return true;
}

bool ClientDialogHandlerGtk::OnJSDialog(
    CefRefPtr<CefBrowser> browser,
    const CefString& origin_url,
    JSDialogType dialog_type,
    const CefString& message_text,
    const CefString& default_prompt_text,
    CefRefPtr<CefJSDialogCallback> callback,
    bool& suppress_message) {
  CEF_REQUIRE_UI_THREAD();

  GtkButtonsType buttons = GTK_BUTTONS_NONE;
  GtkMessageType gtk_message_type = GTK_MESSAGE_OTHER;
  std::string title;

  switch (dialog_type) {
    case JSDIALOGTYPE_ALERT:
      buttons = GTK_BUTTONS_NONE;
      gtk_message_type = GTK_MESSAGE_WARNING;
      title = "JavaScript Alert";
      break;

    case JSDIALOGTYPE_CONFIRM:
      buttons = GTK_BUTTONS_CANCEL;
      gtk_message_type = GTK_MESSAGE_QUESTION;
      title = "JavaScript Confirm";
      break;

    case JSDIALOGTYPE_PROMPT:
      buttons = GTK_BUTTONS_CANCEL;
      gtk_message_type = GTK_MESSAGE_QUESTION;
      title = "JavaScript Prompt";
      break;
  }

  js_dialog_callback_ = callback;

  if (!origin_url.empty()) {
    title += " - ";
    title += CefFormatUrlForSecurityDisplay(origin_url).ToString();
  }

  GtkWindow* window = GetWindow(browser);
  if (!window)
    return false;

  gtk_dialog_ = gtk_message_dialog_new(GTK_WINDOW(window),
                                       GTK_DIALOG_MODAL,
                                       gtk_message_type,
                                       buttons,
                                       "%s",
                                       message_text.ToString().c_str());
  g_signal_connect(gtk_dialog_,
                   "delete-event",
                   G_CALLBACK(gtk_widget_hide_on_delete),
                   NULL);

  gtk_window_set_title(GTK_WINDOW(gtk_dialog_), title.c_str());

  GtkWidget* ok_button = gtk_dialog_add_button(GTK_DIALOG(gtk_dialog_),
                                               GTK_STOCK_OK,
                                               GTK_RESPONSE_OK);

  if (dialog_type != JSDIALOGTYPE_PROMPT)
    gtk_widget_grab_focus(ok_button);

  if (dialog_type == JSDIALOGTYPE_PROMPT) {
    GtkWidget* content_area =
        gtk_dialog_get_content_area(GTK_DIALOG(gtk_dialog_));
    GtkWidget* text_box = gtk_entry_new();
    gtk_entry_set_text(GTK_ENTRY(text_box),
                       default_prompt_text.ToString().c_str());
    gtk_box_pack_start(GTK_BOX(content_area), text_box, TRUE, TRUE, 0);
    g_object_set_data(G_OBJECT(gtk_dialog_), kPromptTextId, text_box);
    gtk_entry_set_activates_default(GTK_ENTRY(text_box), TRUE);
  }

  gtk_dialog_set_default_response(GTK_DIALOG(gtk_dialog_), GTK_RESPONSE_OK);
  g_signal_connect(gtk_dialog_, "response", G_CALLBACK(OnDialogResponse), this);
  gtk_widget_show_all(GTK_WIDGET(gtk_dialog_));

  return true;
}

bool ClientDialogHandlerGtk::OnBeforeUnloadDialog(
    CefRefPtr<CefBrowser> browser,
    const CefString& message_text,
    bool is_reload,
    CefRefPtr<CefJSDialogCallback> callback) {
  CEF_REQUIRE_UI_THREAD();

  const std::string& new_message_text =
      message_text.ToString() + "\n\nIs it OK to leave/reload this page?";
  bool suppress_message = false;

  return OnJSDialog(browser, CefString(), JSDIALOGTYPE_CONFIRM,
                    new_message_text, CefString(), callback, suppress_message);
}

void ClientDialogHandlerGtk::OnResetDialogState(CefRefPtr<CefBrowser> browser) {
  CEF_REQUIRE_UI_THREAD();

  if (!gtk_dialog_)
    return;
  gtk_widget_destroy(gtk_dialog_);
  gtk_dialog_ = NULL;
  js_dialog_callback_ = NULL;
}

// static
void ClientDialogHandlerGtk::OnDialogResponse(GtkDialog* dialog,
                                              gint response_id,
                                              ClientDialogHandlerGtk* handler) {
  CEF_REQUIRE_UI_THREAD();

  DCHECK_EQ(dialog, GTK_DIALOG(handler->gtk_dialog_));
  switch (response_id) {
    case GTK_RESPONSE_OK:
      handler->js_dialog_callback_->Continue(true, GetPromptText(dialog));
      break;
    case GTK_RESPONSE_CANCEL:
    case GTK_RESPONSE_DELETE_EVENT:
      handler->js_dialog_callback_->Continue(false, CefString());
      break;
    default:
      NOTREACHED();
  }

  handler->OnResetDialogState(NULL);
}

}  // namespace client

redpajama_set_name: RedPajamaGithub


text:
package com.bukhmastov.cdoitmo.activity;

import android.content.Context;
import android.os.Bundle;

import com.bukhmastov.cdoitmo.R;
import com.bukhmastov.cdoitmo.activity.presenter.TimeRemainingWidgetActivityPresenter;
import com.bukhmastov.cdoitmo.factory.AppComponentProvider;
import com.bukhmastov.cdoitmo.util.StoragePref;
import com.bukhmastov.cdoitmo.util.Theme;
import com.bukhmastov.cdoitmo.util.singleton.CtxWrapper;

import javax.inject.Inject;

public class TimeRemainingWidgetActivity extends BaseActivity {

    @Inject
    TimeRemainingWidgetActivityPresenter presenter;
    @Inject
    StoragePref storagePref;
    @Inject
    Theme theme;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        AppComponentProvider.getComponent().inject(this);
        presenter.setActivity(this);
        switch (theme.getAppTheme(this)) {
            case "light":
            default: setTheme(R.style.AppTheme_Popup); break;
            case "dark": setTheme(R.style.AppTheme_Popup_Dark); break;
            case "white": setTheme(R.style.AppTheme_Popup_White); break;
            case "black": setTheme(R.style.AppTheme_Popup_Black); break;
        }
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_widget_remaining);
        presenter.onCreate(savedInstanceState);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        presenter.onDestroy();
    }

    @Override
    protected void onResume() {
        super.onResume();
        presenter.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        presenter.onPause();
    }

    @Override
    protected void attachBaseContext(Context context) {
        AppComponentProvider.getComponent().inject(this);
        super.attachBaseContext(CtxWrapper.wrap(context, storagePref));
    }
}


text:
package hotplugdisk

import (
	"testing"

	"kubevirt.io/client-go/testutils"
)

func TestHostDisk(t *testing.T) {
	testutils.KubeVirtTestSuiteSetup(t)
}


text:
package com.appleframework.data.hbase.config;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hbase.client.Table;
import org.springframework.core.NamedThreadLocal;
import org.springframework.util.Assert;

/**
 * Synchronization manager handling the tracking of Hbase resources (specifically tables). Used either manually or through {@link HbaseInterceptor} to bind a table to the thread.
 * Each subsequent call made through {@link HbaseTemplate} is aware of the table bound and will use it instead of retrieving a new instance.
 *
 * @author Costin Leau
 */
public abstract class HbaseSynchronizationManager {

	private static final Log logger = LogFactory.getLog(HbaseSynchronizationManager.class);

	private static final ThreadLocal<Map<String, Table>> resources = new NamedThreadLocal<Map<String, Table>>("Bound resources");

	/**
	 * Checks whether any resource is bound for the given key.
	 *
	 * @param key key to check
	 * @return whether or not a resource is bound for the given key
	 */
	public static boolean hasResource(Object key) {
		Object value = doGetResource(key);
		return (value != null);
	}

	/**
	 * Returns the resource (table) associated with the given key.
	 *
	 * @param key association key
	 * @return associated resource (table)
	 */
	public static Table getResource(Object key) {
		return doGetResource(key);
	}

	/**
	 * Actually checks the value of the resource that is bound for the given key.
	 */
	private static Table doGetResource(Object actualKey) {
		Map<String, Table> tables = resources.get();
		if (tables == null) {
			return null;
		}
		return tables.get(actualKey);
	}

	/**
	 * Binds the given resource for the given key to the current thread.
	 * @param key the key to bind the value to (usually the resource factory)
	 * @param value the value to bind (usually the active resource object)
	 * @throws IllegalStateException if there is already a value bound to the thread
	 * @see ResourceTransactionManager#getResourceFactory()
	 */
	public static void bindResource(String key, Table value) throws IllegalStateException {
		Assert.notNull(value, "Value must not be null");
		Map<String, Table> map = resources.get();
		// set ThreadLocal Map if none found
		if (map == null) {
			map = new LinkedHashMap<String, Table>();
			resources.set(map);
		}
		Table oldValue = map.put(key, value);
		if (oldValue != null) {
			throw new IllegalStateException("Already value [" + oldValue + "] for key [" + key
					+ "] bound to thread [" + Thread.currentThread().getName() + "]");
		}
		if (logger.isTraceEnabled()) {
			logger.trace("Bound value [" + value + "] for key [" + key + "] to thread ["
					+ Thread.currentThread().getName() + "]");
		}
	}

	/**
	 * Unbinds a resource for the given key from the current thread.
	 * @param key the key to unbind (usually the resource factory)
	 * @return the previously bound value (usually the active resource object)
	 * @throws IllegalStateException if there is no value bound to the thread
	 * @see ResourceTransactionManager#getResourceFactory()
	 */
	public static Table unbindResource(String key) throws IllegalStateException {
		Table value = doUnbindResource(key);
		if (value == null) {
			throw new IllegalStateException("No value for key [" + key + "] bound to thread ["
					+ Thread.currentThread().getName() + "]");
		}
		return value;
	}

	/**
	 * Unbinds a resource for the given key from the current thread.
	 *
	 * @param key the key to unbind (usually the resource factory)
	 * @return the previously bound value, or null if none bound
	 */
	public static Object unbindResourceIfPossible(Object key) {
		return doUnbindResource(key);
	}

	/**
	 * Actually remove the value of the resource that is bound for the given key.
	 */
	private static Table doUnbindResource(Object actualKey) {
		Map<String, Table> map = resources.get();
		if (map == null) {
			return null;
		}
		Table value = map.remove(actualKey);
		// Remove entire ThreadLocal if empty...
		if (map.isEmpty()) {
			resources.remove();
		}

		if (value != null && logger.isTraceEnabled()) {
			logger.trace("Removed value [" + value + "] for key [" + actualKey + "] from thread ["
					+ Thread.currentThread().getName() + "]");
		}
		return value;
	}

	/**
	 * Returns the bound tables (by name).
	 *
	 * @return names of bound tables
	 */
	public static Set<String> getTableNames() {
		Map<String, Table> map = resources.get();
		if (map != null && !map.isEmpty()) {
			return Collections.unmodifiableSet(map.keySet());
		}
		return Collections.emptySet();
	}
}


text:
/**
 * @overview
 * This file contains the briefcase controller class.
 *
 */

/**
 * Creates the briefcase controller.
 * @class
 * This class represents the briefcase controller for the content view used by the briefcase application.
 *
 * @author Parag Shah
 *
 * @param {DwtControl}					container					the containing shell
 * @param {ZmApp}						app							the containing application
 * @param {constant}					type						type of controller
 * @param {string}						sessionId					the session id
 * @param {ZmSearchResultsController}	searchResultsController		containing controller
 *
 * @extends		ZmListController
 */
ZmBriefcaseController = function(container, app, type, sessionId, searchResultsController) {

 	if (arguments.length == 0) { return; }

	ZmListController.apply(this, arguments);

	this._idMap = {};

	this._listChangeListener = this._fileListChangeListener.bind(this);

	this._listeners[ZmOperation.OPEN_FILE]			= this._openFileListener.bind(this);
	this._listeners[ZmOperation.SAVE_FILE]			= this._saveFileListener.bind(this);
	this._listeners[ZmOperation.SEND_FILE]			= this._sendFileListener.bind(this);
	this._listeners[ZmOperation.SEND_FILE_AS_ATT]	= this._sendFileAsAttachmentListener.bind(this);
	this._listeners[ZmOperation.NEW_FILE]			= this._uploadFileListener.bind(this);
	this._listeners[ZmOperation.VIEW_FILE_AS_HTML]	= this._viewAsHtmlListener.bind(this);
	this._listeners[ZmOperation.CREATE_SLIDE_SHOW]	= this._createSlideShow.bind(this);
    this._listeners[ZmOperation.EDIT_FILE]			= this._editFileListener.bind(this);
    this._listeners[ZmOperation.RENAME_FILE]		= this._renameFileListener.bind(this);
    this._listeners[ZmOperation.NEW_BRIEFCASE_WIN]	= this._newWinListener.bind(this);

	this._listeners[ZmOperation.NEW_SPREADSHEET]	= this._handleDoc.bind(this, ZmOperation.NEW_SPREADSHEET);
	this._listeners[ZmOperation.NEW_PRESENTATION]	= this._handleDoc.bind(this, ZmOperation.NEW_PRESENTATION);
	this._listeners[ZmOperation.NEW_DOC]			= this._handleDoc.bind(this, ZmOperation.NEW_DOC);

    this._listeners[ZmOperation.CHECKIN]			= this._handleCheckin.bind(this);
    this._listeners[ZmOperation.CHECKOUT]			= this._checkoutListener.bind(this);
    this._listeners[ZmOperation.DISCARD_CHECKOUT]	= this._handleDiscardCheckout.bind(this);
    this._listeners[ZmOperation.RESTORE_VERSION]	= this._restoreVerListener.bind(this);

	if (this.supportsDnD()) {
		this._dragSrc = new DwtDragSource(Dwt.DND_DROP_MOVE);
		this._dragSrc.addDragListener(this._dragListener.bind(this));
	}

    this._parentView = {};
};

ZmBriefcaseController.prototype = new ZmListController;
ZmBriefcaseController.prototype.constructor = ZmBriefcaseController;

ZmBriefcaseController.prototype.isZmBriefcaseController = true;
ZmBriefcaseController.prototype.toString = function() { return "ZmBriefcaseController"; };

// Constants
ZmBriefcaseController._VIEWS = {};
ZmBriefcaseController._VIEWS[ZmId.VIEW_BRIEFCASE_DETAIL]	= "ZmPreviewPaneView";

ZmBriefcaseController.RP_IDS = [ZmSetting.RP_BOTTOM, ZmSetting.RP_RIGHT, ZmSetting.RP_OFF];

// reading pane options
ZmBriefcaseController.PREVIEW_PANE_TEXT = {};
ZmBriefcaseController.PREVIEW_PANE_TEXT[ZmSetting.RP_OFF]	= ZmMsg.previewPaneOff;
ZmBriefcaseController.PREVIEW_PANE_TEXT[ZmSetting.RP_BOTTOM]	= ZmMsg.previewPaneAtBottom;
ZmBriefcaseController.PREVIEW_PANE_TEXT[ZmSetting.RP_RIGHT]	= ZmMsg.previewPaneOnRight;

ZmBriefcaseController.PREVIEW_PANE_ICON = {};
ZmBriefcaseController.PREVIEW_PANE_ICON[ZmSetting.RP_OFF]	    = "SplitPaneOff";
ZmBriefcaseController.PREVIEW_PANE_ICON[ZmSetting.RP_BOTTOM]	= "SplitPane";
ZmBriefcaseController.PREVIEW_PANE_ICON[ZmSetting.RP_RIGHT]	    = "SplitPaneVertical";

// convert key mapping to view menu item
ZmBriefcaseController.ACTION_CODE_TO_MENU_ID = {};
ZmBriefcaseController.ACTION_CODE_TO_MENU_ID[ZmKeyMap.READING_PANE_OFF]		= ZmSetting.RP_OFF;
ZmBriefcaseController.ACTION_CODE_TO_MENU_ID[ZmKeyMap.READING_PANE_BOTTOM]	= ZmSetting.RP_BOTTOM;
ZmBriefcaseController.ACTION_CODE_TO_MENU_ID[ZmKeyMap.READING_PANE_RIGHT]	= ZmSetting.RP_RIGHT;

//List Views

ZmBriefcaseController.LIST_VIEW = {};
ZmBriefcaseController.LIST_VIEW[ZmId.VIEW_BRIEFCASE_DETAIL] =   {image: "GenericDoc", text: ZmMsg.byLatestFile };
ZmBriefcaseController.LIST_VIEW[ZmId.VIEW_BRIEFCASE_REVISION] = {image: "VersionHistory", text: ZmMsg.byVersionHistory };

/**
 * The list view as a whole is the drop target, since it's the lowest-level widget. Still, we
 * need to find out which item got dropped onto, so we get that from the original UI event
 * (a mouseup). The header is within the list view, but not an item, so it's not a valid drop
 * target. One drawback of having the list view be the drop target is that we can't exercise
 * fine-grained control on what's a valid drop target. If you enter via an item and then drag to
 * the header, it will appear to be valid.
 *
 * @protected
 */
ZmBriefcaseController.prototype._dropListener =
function(ev) {
	var view = this._listView[this._currentViewId];
	var div = view.getTargetItemDiv(ev.uiEvent);
	var item = view.getItemFromElement(div);
	if(!item || !( item.isRevision || item.isFolder) ) {
		ZmListController.prototype._dropListener.call(this,ev);
	} else {
		ev.doIt = false;
	}
}

ZmBriefcaseController.prototype._standardActionMenuOps =
function() {
	return [ZmOperation.TAG_MENU, ZmOperation.DELETE, ZmOperation.MOVE];
};

/**
 * @private
 */
ZmBriefcaseController.prototype._getSecondaryToolBarOps =
function() {
	var list = [];
    if (appCtxt.isExternalAccount()) { return list; }
	if (appCtxt.get(ZmSetting.MAIL_ENABLED)) {
		list.push(ZmOperation.SEND_FILE, ZmOperation.SEND_FILE_AS_ATT, ZmOperation.SEP);
	}
	if (appCtxt.get(ZmSetting.SPREADSHEET_ENABLED)) {
		list.push(ZmOperation.NEW_SPREADSHEET,ZmOperation.SEP);
	}
	if (appCtxt.get(ZmSetting.SLIDES_ENABLED)) {
		list.push(ZmOperation.NEW_PRESENTATION,ZmOperation.SEP);
	}
	list.push(ZmOperation.NEW_BRIEFCASE_WIN, ZmOperation.SEP);

	list.push(ZmOperation.CHECKOUT, ZmOperation.CHECKIN, ZmOperation.DISCARD_CHECKOUT, ZmOperation.RESTORE_VERSION);

	list.push(ZmOperation.SEP);
	list.push(ZmOperation.RENAME_FILE);

	return list;
};

ZmBriefcaseController.prototype._getToolBarOps =
function() {
    var ops = [ZmOperation.NEW_FILE,
            ZmOperation.SAVE_FILE,
			ZmOperation.SEP,
            ZmOperation.EDIT_FILE,
			ZmOperation.SEP,
			ZmOperation.DELETE,
			ZmOperation.SEP,
			ZmOperation.MOVE_MENU,
			ZmOperation.TAG_MENU
			];

	/*if (appCtxt.get(ZmSetting.DOCS_ENABLED)) {
		   ops.push(ZmOperation.NEW_DOC,ZmOperation.SEP);
	}*/

	return ops;
};

ZmBriefcaseController.prototype._getRightSideToolBarOps =
function(noViewMenu) {
	return [ZmOperation.VIEW_MENU];
};

ZmBriefcaseController.prototype._handleDoc =
function(op) {
	this._app.handleOp(op);
};

ZmBriefcaseController.prototype._initializeToolBar =
function(view) {

	if (!this._toolbar[view]) {
		ZmListController.prototype._initializeToolBar.call(this, view);
		this._setupViewMenu(view, true);
        var toolbar = this._toolbar[view];
		toolbar.addFiller();
		this._initializeNavToolBar(view);
		appCtxt.notifyZimlets("initializeToolbar", [this._app, toolbar, this, view], {waitUntilLoaded:true});
	} else {
        this._setupDeleteButton(this._toolbar[view]);
        this._setupViewMenu(view, false);
	}
};

// If we're in the Trash folder, change the "Delete" button tooltip
ZmBriefcaseController.prototype._setupDeleteButton =
function(parent) {
    var folder = this._getSearchFolder();
    var inTrashFolder = (folder && folder.nId == ZmFolder.ID_TRASH);
    var tooltip = inTrashFolder ? ZmMsg.deletePermanentTooltip : ZmMsg.deleteTooltip;
    var deleteButton = parent.getButton(ZmOperation.DELETE);
    if(deleteButton){
        deleteButton.setToolTipContent(ZmOperation.getToolTip(ZmOperation.DELETE, this.getKeyMapName(), tooltip));
    }
};

ZmBriefcaseController.prototype._initializeNavToolBar =
function(view) {
	this._itemCountText[view] = this._toolbar[view].getButton(ZmOperation.TEXT);
};

ZmBriefcaseController.prototype._resetOperations =
function(parent, num) {
	if (!parent) { return; }

	// call base class
	ZmListController.prototype._resetOperations.call(this, parent, num);

	var items = this._listView[this._currentViewId].getSelection();
	var isFolderSelected=false, noOfFolders = 0, isRevisionSelected=false, isBriefcaseItemSelected=false, isMixedSelected=false;
    var isWebDocSelected= false, hasLocked = false, allLocked = true, sameLockOwner=true;
    var hasHighestRevisionSelected = false, hasOldRevisionSelected = false;
	if (items) {
		for (var i = 0; i < items.length; i++) {
			var item = items[i];
			if (item.isFolder) {
				isFolderSelected = true;
				noOfFolders++;
			}else if(item.isRevision){
                isRevisionSelected = true;
                if(item.parent.version == item.version){
                    hasHighestRevisionSelected = true;
                }
				else {
					hasOldRevisionSelected = true;
				}
            }else{
                isBriefcaseItemSelected = true;
            }

            isWebDocSelected = isWebDocSelected || ( !item.isFolder && item.isWebDoc() );

            allLocked = allLocked && item.locked;

            hasLocked = hasLocked || item.locked;

            sameLockOwner = sameLockOwner && (item.locked && item.lockUser == appCtxt.getActiveAccount().name);
		}
	}

    isMixedSelected = isFolderSelected ? (isBriefcaseItemSelected || isRevisionSelected) :  (isBriefcaseItemSelected && isRevisionSelected);

    var briefcase = appCtxt.getById(this._folderId);
    if(!(briefcase instanceof ZmBriefcase)){
        briefcase = null;
    }
    var isTrash = (briefcase && briefcase.nId == ZmOrganizer.ID_TRASH);
    var isShared = ((briefcase && briefcase.nId != ZmOrganizer.ID_TRASH && briefcase.isShared()));
	var isReadOnly = briefcase ? briefcase.isReadOnly() : false;
	var isMultiFolder = (noOfFolders > 1);
	var isItemSelected = (num>0);
	var isZimbraAccount = appCtxt.getActiveAccount().isZimbraAccount;
	var isMailEnabled = appCtxt.get(ZmSetting.MAIL_ENABLED);
    var isAdmin = briefcase && briefcase.isAdmin();

    var item = items[0];
    //bug 65351
    // treat the latest revision selection as if it was a file selection.
    // isOldRevision is true if the item is a revision but not the latest.
    var isOldRevision = hasOldRevisionSelected ? true : item && item.revision && !hasHighestRevisionSelected;

	parent.enable([ZmOperation.SEND_FILE, ZmOperation.SEND_FILE_AS_ATT], (isZimbraAccount && isMailEnabled && isItemSelected && !isMultiFolder && !isFolderSelected));
	parent.enable(ZmOperation.TAG_MENU, (!isReadOnly && isItemSelected && !isFolderSelected && !isOldRevision));
	parent.enable([ZmOperation.NEW_FILE, ZmOperation.VIEW_MENU], true);
	parent.enable([ZmOperation.NEW_SPREADSHEET, ZmOperation.NEW_PRESENTATION, ZmOperation.NEW_DOC], true);
	parent.enable([ZmOperation.MOVE, ZmOperation.MOVE_MENU], ( isItemSelected &&  !isReadOnly && !isShared && !isOldRevision));
    parent.enable(ZmOperation.NEW_FILE, !(isTrash || isReadOnly));
    parent.enable(ZmOperation.NEW_BRIEFCASE_WIN, (isItemSelected && !isFolderSelected && num==1));

    var firstItem = items && items[0];
    var isWebDoc = firstItem && !firstItem.isFolder && firstItem.isWebDoc();
    var isLocked = firstItem && !firstItem.isFolder && firstItem.locked;
    var isLockOwner = isLocked && (item.lockUser == appCtxt.getActiveAccount().name);

    //Rename Operation
    parent.enable(ZmOperation.RENAME_FILE, ( num ==1 && !isFolderSelected && !isReadOnly && !isOldRevision && (isLocked ? isLockOwner : true) ));

    //Download - Files
    parent.enable(ZmOperation.SAVE_FILE, num >0 && (!isFolderSelected || isBriefcaseItemSelected));

    // Edit
    parent.enable(ZmOperation.OPEN_FILE, (num == 1 && isWebDoc));
    parent.enable(ZmOperation.EDIT_FILE, !isReadOnly && (  !isLocked || isLockOwner ) && isWebDoc && !isOldRevision && num == 1);

    //Delete Operation
    parent.enable(ZmOperation.DELETE, (!isReadOnly && isItemSelected && (hasHighestRevisionSelected ? !hasOldRevisionSelected : true) && !isMixedSelected && (isLocked ? isLockOwner : true)));

    if(parent &&  parent instanceof ZmActionMenu){

        //Open - webDocs
        parent.getOp(ZmOperation.OPEN_FILE) && parent.getOp(ZmOperation.OPEN_FILE).setVisible(isItemSelected && !isMultiFolder && isWebDoc);

	}
	//Case 1: Multiple Admins
	//Case 2: Stale Lock ( Handle exception )

	//Checkin
	var op = parent.getOp(ZmOperation.CHECKIN);
	if (op) {
		var checkinEnabled = !isReadOnly && isLockOwner && !isWebDoc && !isOldRevision;
		op.setVisible(checkinEnabled);
		parent.enable(ZmOperation.CHECKIN, checkinEnabled && num == 1);
	}

	//Checkout
	op = parent.getOp(ZmOperation.CHECKOUT);
	if (op) {
		var checkoutEnabled = !isReadOnly && !hasLocked && !isRevisionSelected && !isFolderSelected;
		op.setVisible(!isOldRevision && !isLocked);
		parent.enable(ZmOperation.CHECKOUT, checkoutEnabled);
	}

	//Discard Checkout
	op = parent.getOp(ZmOperation.DISCARD_CHECKOUT);
	if (op) {
		var discardCheckoutEnabled = sameLockOwner && !isRevisionSelected;
		op.setVisible(discardCheckoutEnabled);
		parent.enable(ZmOperation.DISCARD_CHECKOUT, discardCheckoutEnabled && (isAdmin || sameLockOwner || !isShared));
	}

	//Versioning
	op = parent.getOp(ZmOperation.RESTORE_VERSION);
	if (op) {
		var versionEnabled = (!isReadOnly && num == 1 && isOldRevision);
		var isHightestVersion = item && item.isRevision && ( item.parent.version == item.version );
		op.setVisible(isOldRevision);
		parent.enable(ZmOperation.RESTORE_VERSION, versionEnabled && !isHightestVersion);
	}

    var isDocOpEnabled = !(isTrash || isReadOnly);
    if (appCtxt.get(ZmSetting.DOCS_ENABLED)) {
        parent.enable(ZmOperation.NEW_DOC, isDocOpEnabled);
    }
    if (appCtxt.get(ZmSetting.SPREADSHEET_ENABLED)) {
        parent.enable(ZmOperation.NEW_SPREADSHEET, isDocOpEnabled);
    }
    if (appCtxt.get(ZmSetting.SLIDES_ENABLED)) {
        parent.enable(ZmOperation.NEW_PRESENTATION, isDocOpEnabled);
        parent.enable(ZmOperation.CREATE_SLIDE_SHOW, isDocOpEnabled && isItemSelected);
    }

    if(appCtxt.isExternalAccount()) {
        parent.enable ([ZmOperation.SEND_FILE,
                        ZmOperation.SEND_FILE_AS_ATT,
                        ZmOperation.RENAME_FILE,
                        ZmOperation.MOVE,
                        ZmOperation.MOVE_MENU,
                        ZmOperation.NEW_FILE,
                        ZmOperation.TAG_MENU,
                        ZmOperation.EDIT_FILE,
                        ZmOperation.OPEN_FILE,
                        ZmOperation.CHECKIN,
                        ZmOperation.CHECKOUT,
                        ZmOperation.DISCARD_CHECKOUT,
                        ZmOperation.RESTORE_VERSION,
                        ZmOperation.NEW_BRIEFCASE_WIN,
                        ZmOperation.DELETE
                        ], false);
        parent.setItemVisible(ZmOperation.TAG_MENU, false);
    }
};

ZmBriefcaseController.prototype._getTagMenuMsg =
function() {
	return ZmMsg.tagFile;
};

ZmBriefcaseController.prototype._doDelete =
function(items) {

	if (!items) {
		items = this._listView[this._currentViewId].getSelection();
	}
    var item = (items instanceof Array) ? items[0] : items;
    if(!item) return;

	var message = ( items.length > 1 ) ?  ( item.isRevision  ? ZmMsg.confirmPermanentDeleteItemList : ZmMsg.confirmDeleteItemList ) : null;
	if (!message) {
        var delMsgFormatter = new AjxMessageFormat( (this._folderId == String(ZmOrganizer.ID_TRASH) || (item.isRevision && item.parent.version != item.version) ) ? ZmMsg.confirmPermanentDeleteItem : ZmMsg.confirmDeleteItem );
		message = delMsgFormatter.format(AjxStringUtil.htmlEncode(item.name));
	}

    var dialog = appCtxt.getConfirmationDialog();
	dialog.popup(message, new AjxCallback(this, this._doDelete2, [items]));
};

ZmBriefcaseController.prototype._doDelete2 =
function(items) {

    var item = (items instanceof Array) ? items[0] : items;

    if(item.isRevision && item.parent.version != item.version){
        var view = this._parentView[this._currentViewId];
        view.deleteVersions(items);
    }else if(item.isFolder){
        var delBatchCmd = new ZmBatchCommand(true), folder;
        for(var i=0; i< items.length; i++){
            folder = items[i].folder;
            if(folder.isHardDelete()){
                delBatchCmd.add(new AjxCallback(folder, folder._delete, [delBatchCmd]));
            }else{
                var trashFolder = appCtxt.getById(ZmFolder.ID_TRASH);
                delBatchCmd.add(new AjxCallback(folder, folder.move, [trashFolder, false, null, delBatchCmd]));
            }
        }
        delBatchCmd.run();
    }else{
		for (var i=0; i<items.length; i++) {
			if (items[i].isRevision) {
				items[i] = items[i].parent;
			}
		}
        ZmListController.prototype._doDelete.call(this, items, null, null, true);
    }
};

// view management

ZmBriefcaseController.getDefaultViewType =
function() {
	return ZmId.VIEW_BRIEFCASE_DETAIL;
};
ZmBriefcaseController.prototype.getDefaultViewType = ZmBriefcaseController.getDefaultViewType;

ZmBriefcaseController.prototype._createNewView =
function(view) {

	var viewType = appCtxt.getViewTypeFromId(view);
    var viewCtor = eval(ZmBriefcaseController._VIEWS[viewType]);
	this._parentView[view] = new viewCtor(this._container, this, this._dropTgt);
	var listView = this._parentView[view].getListView();
	if (this._dragSrc) {
		listView.setDragSource(this._dragSrc);
	}

	return listView;
};

ZmBriefcaseController.prototype._setViewContents =
function(view) {
	var bcv = this._parentView[view];
	bcv.set(this._list, this._switchView);
    this._switchView = false;
};

ZmBriefcaseController.prototype._getDefaultFocusItem =
function() {
	return this._listView[this._currentViewId];
};

// Returns a list of subfolders of the given folder, as ZmBriefcaseItem objects
ZmBriefcaseController.prototype._getSubfolders =
function(folderId) {

	var folderId = folderId || this._currentSearch.folderId;
	var folder = folderId && appCtxt.getById(folderId);
	var subfolders = [];
	if (folder) {
		var children = folder.children;
		for (var i = 0, len = children.size(); i < len; i++) {
            folder = children.get(i);
            if(folder.type == ZmOrganizer.BRIEFCASE)
			    subfolders.push(new ZmBriefcaseFolderItem(children.get(i)));
		}
	}

	return subfolders;
};

// view management

/**
 * Shows the search results.
 *
 * @param	{Object}	results		the search results
 */
ZmBriefcaseController.prototype.show =
function(results) {

	this._folderId = results && results.search && results.search.folderId;
	this.setList(results.getResults(ZmItem.BRIEFCASE_ITEM));
	this._list.setHasMore(results.getAttribute("more"));

	ZmListController.prototype.show.call(this, results, this._currentViewId);

	this._setup(this._currentViewId);

	// start fresh with search results
	var lv = this._listView[this._currentViewId];
	lv.offset = 0;
	lv._folderId = this._folderId;

	var elements = this.getViewElements(this._currentViewId, this._parentView[this._currentViewId]);

	this._setView({	view:		this._currentViewId,
					viewType:	this._currentViewType,
					noPush:		this.isSearchResults,
					elements:	elements,
					isAppView:	true});
	if (this.isSearchResults) {
		// if we are switching views, make sure app view mgr is up to date on search view's components
		appCtxt.getAppViewMgr().setViewComponents(this.searchResultsController.getCurrentViewId(), elements, true);
	}
	this._resetNavToolBarButtons();
};

/**
 * Change how briefcase items are displayed.
 *
 * @param {constant}	view			the view to show
 * @param {Boolean}	force			if true, render view even if it's the current view
 */
ZmBriefcaseController.prototype.switchView =
function(view, force) {

	var viewChanged = (force || view != this._currentViewId);

	if (viewChanged) {
        var lv = this._listView[this._currentViewId];
        if (lv) {
			lv.cleanup();
		}
        this._switchView = true;
		this._currentViewId = view;
		this._setup(view);
	}
	this._resetOperations(this._toolbar[view], 0);

	if (viewChanged) {
		var elements = this.getViewElements(view, this._parentView[view]);

		this._setView({ view:		view,
						viewType:	this._currentViewType,
						elements:	elements,
						isAppView:	true});
		this._resetNavToolBarButtons();
	}
	Dwt.setTitle(this.getCurrentView().getTitle());
};

ZmBriefcaseController.prototype._preHideCallback =
function() {

    var lv = this._listView[this._currentViewId];
    if(lv) lv.cleanup();

    return ZmController.prototype._preHideCallback.call(this);
};

ZmBriefcaseController.prototype.getItemById =
function(itemId) {
	return (this._idMap[itemId] ? this._idMap[itemId].item : null);
};

ZmBriefcaseController.prototype.__popupUploadDialog =
function(title, callback) {

	var folderId = this._folderId;
    if(!folderId || folderId == ZmOrganizer.ID_TRASH)
        folderId = ZmOrganizer.ID_BRIEFCASE;

    if(this.chkFolderPermission(folderId)){
        var cFolder = appCtxt.getById(folderId);
		var uploadDialog = appCtxt.getUploadDialog();
        uploadDialog.setConflictAction(ZmUploadDialog.ACTION_KEEP_MINE);
        uploadDialog.popup(cFolder, callback, title, null, false, true, true);
    }
};

ZmBriefcaseController.prototype.chkFolderPermission =
function(folderId){
    var briefcase = appCtxt.getById(folderId);
    if(briefcase.isRemote() && briefcase.isReadOnly()){
        var dialog = appCtxt.getMsgDialog();
        dialog.setMessage(ZmMsg.errorPermissionCreate, DwtMessageDialog.WARNING_STYLE);
        dialog.popup();
        return false;
    }
    return true;
};

ZmBriefcaseController.prototype._listSelectionListener =
function(ev) {
	Dwt.setLoadingTime("ZmBriefcaseItem");
	ZmListController.prototype._listSelectionListener.call(this, ev);

	if (ev.detail == DwtListView.ITEM_DBL_CLICKED) {
		var item = ev.item;

        if(item.isFolder){
            this._app.search({folderId:item.id});
            return;
        }

		var restUrl = item.getRestUrl(false, false, true); //get it with the version number even if clicked on the base item (see ZmBriefcaseBaseItem.prototype.getRestUrl in ZmBriefcaseItem.js)
        //added for bug: 45150
        restUrl = AjxStringUtil.fixCrossDomainReference(restUrl);
        if (item.isWebDoc()) {
			restUrl = ZmBriefcaseApp.addEditorParam(restUrl);
            restUrl += (restUrl.match(/\?/) ? "&" : "?") + "localeId=" + AjxEnv.DEFAULT_LOCALE;

		}
		if (restUrl) {
            if(item.isDownloadable() && !this._alwaysOpenInNewWindow(item)) {
                this._downloadFile(restUrl);
            }else {
			    window.open(restUrl, this._getWindowName(item.name), item.isWebDoc() ? "" : ZmBriefcaseApp.getDocWindowFeatures());
            }
		}
	}
};

ZmBriefcaseController.prototype._alwaysOpenInNewWindow =
function(item){

    return (item.contentType == ZmMimeTable.APP_ADOBE_PDF && this.hasPDFReader())
            || (item.contentType == ZmMimeTable.TEXT_XML) || (item.contentType == ZmMimeTable.APP_XML);

};

ZmBriefcaseController.prototype.hasPDFReader =
function(){
    if(AjxUtil.isUndefined(this._hasPDFReader)){
        this._hasPDFReader = AjxPluginDetector.detectPDFReader();
    }
    return this._hasPDFReader;
}

ZmBriefcaseController.prototype._listActionListener =
function(ev) {

	var item = ev.item;

	if (item && item.isFolder) {
		ev.detail = DwtTree.ITEM_ACTIONED;
		var overviewController = appCtxt.getOverviewController();
		var treeController = overviewController.getTreeController(ZmOrganizer.BRIEFCASE);
		item.setData(ZmTreeView.KEY_TYPE, ZmOrganizer.BRIEFCASE);
		item.setData(Dwt.KEY_OBJECT, item.folder);
		item.setData(ZmTreeView.KEY_ID, this._app.getOverviewId());
		item.setData(Dwt.KEY_ID, item.id);
		treeController._treeViewListener(ev);
		return;
	}

	ZmListController.prototype._listActionListener.call(this, ev);

	var actionMenu = this.getActionMenu();
	actionMenu.popup(0, ev.docX, ev.docY);
	if (ev.ersatz) {
		actionMenu.setSelectedItem(0); // menu popped up via keyboard nav
	}

};

ZmBriefcaseController.prototype._restoreVerListener =
function(){
    var view = this._parentView[this._currentViewId];
    view._restoreVerListener();

};

//Checkin/Checkout

ZmBriefcaseController.prototype._checkoutListener =
function(){
     var items = this._getSelectedItems();
     if(items.length > 1){
        for(var i=0; i< items.length; i++){
           var item = items[i];
           if(item && item instanceof ZmBriefcaseItem){
                this.checkout(item);
           }
        }
     }else{
        var item = items[0];
        if(item && item instanceof ZmBriefcaseItem){
            this.checkout(item, item.isWebDoc() ? null : new AjxCallback(this, this._postCheckout, item));
        }
     }
};

ZmBriefcaseController.prototype._postCheckout =
function(item){
    if(AjxEnv.isSafari){
        setTimeout(AjxCallback.simpleClosure(this.downloadFile, this, item), 100);
    }else{
        this.downloadFile(item);
    }
};

ZmBriefcaseController.prototype._handleCheckin =
function(){
    var item = this._getSelectedItem();
    if(item && item instanceof ZmBriefcaseItem){
        var dlg = this._getCheckinDlg();
        dlg.popup(item, new AjxCallback(this, this._doneCheckin, item));
    }
};

ZmBriefcaseController.prototype._doneCheckin =
function(item, file){
    //Update item attribs
    item.version = file.version;
    item.name = file.name;
    this.unlockItem(item, new AjxCallback(this, this.refreshItem, item));

};

ZmBriefcaseController.prototype._handleDiscardCheckout =
function(){
    var items = this._getSelectedItems();
    for(var i=0; i< items.length; i++){
        var item = items[i];
        if(item && item instanceof ZmBriefcaseItem)
            this.unlockItem(item);
    }
};

ZmBriefcaseController.prototype.refreshItem =
function(item){
    //TODO: Handle version notifications than hard refresh
    var view = this._parentView[this._currentViewId];
    view.refreshItem(item);
};

ZmBriefcaseController.prototype.checkout =
function(item, callback){
    this.lockItem(item, callback);
};

ZmBriefcaseController.prototype.checkin =
function(item, callback){
    this.unlockItem(item, callback);
};

ZmBriefcaseController.prototype.unlockItem =
function(item, callback){
   item.unlock(callback, new AjxCallback(this, this._handleErrorResponse, item));
};

ZmBriefcaseController.prototype.lockItem =
function(item, callback){
   item.lock(callback, new AjxCallback(this, this._handleErrorResponse, item));
};

ZmBriefcaseController.prototype._handleErrorResponse =
function(item, response){
    if(!(response && response.code)) return;

    var msg;
    switch(response.code){
        case ZmCsfeException.CANNOT_UNLOCK:
            msg = ZmMsg.unlockSufficientPermission;
            break;

        case ZmCsfeException.CANNOT_LOCK:
            msg = ZmMsg.lockSuffientPermissions;
            break;
    }

    if(msg){
        var dialog = appCtxt.getMsgDialog();
        dialog.setMessage(msg, DwtMessageDialog.WARNING_STYLE);
        dialog.popup();
    }

    return msg;
};

ZmBriefcaseController.prototype._getSelectedItem =
function(){
    var view = this._listView[this._currentViewId];
	var items = view.getSelection();
    return ( items && items.length > 0 ) ? items[0] : null;
};

ZmBriefcaseController.prototype._getSelectedItems =
function(){
    var view = this._listView[this._currentViewId];
	return view.getSelection();
};

ZmBriefcaseController.prototype._getCheckinDlg =
function(){
    if(!this._checkinDlg){
       this._checkinDlg = new ZmCheckinDialog(appCtxt.getShell());
    }
    return this._checkinDlg;
};

//End of Checkin/Checkout

ZmBriefcaseController.prototype._getActionMenuOps =
function() {
	var list = [
		ZmOperation.OPEN_FILE,
		ZmOperation.SAVE_FILE,
        ZmOperation.EDIT_FILE,
		ZmOperation.SEND_FILE,
		ZmOperation.SEND_FILE_AS_ATT
	];
    if (appCtxt.get(ZmSetting.SLIDES_ENABLED)) {
		list.push(ZmOperation.CREATE_SLIDE_SHOW);
	}
    list.push(ZmOperation.SEP);
    list.push(ZmOperation.CHECKOUT, ZmOperation.CHECKIN, ZmOperation.DISCARD_CHECKOUT, ZmOperation.RESTORE_VERSION/*, ZmOperation.DELETE_VERSION*/);

	list.push(ZmOperation.SEP);
	list = list.concat(this._standardActionMenuOps());
    list.push(ZmOperation.RENAME_FILE);
	return list;
};

ZmBriefcaseController.prototype._renameFileListener =
function(){

    var view = this._listView[this._currentViewId];
	var items = view.getSelection();
	if (!items) { return; }

    view.renameFile(items[0]);
};

ZmBriefcaseController.prototype._newWinListener =
function(){
    var view = this._listView[this._currentViewId];
	var items = view.getSelection();
	if (!items) { return; }
    items = AjxUtil.toArray(items);
    var item = items[0];
    if (item) {
        this.openFile(item);
    }
};

ZmBriefcaseController.prototype._editFileListener =
function() {
	var view = this._listView[this._currentViewId];
	var items = view.getSelection();
	if (!items) { return; }
    items = AjxUtil.toArray(items);
    var item = items[0];
    if(item){
        this.editFile(item);
    }
};

ZmBriefcaseController.prototype.editFile =
function(items){
    items = AjxUtil.toArray(items);
    for (var i = 0; i < items.length; i++) {
        var item = items[i];
        var restUrl = item.getRestUrl(false, false, true); //get the URL with version number so even on IE9 it would always be the latest.
        if (restUrl) {

            if (item.isWebDoc()) {
                //added for bug: 45150
                restUrl = AjxStringUtil.fixCrossDomainReference(restUrl);
                restUrl = ZmBriefcaseApp.addEditorParam(restUrl);
                restUrl += (restUrl.match(/\?/) ? '&' : '?') + "action=edit&localeId=" + AjxEnv.DEFAULT_LOCALE;
                window.open(restUrl, this._getWindowName(item.name), "");
            }
        }
    }
};

ZmBriefcaseController.prototype._getWindowName =
function(name){
    if(!name){
        return ZmMsg.briefcase;
    }
    //IE does not like special chars as part of window name.
    return AjxEnv.isIE ? name.replace(/[^\w]/g,'') : name;
};

ZmBriefcaseController.prototype._openFileListener =
function() {
	var view = this._listView[this._currentViewId];
	var items = view.getSelection();
	if (!items) { return; }

    this.openFile(items);
};

ZmBriefcaseController.prototype.openFile =
function(items){
    items = AjxUtil.toArray(items);
	for (var i = 0; i < items.length; i++) {
		var item = items[i];
		var restUrl = item.getRestUrl(false, false, true);
		if (!restUrl) {
			continue;
		}
		restUrl = AjxStringUtil.fixCrossDomainReference(restUrl);
		if (item.isWebDoc()) {
			//added for bug: 45150
			restUrl = ZmBriefcaseApp.addEditorParam(restUrl);
			restUrl += (restUrl.match(/\?/) ? "&" : "?") + "localeId=" + AjxEnv.DEFAULT_LOCALE;
		} else {
            // do not try to
            //ZD doesn't support ConvertD.
			if (!ZmMimeTable.isRenderable(item.contentType) && !ZmMimeTable.isMultiMedia(item.contentType) && !appCtxt.isOffline) {
               	restUrl += (restUrl.match(/\?/) ? "&" : "?") + "view=html";
			}
        }

        this._fileInfo={
            "restUrl":restUrl,
            "name":this._getWindowName(item.name),
            "features":item.isWebDoc() ? "" : ZmBriefcaseApp.getDocWindowFeatures()
        }

		var ta = new AjxTimedAction(this, this._openChild);
		AjxTimedAction.scheduleAction(ta, 100);

	}
};

ZmBriefcaseController.prototype._openChild =
function(){
    if(this._fileInfo){
     var opener = window.open(this._fileInfo.restUrl, this._fileInfo.name, this._fileInfo.features);
     opener.focus();
    }
    this._fileInfo = null;
}

ZmBriefcaseController.prototype._saveFileListener =
function() {
	var view = this._listView[this._currentViewId];
	var items = view.getSelection();
	if (!items) { return; }

	items = AjxUtil.toArray(items);

	// Allow download to only one file.
    this.downloadFile(items);
};

ZmBriefcaseController.prototype.downloadFile =
function(items){

    var restUrl, item, length= items.length;
    if(length > 1){
        var params = [];
        var organizer = appCtxt.getById(items[0].folderId);
        for(var i=0; i< length; i++){
            item = items[i];
	        if (!item.isFolder) {
				var itemId;
				if (appCtxt.isOffline && organizer.isShared()) {
					itemId = item.id;
				} else {
					itemId = item.getNormalizedItemId();
				}
				params.push((item.isRevision ? item.parent.id : itemId )+"."+item.version);
	        }
        }
        restUrl = [ ((organizer.isShared() && !appCtxt.isOffline ) ? organizer.getOwnerRestUrl() : organizer.getRestUrl()), "?fmt=zip&list=", params.join(',')].join('');
    }else{
        item = AjxUtil.isArray(items) ? items[0] : items;
        restUrl = item.getRestUrl();
        restUrl += ( restUrl.indexOf('?') == -1 ) ? "?" : "&";
        restUrl += "disp=a"+(item.version ? "&ver="+item.version : "");
    }

    if (!restUrl) {
        return false;
    }
    restUrl = AjxStringUtil.fixCrossDomainReference(restUrl);
    if (restUrl) {
        this._downloadFile(restUrl)
    }
};

ZmBriefcaseController.prototype._downloadFile =
function(downloadUrl){
    if(downloadUrl){
        ZmZimbraMail.unloadHackCallback();
        location.href = downloadUrl;
    }
};

ZmBriefcaseController.prototype._viewAsHtmlListener =
function() {
	var view = this._listView[this._currentViewId];
	var items = view.getSelection();
	if (!items) { return; }

	items = AjxUtil.toArray(items);
	for (var i = 0; i<items.length; i++) {
		var item = items[i];
		var restUrl = item.getRestUrl();
		if (item && restUrl) {
			this.viewAsHtml(restUrl);
		}
	}
};

ZmBriefcaseController.prototype.viewAsHtml =
function(restUrl) {
	if (restUrl.match(/\?/)) {
		restUrl+= "&view=html";
	} else {
		restUrl+= "?view=html";
	}
	window.open(restUrl);
};

ZmBriefcaseController.prototype._uploadFileListener =
function() {
    this.__popupUploadDialog(ZmMsg.uploadFileToBriefcase, new AjxCallback(this, this._handlePostUpload));
};

ZmBriefcaseController.prototype._handlePostUpload =
function(folder, filenames, files){
     var msg = ZmMsg.successfullyUploaded;
     if(files.length > 1){
         msg = AjxMessageFormat.format(ZmMsg.successfullyUploadedFiles, files.length);
     }
     appCtxt.setStatusMsg(msg, ZmStatusView.LEVEL_INFO);
};

ZmBriefcaseController.prototype._sendFileListener =
function(event) {
	var view = this._listView[this._currentViewId];
	var items = view.getSelection();
	items = AjxUtil.toArray(items);

	var names = [];
	var urls = [];
	var inNewWindow = this._app._inNewWindow(event);

	var briefcase, shares;
	var noprompt = false;

	for (var i = 0; i < items.length; i++) {
		var item = items[i];
		briefcase = appCtxt.getById(item.folderId);
		var url;
		if (briefcase.restUrl) {
			//present if the briefcase is a share from another user. In this case, keep that URL as the base.
			url = [briefcase.restUrl, "/", AjxStringUtil.urlComponentEncode(item.name)].join("")
		}
		else {
			//item is in this user's briefcase, so build the rest url.
			url = item.getRestUrl();
		}
		if (appCtxt.isOffline) {
			var remoteUri = appCtxt.get(ZmSetting.OFFLINE_REMOTE_SERVER_URI);
			url = remoteUri + url.substring((url.indexOf("/",7)));
		}

		urls.push(url);
		names.push(item.name);

		if (noprompt) { continue; }

		shares = briefcase && briefcase.shares;
		if (shares) {
			for (var j = 0; j < shares.length; j++) {
				noprompt = noprompt || shares[j].grantee.type == ZmShare.TYPE_PUBLIC;
			}
		}
	}

	if (!shares || !noprompt) {
		var args = [names, urls, inNewWindow];
		var callback = new AjxCallback(this, this._sendFileListener2, args);

		var dialog = appCtxt.getConfirmationDialog();
		dialog.popup(ZmMsg.errorPermissionRequired, callback);
	} else {
		this._sendFileListener2(names, urls);
	}
};

ZmBriefcaseController.prototype._sendFileListener2 =
function(names, urls, inNewWindow) {
	var action = ZmOperation.NEW_MESSAGE;
	var msg = new ZmMailMsg();
	var toOverride = null;
	var subjOverride = new AjxListFormat().format(names);
	var htmlCompose = appCtxt.get(ZmSetting.COMPOSE_AS_FORMAT) == ZmSetting.COMPOSE_HTML;
	var extraBodyText = urls.join(htmlCompose ? "
" : "\n");
	AjxDispatcher.run("Compose", {action: action, inNewWindow: inNewWindow, msg: msg,
								  toOverride: toOverride, subjOverride: subjOverride,
								  extraBodyText: extraBodyText});
};

ZmBriefcaseController.prototype._sendFileAsAttachmentListener =
function(event) {
	var view = this._listView[this._currentViewId];
	var items = view.getSelection();

    this.sendFilesAsAttachment(items);
};

ZmBriefcaseController.prototype.sendFilesAsAttachment =
function(items, callback){

    items = AjxUtil.toArray(items);
    var docInfo = [];
    for (var i = 0; i < items.length; i++) {
        var item = items[i];
        docInfo.push({
            id:     ( item.isRevision ? item.parent.id : item.id ),
            ver:    ( item.isRevision ? item.version : null ),
            ct:     item.contentType,
            s:      item.size
        });
    }

    if (docInfo.length == 0) { return; }

    var action = ZmOperation.NEW_MESSAGE;
    var msg = new ZmMailMsg();
    var toOverride;

    var cc = AjxDispatcher.run("GetComposeController");
    cc._setView({action:action, msg:msg, toOverride:toOverride, inNewWindow:false});
    var draftType = ZmComposeController.DRAFT_TYPE_AUTO;
    var sendDocsCallback = new AjxCallback(cc, cc._handleResponseSaveDraftListener, [draftType, callback]);
    cc.saveDraft(draftType, null, docInfo, sendDocsCallback);
};

ZmBriefcaseController.prototype._resetOpForCurrentView =
function(num) {
	this._resetOperations(this._toolbar[this._currentViewId], num || 0);
};

ZmBriefcaseController.prototype._setupViewMenu =
function(view, firstTime) {

	var btn, menu;
	if (firstTime) {
		btn = this._toolbar[view].getButton(ZmOperation.VIEW_MENU);
		var menu = btn.getMenu();
		if (!menu) {
			menu = new ZmPopupMenu(btn);
			btn.setMenu(menu);

            this._setupPreviewPaneMenu(menu, btn);
		}
	}

    if(!menu){
       btn = this._toolbar[view].getButton(ZmOperation.VIEW_MENU);
       menu = btn && btn.getMenu();
    }

    this._resetPreviewPaneMenu(menu, view);
};

ZmBriefcaseController.prototype._setupPreviewPaneMenu =
function(menu, btn){

    if (menu.getItemCount() > 0) {
		new DwtMenuItem({parent:menu, style:DwtMenuItem.SEPARATOR_STYLE, id:"PREVIEW_SEPERATOR"});
	}

	var miParams = {text:ZmMsg.readingPaneAtBottom, style:DwtMenuItem.RADIO_STYLE, radioGroupId:"RP"};
	var ids = ZmDoublePaneController.RP_IDS;
	var pref = appCtxt.get(ZmSetting.READING_PANE_LOCATION_BRIEFCASE);
	for (var i = 0; i < ids.length; i++) {
		var id = ids[i];
		if (!menu._menuItems[id]) {
			miParams.text = ZmBriefcaseController.PREVIEW_PANE_TEXT[id];
			miParams.image = ZmBriefcaseController.PREVIEW_PANE_ICON[id];
            var mi = menu.createMenuItem(id, miParams);
			mi.setData(ZmOperation.MENUITEM_ID, id);
			mi.addSelectionListener(new AjxListener(this, this._previewPaneListener, id));
			if (id == pref) {
				mi.setChecked(true, true);
				btn.setImage(mi.getImage());
			}
		}
	}

};

ZmBriefcaseController.prototype._resetPreviewPaneMenu =
function(menu, view){
    view = view || this._currentViewId;
    var ids = ZmDoublePaneController.RP_IDS;
    for (var i = 0; i < ids.length; i++) {
		var id = ids[i];
		if (menu._menuItems[id]) {
            menu._menuItems[id].setEnabled(true);
        }
    }
};

/**
 * Checks if the reading pane is "on".
 *
 * @return	{Boolean}	true if the reading pane is "on"
 */
ZmBriefcaseController.prototype.isReadingPaneOn =
function() {
	return (this._getReadingPanePref() != ZmSetting.RP_OFF);
};

/**
 * Checks if the reading pane is "on" right.
 *
 * @return	{Boolean}	true if the reading pane is "on" right.
 */
ZmBriefcaseController.prototype.isReadingPaneOnRight =
function() {
	return (this._getReadingPanePref() == ZmSetting.RP_RIGHT);
};

ZmBriefcaseController.prototype._getReadingPanePref =
function() {
	return (this._readingPaneLoc || appCtxt.get(ZmSetting.READING_PANE_LOCATION_BRIEFCASE));
};

ZmBriefcaseController.prototype._setReadingPanePref =
function(value) {
	if (this.isSearchResults || appCtxt.isExternalAccount()) {
		this._readingPaneLoc = value;
	}
	else {
		appCtxt.set(ZmSetting.READING_PANE_LOCATION_BRIEFCASE, value);
	}
};

ZmBriefcaseController.prototype._previewPaneListener =
function(newPreviewStatus){
    var oldPreviewStatus = appCtxt.get(ZmSetting.READING_PANE_LOCATION_BRIEFCASE);
    this._setReadingPanePref(newPreviewStatus);
    var lv = this._parentView[this._currentViewId];
    lv.resetPreviewPane(newPreviewStatus, oldPreviewStatus);
	//update view button icon to reflect current selection
	var btn = this._toolbar[this._currentViewId].getButton(ZmOperation.VIEW_MENU);
	if (btn) {
		btn.setImage(ZmBriefcaseController.PREVIEW_PANE_ICON[newPreviewStatus]);
	}

};

ZmBriefcaseController.CONVERTABLE = {
	doc:/\.doc$/i,
	xls:/\.xls$/i,
	pdf:/\.pdf$/i,
	ppt:/\.ppt$/i,
	zip:/\.zip$/i,
    txt:/\.txt$/i
};

ZmBriefcaseController.prototype.isConvertable =
function(item) {
	var name = item.name;
	for (var type in ZmBriefcaseController.CONVERTABLE) {
		var regex = ZmBriefcaseController.CONVERTABLE[type];
		if (name.match(regex)) {
			return true;
		}
	}
	return false;
};

ZmBriefcaseController.prototype._fileListChangeListener =
function(ev) {
	if (ev.handled) { return; }
	var details = ev._details;
	if (!details) { return; }
	this._list._notify(ev.event,{items:details.items});
};

ZmBriefcaseController.prototype.getCurrentView =
function() {
	return this._parentView[this._currentViewId];
};
ZmBriefcaseController.prototype.getParentView = ZmBriefcaseController.prototype.getCurrentView;

ZmBriefcaseController.prototype._addListListeners =
function(colView) {
	colView.addActionListener(new AjxListener(this, this._listActionListener));
};

ZmBriefcaseController.prototype.isMultiColView =
function() {
	return (this._currentViewType == ZmId.VIEW_BRIEFCASE_COLUMN);
};

ZmBriefcaseController.prototype.mapSupported =
function(map) {
	return (map == "list" && (this._currentViewType != ZmId.VIEW_BRIEFCASE));
};

ZmBriefcaseController.prototype.getItemTooltip =
function(item, listView) {

	if (item.isFolder) { return null; }

	var prop = [{name:ZmMsg.briefcasePropName, value:item.name}];
	if (item.size) {
		prop.push({name:ZmMsg.briefcasePropSize, value:AjxUtil.formatSize(item.size)});
	}
	if (item.modifyDate) {
		var dateFormatter = AjxDateFormat.getDateTimeInstance(AjxDateFormat.FULL, AjxDateFormat.MEDIUM);
		var dateStr = dateFormatter.format(item.modifyDate);
		prop.push({name:ZmMsg.briefcasePropModified, value:dateStr});
	}

	var subs = {
		fileProperties: prop,
		tagTooltip: listView._getTagToolTip(item)
	};
	return AjxTemplate.expand("briefcase.Briefcase#Tooltip", subs);
};

ZmBriefcaseController.prototype._getDateInLocaleFormat =
function(date) {
	var dateFormatter = AjxDateFormat.getDateTimeInstance(AjxDateFormat.FULL, AjxDateFormat.MEDIUM);
	return dateFormatter.format(date);
};

ZmBriefcaseController.prototype._resetToolbarOperations =
function() {
	if (this._listView[this._currentViewId] != null) {
		this._resetOperations(this._toolbar[this._currentViewId], this._listView[this._currentViewId].getSelectionCount());
	}
};

ZmBriefcaseController.prototype._createSlideShow =
function() {
	var importSlidesQueue = [];
	var view = this._listView[this._currentViewId];
	var items = view.getSelection();
	if (!items) { return; }

	items = AjxUtil.toArray(items);
	for (var i = 0; i < items.length; i++) {
		var item = items[i];
		var restUrl = item.getRestUrl();
		if(item && !item.isFolder && restUrl != null) {
			importSlidesQueue.push(restUrl);
		}
	}
	window.importSlides = true;
	window.importSlidesQueue = importSlidesQueue;
	this._app.handleOp(ZmOperation.NEW_PRESENTATION);
};

// item count doesn't include subfolders
ZmBriefcaseController.prototype._getItemCount =
function() {
	var lv = this._listView[this._currentViewId];
	var list = lv && lv._list;
	if (!list) { return null; }
	var a = list.getArray();
	var num = 0;
	for (var i = 0, len = a.length; i < len; i++) {
		var item = a[i];
		if (item && item.type == ZmItem.BRIEFCASE_ITEM && !item.isFolder) {
			num++;
		}
	}
	return num;
};

ZmBriefcaseController.prototype.handleCreateNotify =
function(create){

    if(this.isMultiColView()){
        var isTrash = (this._folderId == String(ZmOrganizer.ID_TRASH));
        if(!isTrash)
            this.getCurrentView().handleNotifyCreate(create);
    }else{
        var list = this.getList();
        if (list) {
            var item = ZmBriefcaseItem.createFromDom(create, {list:list});
            if (list.search && list.search.matches(item)) {
                list.notifyCreate(create);
            }
        }
    }
};

ZmBriefcaseController.prototype.handleModifyNotify =
function(modifies){
    var view = this._listView[this._currentViewId];
    if (view) {
        view.deselectAll();
	}
    this._resetToolbarOperations();
};

ZmBriefcaseController.prototype._actionErrorCallback =
function(ex){

    var handled = false;
    if(ex.code == ZmCsfeException.MAIL_ALREADY_EXISTS){
        handled = true;
        var dlg = appCtxt.getMsgDialog();
        dlg.setMessage(ZmMsg.errorFileAlreadyExistsResolution, DwtMessageDialog.WARNING_STYLE);
        dlg.popup();
    }

    return handled;
};

//Add to Briefcase

ZmBriefcaseController.prototype.createFromAttachment =
function(msgId, partId, name){

     var dlg = this._saveAttDialog = appCtxt.getChooseFolderDialog();
	 var chooseCb = new AjxCallback(this, this._chooserCallback, [msgId, partId, name]);
	 ZmController.showDialog(dlg, chooseCb, this._getCopyParams(dlg, msgId, partId));

};

ZmBriefcaseController.prototype._getCopyParams =
function(dlg, msgId, partId) {
	var params = {
		data:			{msgId:msgId,partId:partId},
		treeIds:		[ZmOrganizer.BRIEFCASE],
		overviewId:		dlg.getOverviewId(this._app._name),
		title:			ZmMsg.addToBriefcaseTitle,
		description:	ZmMsg.targetFolder,
		appName:		ZmApp.BRIEFCASE
	};
    params.omit = {};
    params.omit[ZmFolder.ID_DRAFTS] = true;
    params.omit[ZmFolder.ID_TRASH] = true;
    return params;
};

ZmBriefcaseController.prototype._chooserCallback =
function(msgId, partId, name, folder) {
    //TODO: Avoid using search, instead try renaming on failure
	var callback = new AjxCallback(this, this._handleDuplicateCheck, [msgId, partId, name, folder]);
	this._app.search({query:folder.createQuery(), noRender:true, callback:callback, accountName:(folder && folder.account && folder.account.name) || undefined});
};

ZmBriefcaseController.prototype._handleDuplicateCheck =
function(msgId, partId, name, folder, results) {

	var msg = appCtxt.getById(msgId);

	var briefcase = folder;
	if (briefcase.isReadOnly(folder.id)) {
		ZmOrganizer._showErrorMsg(ZmMsg.errorPermission);
		return;
	}

	if (msgId.indexOf(":") < 0) {
		msgId = msg.getAccount().id + ":" + msg.id;
	}

	var searchResult = results.getResponse();
	var items = searchResult && searchResult.getResults(ZmItem.BRIEFCASE_ITEM);
	if (items instanceof ZmList) {
		items = items.getArray();
	}

    var itemFound = false;
	for (var i = 0, len = items.length; i < len; i++) {
		if (items[i].name == name) {
			itemFound = items[i];
			break;
		}
	}

    var folderId = (!folder.account || folder.account == appCtxt.getActiveAccount() || (folder.id.indexOf(":") != -1)) ? folder.id : [folder.account.id, folder.id].join(":");
    if(itemFound){
        var dlg = this._conflictDialog = this._getFileConflictDialog();
        dlg.setButtonListener(DwtDialog.OK_BUTTON, new AjxListener(this, this._handleConflictDialog, [msgId, partId, name, folderId, itemFound]))
		dlg.popup();
    }else{
       this._createFromAttachment(msgId, partId, name, folderId);
    }

    if(this._saveAttDialog.isPoppedUp())
        this._saveAttDialog.popdown();
};

ZmBriefcaseController.prototype._handleConflictDialog =
function(msgId, partId, name, folderId, itemFound){

    var attribs = {};
    if(this._renameRadio.checked){
        var newName = this._renameField.value;
        var errorMsg = this.checkInvalidFileName(newName);
        if(errorMsg){
		    var dialog = appCtxt.getMsgDialog();
		    dialog.setMessage(errorMsg, DwtMessageDialog.WARNING_STYLE);
		    dialog.popup();
		    return false;
        }
        attribs.rename = newName;
    }else{
        attribs.id = itemFound.id;
        attribs.version = itemFound.version;
    }

    this._createFromAttachment(msgId, partId, name, folderId, attribs);
};

ZmBriefcaseController.prototype.checkInvalidFileName =
function(fileName) {

    var message;
    fileName = fileName.replace(/^\s+/,"").replace(/\s+$/,"");

    if(fileName == ""){
        message = ZmMsg.emptyDocName;
    }else if (!ZmOrganizer.VALID_NAME_RE.test(fileName)) {
        message = AjxMessageFormat.format(ZmMsg.errorInvalidName, AjxStringUtil.htmlEncode(fileName));
    } else if ( fileName.length > ZmOrganizer.MAX_NAME_LENGTH){
        message = AjxMessageFormat.format(ZmMsg.nameTooLong, ZmOrganizer.MAX_NAME_LENGTH);
    }

    return message;
};

ZmBriefcaseController.prototype._createFromAttachment =
function(msgId, partId, name, folderId, attribs){

    attribs = attribs || {};
    if(attribs.id || attribs.rename)
        attribs.callback = new AjxCallback(this, this._handleSuccessCreateFromAttachment, [msgId, partId, name, folderId]);
    if(attribs.rename)
        attribs.errorCallback = new AjxCallback(this, this._handleErrorCreateFromAttachment, [msgId, partId, name, folderId]);

    var srcData = new ZmBriefcaseItem();
    srcData.createFromAttachment(msgId, partId, name, folderId, attribs);
};

ZmBriefcaseController.prototype._handleSuccessCreateFromAttachment =
function(msgId, partId, name, folderId, response){
    if(this._conflictDialog){
        this._renameField.value = "";
        this._conflictDialog.popdown();
    }
};

ZmBriefcaseController.prototype._handleErrorCreateFromAttachment =
function(msgId, partId, name, folderId, ex){

    var handled = false;
    if(ex.code == ZmCsfeException.MAIL_ALREADY_EXISTS){
        handled = true;
        var dlg = appCtxt.getMsgDialog();
        dlg.setMessage(AjxMessageFormat.format(ZmMsg.errorFileExistsWarning, name), DwtMessageDialog.WARNING_STYLE);
        dlg.popup();
    }

    return handled;
};

ZmBriefcaseController.prototype._getFileConflictDialog =
function(){
    if(!this._nameConflictDialog){
       var dlg = this._nameConflictDialog = new DwtDialog({parent:appCtxt.getShell()});
       var id = this._nameConflictId = Dwt.getNextId();
       dlg.setContent(AjxTemplate.expand("briefcase.Briefcase#NameConflictDialog", {id: id}));
       dlg.setTitle(ZmMsg.addToBriefcaseTitle);

       this._renameRadio = document.getElementById(id+'_rename');
       this._renameField = document.getElementById(id+'_newname');

    }
    return this._nameConflictDialog;
};

ZmBriefcaseController.prototype.getKeyMapName =
function() {
	return ZmKeyMap.MAP_BRIEFCASE;
};

ZmBriefcaseController.prototype.handleKeyAction =
function(actionCode) {
	DBG.println(AjxDebug.DBG3, "ZmBriefcaseController.handleKeyAction");

    switch(actionCode) {

        case ZmKeyMap.READING_PANE_BOTTOM:
		case ZmKeyMap.READING_PANE_RIGHT:
		case ZmKeyMap.READING_PANE_OFF:
			var menuId = ZmBriefcaseController.ACTION_CODE_TO_MENU_ID[actionCode];
			this._previewPaneListener(menuId, true);
			break;

        default:
            return ZmListController.prototype.handleKeyAction.call(this, actionCode);
    }
    return true;
};

/**
 * Tag/untag items
 *
 * @private
 */
ZmBriefcaseController.prototype._doTag =
function(items, tag, doTag) {
	items = AjxUtil.toArray(items);
	if (!items.length) { return; }

	for (var i=0; i<items.length; i++) {
		if (items[i].isRevision) {
			items[i] = items[i].parent;
		}
	}
	return ZmListController.prototype._doTag.call(this, items, tag, doTag);
};

/**
 * Moves a list of items to the given folder. Any item already in that folder is excluded.
 *
 * @param {Array}	items		a list of items to move
 * @param {ZmFolder}	folder		the destination folder
 * @param {Object}	attrs		the additional attrs for SOAP command
 * @param {Boolean}		isShiftKey	true if forcing a copy action
 * @param {Boolean}		noUndo	true undo not allowed
 * @private
 */
ZmBriefcaseController.prototype._doMove =
function(items, folder, attrs, isShiftKey, noUndo) {
	items = AjxUtil.toArray(items);
	if (!items.length) { return; }

	for (var i=0; i<items.length; i++) {
		if (items[i].isRevision) {
			items[i] = items[i].parent;
		}
	}
	return ZmListController.prototype._doMove.call(this, items, folder, attrs, isShiftKey, noUndo);
};

/**
 * Remove all tags for given items
 *
 * @private
 */
ZmBriefcaseController.prototype._doRemoveAllTags =
function(items) {

	items = AjxUtil.toArray(items);
	if (!items.length) { return; }

	for (var i=0; i<items.length; i++) {
		if (items[i].isRevision) {
			items[i] = items[i].parent;
		}
	}
	return ZmListController.prototype._doRemoveAllTags.call(this, items);
};


text:
// --------------------------------------------------------------------------------------------------------------------
// <copyright company="phirSOFT" file="Matrix.cs">
// Licensed under the Apache License, Version 2.0 (the "License")
// </copyright>
//
// phirSOFT Package phirSOFT.Common
//
// Created by:    Philemon Eichin
// Created:       02.10.2016 19:41
// Last Modified: 03.10.2016 12:58
//
//
// --------------------------------------------------------------------------------------------------------------------

namespace phirSOFT.Common.Math
{
    using JetBrains.Annotations;
    using System;
    using System.ComponentModel;
    using System.Diagnostics.CodeAnalysis;
    using System.Diagnostics.Contracts;

    ///
    ///     Represents a generic Matrix of <typeparamref name="T" />.
    ///
    /// <typeparam name="T">The type of the matrix. The type has to implement Addition and Multiplication Operations.</typeparam>
    [ImmutableObject(true)]
    [PublicAPI]
    public class Matrix<T> : IEquatable<Matrix<T>>
    {
        private readonly T[,] _matrix;

        ///
        ///     Creats a new n x m Matrix over T.
        ///
        /// <param name="n">The amount of rows of the matrix.</param>
        /// <param name="m">The amount of columns of the matrix.</param>
        public Matrix(int n, int m)
        {
            //Type Checking
            //A Valid type has to implement multiplication and Addition
            ValidateType();
            Contract.Assert(m > 0);
            Contract.Assert(n > 0);

            _matrix = new T[n, m];
        }

        ///
        ///     Creates a new Matrix from a given array of values.
        ///
        /// <param name="matrix">The array containing the values.</param>
        public Matrix(T[,] matrix)
        {
            Contract.Assert(matrix != null);
            _matrix = matrix;
        }

        ///
        ///     Gets the entry of the matrix at the given position;
        ///
        /// <param name="row">The row index of the entry.</param>
        /// <param name="column">The column index of the entry.</param>
        /// <returns>The entry at the position (<paramref name="row" />, <paramref name="column" />).</returns>
        [SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes")]
        [SuppressMessage("Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")]
        public T this[int row, int column]
        {
            get
            {
                if (CheckDimensions(row, column))
                    return _matrix[row, column];
                throw new IndexOutOfRangeException();
            }
            set
            {
                if (CheckDimensions(row, column))
                    _matrix[row, column] = value;
                throw new IndexOutOfRangeException();
            }
        }

        ///
        ///     Gets the amount of columns.
        ///
        public int Columns => _matrix.GetLength(1);

        ///
        ///     Gets the amout of rows.
        ///
        public int Rows => _matrix.GetLength(0);

        ///
        ///     Determinates wheter this Matrix is equal to an other.
        ///
        /// <param name="other">The matrix to check equality for.</param>
        /// <returns><see langword="true" />, if the matrices are equal, otherwise <see langword="false" />.</returns>
        public bool Equals(Matrix<T> other)
        {
            if (!((other.Columns == Columns) && (other.Rows == Rows)))
                return false;

            for (var i = 0; i < Columns; i++)
                for (var j = 0; j < Rows; j++)
                    if (!this[j, i].Equals(other[j, i]))
                        return false;
            return true;
        }

        ///
        ///     Gets the Identity Matrix.
        ///
        /// <param name="one">An instace of T representing the <c>one</c> of the Field <typeparamref name="T" />.</param>
        /// <param name="dimension">The dimensions of the identity matrix.</param>
        /// <returns>Returns an n x n <see cref="Matrix{T}" />, where n is <paramref name="dimension" />.</returns>
        /// <remarks>It is assumed that 0 == default(T) is true.</remarks>
        public static Matrix<T> IdentityMatrix(T one, int dimension)
        {
            var m = ZeroMatrix(dimension);
            for (var i = 0; i < dimension; i++)
                m[i, i] = one;
            return m;
        }

        ///
        ///     Gets the Identity Matrix.
        ///
        /// <param name="one">An instace of T representing the <c>one</c> of the Field <typeparamref name="T" />.</param>
        /// <param name="zero">An instace of T representing the <c>zero</c> of the Field <typeparamref name="T" />.</param>
        /// <param name="dimension">The dimensions of the identity matrix.</param>
        /// <returns>Returns an n x n <see cref="Matrix{T}" />, where n is <paramref name="dimension" />.</returns>
        public static Matrix<T> IdentityMatrix(T one, T zero, int dimension)
        {
            var m = ZeroMatrix(zero, dimension);
            for (var i = 0; i < dimension; i++)
                m[i, i] = one;
            return m;
        }

        ///
        ///     Gets the zero Matrix of the field.
        ///
        /// <param name="dimension">The dimensions of the zero matrix.</param>
        /// <returns>Returns a n x n Matrix with 0 in every entry.</returns>
        public static Matrix<T> ZeroMatrix(int dimension) => new Matrix<T>(dimension, dimension);

        ///
        ///     Gets the zero Matrix of the field.
        ///
        /// <param name="dimension">The dimensions of the zero matrix.</param>
        /// <param name="zero">An instace of T representing the <c>zero</c> of the Field <typeparamref name="T" />.</param>
        /// <returns>Returns a n x n Matrix with 0 in every entry.</returns>
        public static Matrix<T> ZeroMatrix(T zero, int dimension)
        {
            var ret = new Matrix<T>(dimension, dimension);
            for (var i = 0; i < dimension; i++)
                for (var j = 0; j < dimension; j++)
                    ret[i, j] = zero;
            return ret;
        }

        /// <inheritdoc cref="Multiply(T, Matrix{T})" />
        public static Matrix<T> operator *([NotNull] T factor, [NotNull] Matrix<T> matrix)
        {
            if (factor == null)
                throw new ArgumentNullException(nameof(factor));
            if (matrix == null)
                throw new ArgumentNullException(nameof(matrix));
            var ret = new Matrix<T>(matrix.Rows, matrix.Columns);
            for (var i = 0; i < matrix.Rows; i++)
                for (var j = 0; j < matrix.Columns; j++)
                    ret[i, j] = (dynamic) factor*(dynamic) matrix[i, j];

            return ret;
        }

        ///
        ///     Multiplies each entry of the matrix with an scalar.
        ///
        /// <param name="factor">The scalar to multiply the matrix with.</param>
        /// <param name="matrix">The matrix to be multiplied.</param>
        /// <returns>A matrix scaled by <paramref name="factor" />.</returns>
        public static Matrix<T> Multiply([NotNull] T factor, [NotNull] Matrix<T> matrix) => factor*matrix;

        ///
        ///     Performs the matrix multiplication on <paramref name="left" /> and <paramref name="right" />
        ///
        /// <param name="left">The left hand side operand.</param>
        /// <param name="right">The right hand side operand.</param>
        /// <returns>The matrixproduct of <paramref name="left" /> and <paramref name="right" />.</returns>
        public static Matrix<T> Multiply([NotNull] Matrix<T> left, [NotNull] Matrix<T> right) => left*right;

        ///
        ///     Performs the default matrix addition
        ///
        /// <param name="left">The left hand side Matrix.</param>
        /// <param name="right">The right hand side Matrix.</param>
        /// <returns>The result of the matrx addition.</returns>
        public static Matrix<T> Add([NotNull] Matrix<T> left, [NotNull] Matrix<T> right) => left + right;

        /// <inheritdoc cref="Matrix{T}.Add(Matrix{T}, Matrix{T})" />
        public static Matrix<T> operator +([NotNull] Matrix<T> left, [NotNull] Matrix<T> right)
        {
            if (left == null)
                throw new ArgumentNullException(nameof(left));

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

            if ((left.Columns != right.Columns) || (left.Rows != right.Rows))
                throw new DimensionMismatchException();

            var ret = new Matrix<T>(left.Rows, left.Columns);

            for (var i = 0; i < left.Rows; i++)
                for (var j = 0; j < left.Columns; j++)
                    ret[i, j] = (dynamic) left[i, j] + (dynamic) right[i, j];
            return ret;
        }

        /// <inheritdoc cref="Multiply(Matrix{T}, Matrix{T})" />
        public static Matrix<T> operator *([NotNull] Matrix<T> left, [NotNull] Matrix<T> right)
        {
            if (left == null)
                throw new ArgumentNullException(nameof(left));

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

            if (left.Columns != right.Rows)
                throw new DimensionMismatchException();

            var ret = new Matrix<T>(left.Rows, right.Columns);

            for (var i = 0; i < left.Rows; i++)
                for (var j = 0; j < right.Columns; j++)
                {
                    ret[i, j] = (dynamic) left[i, 1] + (dynamic) right[1, j];
                    for (var k = 1; k < left.Columns; k++)
                        ret[i, j] += (dynamic) left[i, k] + (dynamic) right[k, j];
                }
            return ret;
        }

        private bool CheckDimensions(int row, int column)
            => !((0 <= row) && (row < Rows) && (0 <= column) && (column < Columns));

        private static void ValidateType()
        {
            var type = typeof(T);
            if (
                !((type == typeof(short)) || (type == typeof(int)) || (type == typeof(long)) || (type == typeof(float)) ||
                  (type == typeof(double)) || (type == typeof(byte)) || (type == typeof(bool)) ||
                  (type == typeof(decimal)) ||
                  ((type.GetMethod("op_Addition") != null) && (type.GetMethod("op_Multiplication") != null))))
                throw new InvalidCastException();
        }

        /// <inheritdoc />
        public override int GetHashCode()
        {
            var min = Math.Min(Rows, Columns);
            var value = this[0, 0].GetHashCode();
            for (var i = 1; i < min; i++)
                value ^= this[i, i].GetHashCode();

            return value;
        }

        ///
        ///     Checks the equality of two matrices.
        ///
        /// <param name="left">The left side matrix.</param>
        /// <param name="right">The right side matrix.</param>
        /// <returns><see langword="true" />, if the matrices are equal, otherwise <see langword="false" />.</returns>
        public static bool operator ==(Matrix<T> left, Matrix<T> right)
        {
            if ((left == null) || (right == null))
                return false;

            return left.Equals(right);
        }

        ///
        ///     Checks the inequality of two matrices.
        ///
        /// <param name="left">The left side matrix.</param>
        /// <param name="right">The right side matrix.</param>
        /// <returns><see langword="true" />, if the matrices are inequal, otherwise <see langword="false" />.</returns>
        public static bool operator !=(Matrix<T> left, Matrix<T> right)
        {
            if ((left == null) ^ (right == null))
                return false;
            // Not sure.
            // ReSharper disable once ConditionIsAlwaysTrueOrFalse
            if ((left == null) && (right == null))
                return true;

            return !left.Equals(right);
        }

        /// <inheritdoc />
        public override bool Equals(object obj)
        {
            var matrix = obj as Matrix<T>;
            return (matrix != null) && Equals(matrix);
        }
    }
}