text:
MIME-Version: 1.0
Server: CERN/3.0
Date: Monday, 16-Dec-96 21:45:06 GMT
Content-Type: text/html
Content-Length: 23607
Last-Modified: Tuesday, 19-Nov-96 20:35:33 GMT

<TITLE>Abstracts of the Horus Papers</TITLE>

<!WA0><!WA0><!WA0><!WA0><!WA0><!WA0><!WA0><!WA0><!WA0><!WA0><!WA0><!WA0><!WA0><!WA0><!WA0><!WA0><!WA0><!WA0><!WA0><!WA0>

<!WA1><!WA1><!WA1><!WA1><!WA1><!WA1><!WA1><!WA1><!WA1><!WA1><!WA1><!WA1><!WA1><!WA1><!WA1><!WA1><!WA1><!WA1><!WA1><!WA1><!WA2><!WA2><!WA2><!WA2><!WA2><!WA2><!WA2><!WA2><!WA2><!WA2><!WA2><!WA2><!WA2><!WA2><!WA2><!WA2><!WA2><!WA2><!WA2><!WA2>

<!WA3><!WA3><!WA3><!WA3><!WA3><!WA3><!WA3><!WA3><!WA3><!WA3><!WA3><!WA3><!WA3><!WA3><!WA3><!WA3><!WA3><!WA3><!WA3><!WA3><!WA4><!WA4><!WA4><!WA4><!WA4><!WA4><!WA4><!WA4><!WA4><!WA4><!WA4><!WA4><!WA4><!WA4><!WA4><!WA4><!WA4><!WA4><!WA4><!WA4>

<!WA5><!WA5><!WA5><!WA5><!WA5><!WA5><!WA5><!WA5><!WA5><!WA5><!WA5><!WA5><!WA5><!WA5><!WA5><!WA5><!WA5><!WA5><!WA5><!WA5><!WA6><!WA6><!WA6><!WA6><!WA6><!WA6><!WA6><!WA6><!WA6><!WA6><!WA6><!WA6><!WA6><!WA6><!WA6><!WA6><!WA6><!WA6><!WA6><!WA6>

<!WA7><!WA7><!WA7><!WA7><!WA7><!WA7><!WA7><!WA7><!WA7><!WA7><!WA7><!WA7><!WA7><!WA7><!WA7><!WA7><!WA7><!WA7><!WA7><!WA7><!WA8><!WA8><!WA8><!WA8><!WA8><!WA8><!WA8><!WA8><!WA8><!WA8><!WA8><!WA8><!WA8><!WA8><!WA8><!WA8><!WA8><!WA8><!WA8><!WA8>

<!WA9><!WA9><!WA9><!WA9><!WA9><!WA9><!WA9><!WA9><!WA9><!WA9><!WA9><!WA9><!WA9><!WA9><!WA9><!WA9><!WA9><!WA9><!WA9><!WA9><!WA10><!WA10><!WA10><!WA10><!WA10><!WA10><!WA10><!WA10><!WA10><!WA10><!WA10><!WA10><!WA10><!WA10><!WA10><!WA10><!WA10><!WA10><!WA10><!WA10>

<!WA11><!WA11><!WA11><!WA11><!WA11><!WA11><!WA11><!WA11><!WA11><!WA11><!WA11><!WA11><!WA11><!WA11><!WA11><!WA11><!WA11><!WA11><!WA11><!WA11><!WA12><!WA12><!WA12><!WA12><!WA12><!WA12><!WA12><!WA12><!WA12><!WA12><!WA12><!WA12><!WA12><!WA12><!WA12><!WA12><!WA12><!WA12><!WA12><!WA12>

<!WA13><!WA13><!WA13><!WA13><!WA13><!WA13><!WA13><!WA13><!WA13><!WA13><!WA13><!WA13><!WA13><!WA13><!WA13><!WA13><!WA13><!WA13><!WA13><!WA13>

<!WA14><!WA14><!WA14><!WA14><!WA14><!WA14><!WA14><!WA14><!WA14><!WA14><!WA14><!WA14><!WA14><!WA14><!WA14><!WA14><!WA14><!WA14><!WA14><!WA14>

<!WA15><!WA15><!WA15><!WA15><!WA15><!WA15><!WA15><!WA15><!WA15><!WA15><!WA15><!WA15><!WA15><!WA15><!WA15><!WA15><!WA15><!WA15><!WA15><!WA15>

<!WA16><!WA16><!WA16><!WA16><!WA16><!WA16><!WA16><!WA16><!WA16><!WA16><!WA16><!WA16><!WA16><!WA16><!WA16><!WA16><!WA16><!WA16><!WA16><!WA16>

<!WA17><!WA17><!WA17><!WA17><!WA17><!WA17><!WA17><!WA17><!WA17><!WA17><!WA17><!WA17><!WA17><!WA17><!WA17><!WA17><!WA17><!WA17><!WA17><!WA17>

<!WA18><!WA18><!WA18><!WA18><!WA18><!WA18><!WA18><!WA18><!WA18><!WA18><!WA18><!WA18><!WA18><!WA18><!WA18><!WA18><!WA18><!WA18><!WA18><!WA18>

<!WA19><!WA19><!WA19><!WA19><!WA19><!WA19><!WA19><!WA19><!WA19><!WA19><!WA19><!WA19><!WA19><!WA19><!WA19><!WA19><!WA19><!WA19><!WA19><!WA19><!WA20><!WA20><!WA20><!WA20><!WA20><!WA20><!WA20><!WA20><!WA20><!WA20><!WA20><!WA20><!WA20><!WA20><!WA20><!WA20><!WA20><!WA20><!WA20><!WA20>

<!WA21><!WA21><!WA21><!WA21><!WA21><!WA21><!WA21><!WA21><!WA21><!WA21><!WA21><!WA21><!WA21><!WA21><!WA21><!WA21><!WA21><!WA21><!WA21><!WA21>

Abstracts

Software for Reliable Networks

Kenneth P. Birman and Robbert van Renesse

Scientific American, May, 1996

The failure of a single program on a single computer can sometimes crash a
network of intercommunicating machines, causing havoc for stock exchanges,
telephone systems, air-traffic control and other operations. Two software
designers explain what can be done to make networks more robust.

Horus, a flexible Group Communication System

Robbert van Renesse, Kenneth P. Birman and Silvano Maffeis

Communications of the ACM, April 1996.

The emergence of process-group environments for distributed computing
represents a promising step towards
robustness for mission-critical distributed applications.
Process groups have a ``natural'' correspondence with data or services
that have been replicated
for availability, or as part of a coherent cache.
They can been used to support highly available security
domains. And, group mechanisms fit well with an emerging generation of
intelligent network and collaborative work applications.

Masking the Overhead of Protocol Layering

Robbert van Renesse

Proceedings of the 1996 ACM SIGCOMM Conference

Stanford, September 1996

Layering of protocols has been advocated as a way of dealing with the
complexity of computer communication.
It has also been criticized for its performance overhead.
In this paper, we present some insights in the design of protocols, and
how these insights can be used to mask the overhead of layering, in a
way similar to client caching in a file system.
With our techniques, we achieve an order of magnitude improvement in
end-to-end message latency in the Horus communication framework.
Over an ATM network, we are able to send and deliver messages of varying
levels of semantics in about 85 microseconds, using a protocol stack of
four layers that were written in ML, a high-level functional language.

World Wide Failures

Werner Vogels

Proceedings of the ACM SIGOPS European Workshop, Connamoran, Ireland,
September 1996

The one issue that unites almost all approaches to distributed computing
is the need to know whether certain components in the system have failed or
are otherwise unavailable. When designing and building systems that
will need to function at a global scale, failure management will need to
be considered a fundamental building block. This paper describes the
development of a system-independent failure management servcies, which allows
systems and applications to incorporate accurate detection of failed
processes, nodes and networks without the need for making compromises in their
particular design.

A Framework for Protocol Composition in Horus

Robbert van Renesse, Kenneth P. Birman, Roy Friedman,

Mark Hayden, and David A. Karr

August 1995

The Horus system supports a communication architecture that treats
protocols as instances of an abstract data type.
This approach encourages developers to
partition complex protocols into simple microprotocols, each of which
is implemented by a protocol layer.
Protocol layers can be stacked on top of each
other in a variety of ways, at run-time.
First, we describe the classes of protocols that can be supported this way.
Next, we present the Horus object model that we designed for
this technology, and the interface between the layers that makes it all
work.  We then present an example layer that implements a group
membership protocol.  Next, we show how, given a set of required properties,
an appropriate stack can be constructed.  We look at an example stack of
protocols, which provides fault-tolerant, totally ordered communication
between a group of processes.
The work contributes a standard framework for protocol development and
experimentation, provides a high performance implementation of the
virtual synchrony model, and introduces a methodology for increasing the
robustness of the protocol development process.

Trading Consistency for Availability in Distributed Systems

Roy Friedman and  Ken Birman

TR96-1579

April 8, 1996

This paper shows that two important classes of actions, non left commuting
and strongly non commuting, cannot be executed by concurrent partitions in
a system that provides serializable services. This result indicates that
there is an inherent limitation to the ability of systems to provide services
in a consistent manner during network partitions.

Deciding in Partitionable Networks

Roy Friedman,  Idit Keidar,  Dalia Malki,  Ken Birman and  Danny Dolev

TR95-1554

November 27, 1995

Motivated by Chandra and Toueg's work, we study decision protocols in a
model that closely approximates ``real'' distributed systems. Our results
show how the weakest failure detector and associated consensus algorithm
can be adapted to a network in which omission failures can occur during
periods when processes suspect one-another as faulty. For protocols in
which a majority subset of the participants can reach decisions on behalf
of the system as a whole, we also characterize a series of stages that
necessarily arise during execution. Jointly, these findings establish a
direct relationship between an extended version of the three-phase commit
protocol, which makes progress even when a traditional three-phase commit
would block, and the consensus protocol of Chandra and Toueg. Although we
do not explore the linkage here, our results should also be applicable to
other agreement protocols for systems of this sort, such as leader election
and dynamic group membership.

Strong and Weak Virtual Synchrony in Horus

 Roy Friedman and  Robbert van Renesse

 August 24, 1995

  A formal definition of {\em strong virtual synchrony}, capturing the
  semantics of virtual synchrony as implemented in Horus, is
  presented. This definition has the nice property that every message
  is delivered within the view in which it was sent. However, it is
  shown that in order to implement strong virtual synchrony, the
  application program has to block messages during view changes. An
  alternative definition, called {\em weak virtual synchrony}, which
  can be implemented without blocking messages, is then presented.
  This definition still guarantees that messages will be delivered
  within the view in which they were sent, only that it uses a
  slightly weaker notion of what the view in which a message was sent
  is. An implementation of weak virtual synchrony that does not block
  messages during view changes is developed, and it is shown how to
  use a system that provides weak virtual synchrony even when strong
  virtual synchrony is actually needed. To capture additional ordering
  requirements, the definition of {\em ordered virtual synchrony} is
  presented. Finally, it is discussed how to extend the definitions in
  order to cope with the fact that a process can become a member of
  more than one group.

Packing Messages as a Tool for Boosting the
Performance of Total Ordering Protocols

 Roy Friedman and  Robbert van Renesse

 July 07, 1995

  This paper compares the throughput and latency of four protocols
  that provide total ordering. Two of these protocols are measured
  with and without message packing. We used a technique that buffers
  application messages for a short period of time before sending them,
  so more messages are packed together. The main conclusion of this
  comparison is that message packing influences the performance of
  total ordering protocols under high load overwhelmingly more than
  any other optimization that was checked in this paper, both in terms
  of throughput and latency. This improved performance is attributed
  to the fact that packing messages reduces the header overhead for
  messages, the contention on the network, and the load on the
  receiving CPUs.

Using Virtual Synchrony to Develop Efficient Fault Tolerant
Distributed Shared Memories

 Roy Friedman

 March 31, 1995

  This paper shows how to define consistency conditions for
  distributed shared memories in virtually synchronous environments.
  Such definitions allow to develop fault tolerant implementations of
  distributed shared memories, in which during normal execution,
  operations can be performed very efficiently, and only those
  operations which take place during a configuration change must be
  delayed. Three well known consistency conditions, namely,
  linearizability, sequential consistency, and causal memory, are
  redefined for virtually synchronous environments. It is then shown
  how to provide efficient fault tolerant implementations for these
  definitions.

Protocol Composition in Horus

 Robbert Van Renesse and  Kenneth P. Birman

March 29, 1995

 Horus is a communication architecture that treats a protocol as an
 abstract data type. Protocol layers can be stacked on top of each
 other in a variety of ways, at run-time. This paper starts out with
 describing the many classes of protocols that can be supported this
 way. Next, we describe the Horus object model that we designed for
 this technology, and the interface between the layers that makes it
 all work. We then present an example layer which implements a group
 membership protocol. Then, we look at a example stack of protocols,
 which provides fault-tolerant, totally ordered communication between a
 group of processes. We conclude with presenting some remaining
 challenges in our project.

Horus: A Flexible Group Communications System

Robbert Van Renesse,  Kenneth P. Birman,  Bradford B. Glade,  Katie
Guo,  Mark Hayden,  Takako Hickey,  Dalia Malki,  Alex Vaysburd and
Werner Vogels

March 23, 1995

The Horus system offers flexible group communication support for
distributed applications. It is extensively layered and highly
reconfigurable, allowing applications to only pay for services they
use, and for groups with different communication needs to coexist in a
single system. The approach encourages experimentation with new
communication properties and incremental extension of the system, and
enables us to support a variety of application-oriented interfaces.

Achieving Critical Reliability With Unreliable Components and
Unreliable Glue

 Mark Hayden and  Kenneth P. Birman

 March 14, 1995

  Even the most aggressive quality assurance procedures yield at best
  probabilistic confidence in the reliability of complex systems.
  Distributed systems, because of their large numbers of components,
  are enormously complex engineering artifacts, and hence may appear
  to be inherently unreliable -- despite the best efforts of
  researchers and developers. A cellular distributed systems
  architecture offers the hope of drastically improving the
  reliability of current technologies in settings where reliability is
  critical. The approach combines a stateful style of distributed
  computing within cells with a loosely coupled probabilistic
  inter-cell computing model based on a probabilistic broadcast
  primitive. We give an implementation of this primitive, called
  pbcast, and demonstrate how to use it to implement this methodology.
  Our approach is compatible with the use of popular distributed
  computing and reliability technologies, while offering considerable
  isolation against the spread of failures among cells.

Preserving Privacy in a Network of Mobile Computers

 David A. Cooper and  Kenneth P. Birman

 March 03, 1995

  Even as wireless networks create the potential for access to information
  from mobile platforms, they pose a problem for privacy. In order to
  retrieve messages, users must periodically poll the network. The
  information that the user must give to the network could potentially be
  used to track that user. However, the movements of the user can also be
  used to hide the user's location if the protocols for sending and
  retrieving messages are carefully designed. We have developed a
  replicated memory service which allows users to read from memory without
  revealing which memory locations they are reading. Unlike previous
  protocols, our protocol is efficient in its use of computation and
  bandwidth. In this paper, we will show how this protocol can be used
  in conjunction with existing privacy preserving protocols to allow a
  user of a mobile computer to maintain privacy despite active attacks.

Incorporating System Resource Information into Flow Control

 Takako M. Hickey and  Robbert Van Renesse

February 27, 1995

 Upcall-based distributed systems have become widespread in recent
 years. While upcall-based systems provide some obvious advantages,
 experiences with these systems have exposed unanticipated problems of
 unpredictability and inefficiency. Incorporating system resources
 information into flow control is essential in solving these problems.
 Variants of window-based flow control suitable for distributed systems
 are investigated. Next, message packing, which improves network
 bandwidth usage efficiency, and, consequently, message throughput, is
 presented. Finally, a back pressure mechanism which controls admission
 of messages into the system by blocking applications at high load is
 presented. The combination of the window mechanism and the back
 pressure mechanism provides end-to-end management of system resources.
 The former manages network resources, while the latter manages
 operating system resources. The combination maintains good throughput
 even under high load.

Design and Performance of Horus:
A Lightweight Group Communications System

Robbert van Renesse, Takako M. Hickey, and Kenneth P. Birman

december 1994

The Horus project seeks to develop a communication system addressing
the requirements of a wide variety of distributed applications.
Horus implements the group communications model providing
(among others)
unreliable or reliable FIFO, causal, or total group multicasts.
It is extensively layered and highly reconfigurable allowing
applications to only pay for services they use.
This architecture enables groups with different
communication needs to coexist in a single system.
The approach permits experimentation with new communication
properties and incremental extension of the system, and enables
us to support a variety of application-oriented interfaces.
Our initial experiments show good performance.

Support for Complex Multi-Media Applications using the Horus system.

Werner Vogels and Robbert van Renesse

December 1994.

A distributed multi-media application involves more than just protocols
for the dissemination of video and audio data. As in any other
distributed application, protocols are necessary that guarantee the
 consistency, fault-tolerance, and security of shared data objects. The
Horus system offers a framework for buildin g complex distributed
systems that involve any number of protocols, as well as a variety of
protocols for the diffe rent aspects of a distributed application
(including some protocols specific to multi-media applications). We
believe that
 this integrated approach is superior to combining different toolkits,
and illustrate this with a detailed example of an existing
video-on-demand application.

A Security Architecture for Fault-Tolerant Systems

 Michael K. Reiter,  Kenneth P. Birman and  Robbert Van Renesse

June 1993

 Process groups are a common abstraction for fault-tolerant computing
 in distributed systems. We present a security architecture that
 extends the process group into a security abstraction. Integral parts
 of this architecture are services that securely and fault-tolerantly
 support cryptographic key distribution using novel techniques. We
 detail the design and implementation of these services and the secure
 process group abstraction they support. We also give performance
 figures for some common group operations.

Preserving Privacy in a Network of Mobile Computers

 David A. Cooper and  Kenneth P. Birman

 October 26, 1994

  Even as wireless networks create the potential for access to
  information from mobile platforms, they pose a problem for privacy.
  In order to retrieve messages, users must periodically poll the
  network. The information that the user must give to the network
  could potentially be used to track that user. However, the movements
  of the user can also be used to hide the user's location if the
  protocols for sending and retrieving messages are carefully
  designed. In this paper we will describe a set of protocols that we
  have developed to allow a user with a mobile computer to communicate
  without compromising privacy.

Uniform Actions in Asynchronous Distributed Systems

 Dalia Malki,  Kenneth P. Birman,  Aleta M. Ricciardi and  Andre
 Schiper

 September 08, 1994

  We develop necessary conditions for the development of asynchronous
  distributed software that will perform {\em uniform} actions (events
  that if performed by any process, must be performed at all
  processes). The paper focuses on {\em dynamic uniformity}, which
  differs from the classical problems in that processes continually
  leave and join the ongoing computation. Here, we first treat a
  static version of the problem (lacking joins), and then extend the
  results so obtained to also include joins. Our results demonstrate
  that in contrast to Consensus, which cannot be solved in
  asynchronous systems with even a single faulty process, dynamic
  uniformity can be solved using a failure detection mechanism that
  makes bounded numbers of mistakes. Because dynamic uniformity arises
  in systems that maintain safety within a ``primary partition'' of a
  network, our paper provides a rigorous characterization of the
  framework upon which several existing distributed programming
  environments are based.

Understanding Partitions and the ``No Partition'' Assumption

 Aleta M. Ricciardi,  Andre Schiper and  Kenneth P. Birman

 June 1993

  The paper discusses partitions in asynchronous message-passing
  systems. In such systems slow processes and slow links can lead to
  virtual partitions that are indistinguishable from real ones. This
  raises the following question: what is a ``partition'' in an
  asynchronous system? To overcome the impossibility of detecting
  crashed processes in an asynchronous system, our system model
  incorporates a failure suspector to detect (possibly erroneously)
  process failures. Based on failure suspicions we give a definition
  of partitions that acccounts for real partitions as well as virtual
  ones. We show that under certain assumptions about the process
  behavior, any incorrect failure suspicion inevitably partitions the
  system. We then show how to interpret the ``absence of partition''
  assumption.

Virtually-Synchronous Communication Based on a Weak Failure
Suspector</

 Andre Schiper and  Aleta M. Ricciardi

 April 1993

  Failure detectors (or, more accurately, Failure Suspectors - FS)
  appear to be a fundamental service upon which to build
  fault-tolerant, distributed applications. This paper shows that a FS
  with very weak semantics (i.e. that delivers failure and recovery
  information in no specific order) suffices to implement
  virtually-synchronous communication (VSC) in an asynchronous system
  subject to process crash failures and network partitions. The VSC
  paradigm is particularly useful in asynchronous systems and greatly
  simplifies building fault-tolerant applications that mask failures
  by replicating processes. We suggest a three-component architecture
  to implement virtually-synchronous communication : 1) at the lowest
  level, the FS component; on top of it, 2a) a component that defines
  new views, and 2b) a component that reliably multicasts messages
  within a view. The issues covered in this paper also lead to a
  better understanding of the various membership service semantics
  proposed in recent literature.

Process Membership in Asynchronous Environments

 Aleta M. Ricciardi and  Kenneth P. Birman

 February 1993

  The development of reliable distributed software is simplified by
  the ability to assume a fail-stop failure model. We discuss the
  emulation of such a model in an asynchronous distributed
  environment. The solution we propose, called Strong-GMP, can be
  supported through a highly efficient protocol, and has been
  implemented as part of a distributed systems software project at
  Cornell University. Here, we focus on the precise definition of the
  problem, the protocol, correctness proofs and an analysis of costs.
  Keywords: Asynchronous computation; Fault detection; Process
  membership; Fault tolerance; Process group.

Comments to
<!WA22><!WA22><!WA22><!WA22><!WA22><!WA22><!WA22><!WA22><!WA22><!WA22><!WA22><!WA22><!WA22><!WA22><!WA22><!WA22><!WA22><!WA22><!WA22><!WA22>Werner Vogels


text:
require 'rack'
require 'volt/server/rack/keep_alive'
require 'volt/server/rack/quiet_common_logger'
require 'volt/server/rack/opal_files'
require 'volt/server/rack/index_files'
require 'volt/server/rack/http_resource'
require 'volt/server/rack/sprockets_helpers_setup'

module Volt
  class DefaultMiddlewareStack
    # Setup on the middleware we can setup before booting components
    def self.preboot_setup(volt_app, rack_app)
      # Should only be used in production
      if Volt.config.deflate
        rack_app.use Rack::Deflater
        rack_app.use Rack::Chunked
      end

      rack_app.use Rack::ContentLength
      rack_app.use Rack::KeepAlive
      rack_app.use Rack::ConditionalGet
      rack_app.use Rack::ETag

      rack_app.use Rack::Session::Cookie, {
        key: 'rack.session',
        # domain: 'localhost.com',
        path: '/',
        expire_after: 2592000,
        secret: Volt.config.app_secret
      }

      rack_app.use QuietCommonLogger
      if Volt.env.development? || Volt.env.test?
        rack_app.use Rack::ShowExceptions
      end
    end

    # Setup the middleware that we need to wait for components to boot before we
    # can set them up.
    def self.postboot_setup(volt_app, rack_app)
      # Serve the opal files
      opal_files = OpalFiles.new(rack_app, volt_app.app_url, volt_app.app_path, volt_app.component_paths)
      volt_app.opal_files = opal_files
      volt_app.sprockets = opal_files.environment

      Volt::SprocketsHelpersSetup.new(volt_app)

      # Serve the main html files from public, also figure out
      # which JS/CSS files to serve.
      rack_app.use IndexFiles, volt_app, volt_app.component_paths, opal_files

      rack_app.use HttpResource, volt_app, volt_app.router

      # serve assets from public
      rack_app.use Rack::Static,
                    urls: [''],
                    root: 'public',
                    index: 'index.html',
                    header_rules: [
                      [:all, { 'Cache-Control' => 'public, max-age=86400' }]
                    ]

      rack_app.run lambda { |env| [404, { 'Content-Type' => 'text/html; charset=utf-8' }, ['404 - page not found']] }
    end
  end
end

redpajama_set_name: RedPajamaGithub


text:
package com.yammer.dropwizard.auth.tests;

import com.google.common.base.Optional;
import com.google.common.cache.CacheBuilderSpec;
import com.google.common.cache.CacheStats;
import com.google.common.collect.ImmutableSet;
import com.yammer.dropwizard.auth.Authenticator;
import com.yammer.dropwizard.auth.CachingAuthenticator;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InOrder;

import static org.fest.assertions.api.Assertions.assertThat;
import static org.mockito.Mockito.*;

public class CachingAuthenticatorTest {
    @SuppressWarnings("unchecked")
    private final Authenticator<String, String> underlying = mock(Authenticator.class);

    private final CachingAuthenticator<String, String> cached =
            CachingAuthenticator.wrap(underlying, CacheBuilderSpec.parse("maximumSize=1"));

    @Before
    public void setUp() throws Exception {
        when(underlying.authenticate(anyString())).thenReturn(Optional.of("principal"));
    }

    @Test
    public void cachesTheFirstReturnedPrincipal() throws Exception {
        assertThat(cached.authenticate("credentials"))
                .isEqualTo(Optional.of("principal"));

        assertThat(cached.authenticate("credentials"))
                .isEqualTo(Optional.of("principal"));

        verify(underlying, times(1)).authenticate("credentials");
    }

    @Test
    public void respectsTheCacheConfiguration() throws Exception {
        cached.authenticate("credentials1");
        cached.authenticate("credentials2");
        cached.authenticate("credentials1");

        final InOrder inOrder = inOrder(underlying);
        inOrder.verify(underlying, times(1)).authenticate("credentials1");
        inOrder.verify(underlying, times(1)).authenticate("credentials2");
        inOrder.verify(underlying, times(1)).authenticate("credentials1");
    }

    @Test
    public void invalidatesSingleCredentials() throws Exception {
        cached.authenticate("credentials");
        cached.invalidate("credentials");
        cached.authenticate("credentials");

        verify(underlying, times(2)).authenticate("credentials");
    }

    @Test
    public void invalidatesSetsOfCredentials() throws Exception {
        cached.authenticate("credentials");
        cached.invalidateAll(ImmutableSet.of("credentials"));
        cached.authenticate("credentials");

        verify(underlying, times(2)).authenticate("credentials");
    }

    @Test
    public void invalidatesAllCredentials() throws Exception {
        cached.authenticate("credentials");
        cached.invalidateAll();
        cached.authenticate("credentials");

        verify(underlying, times(2)).authenticate("credentials");
    }

    @Test
    public void calculatesTheSizeOfTheCache() throws Exception {
        cached.authenticate("credentials1");

        assertThat(cached.size())
                .isEqualTo(1);
    }

    @Test
    public void calculatesCacheStats() throws Exception {
        cached.authenticate("credentials1");

        final CacheStats stats = cached.stats();

        assertThat(stats.loadCount())
                .isEqualTo(1);
    }
}


text:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

/*=============================================================================
**
** Source: test1.c (modf)
**
** Purpose: Test to ensure that modf return the correct values
**
** Dependencies: PAL_Initialize
**               PAL_Terminate
**				 Fail
**               fabs
**

**
**===========================================================================*/

#include <palsuite.h>

#define DELTA 0.0000001 //Error acceptance level to the 7th decimal

/**
 * Helper test structure
 */
struct test
{
    double value;   // fmodf param 1
    double result1; // expected result (fractional portion)
    double result2; // expected result (integer portion)
};

/**
 * main
 *
 * executable entry point
 */
INT __cdecl main(INT argc, CHAR **argv)
{
    INT i;

    struct test tests[] =
    {
      // param 1   fractional   integer
        { 3,        0,          3  },
        { -10,      0,         -10 },
        { 1.1234,   0.1234,     1 },
        { -1.1234,  -0.1234,    -1 },
        { 1.7e308,  0,          1.7e308 },
        { -1.7e308, 0,         -1.7e308 },
        { 1.7e-30,  1.7e-30,    0 },
        { 0,        0,          0 }
    };

    // PAL initialization
    if( PAL_Initialize(argc, argv) != 0 )
    {
	    return FAIL;
    }

    for( i = 0; i < sizeof(tests) / sizeof(struct test); i++ )
    {
        double fractionalResult;
        double integerResult;
        double testDelta;

        fractionalResult = modf( tests[i].value, &integerResult );

        // The test is valid when the difference between the
        // result and the expectation is less than DELTA

        testDelta = fabs( fractionalResult - tests[i].result1 );

        if( (testDelta >= DELTA) ||
            (integerResult != tests[i].result2) )

        {
            Fail( "ERROR: "
                  "modf(%f) returned "
                  "fraction=%20.20f and integer=%20.20f "
                  "when it should have returned "
                  "fraction=%20.20f and integer=%20.20f ",
                  tests[i].value,
                  fractionalResult,
                  integerResult,
                  tests[i].result1,
                  tests[i].result2 );
        }
    }

    PAL_Terminate();
    return PASS;
}


text:
Using SdFat-beta and Arduino.cc libs the patch improves card read speed
from 109KB/s to 129KB/s.

Source:

  https://forum.arduino.cc/index.php?topic=358160.30

I copied the SERCOM and SPI files over the originals that are part of the
SAMD board library. To find the originals:

find ~/Library/Arduino15 -name SERCOM.cpp
find ~/Library/Arduino15 -name SPI.cpp

If you break things, use the Arduino.cc IDE board manager to uninstall
the Arduino Zero then install it again.

I did not try the Sd2Card patches as those are for the 2009 version of SdFat
that is wrapped by the Arduino SD library. May try them at some point.


text:
// Type: Highsoft.Web.Mvc.Stocks.FlagsSeries

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;

namespace Highsoft.Web.Mvc.Stocks
{
    public class FlagsSeries : Series
    {
        public FlagsSeries()
        {
            bool? nullable1 = new bool?(false);
            this.AllowPointSelect_DefaultValue = nullable1;
            this.AllowPointSelect = nullable1;
            double? nullable2 = new double?();
            this.AnimationLimit_DefaultValue = nullable2;
            this.AnimationLimit = nullable2;
            this.ClassName = this.ClassName_DefaultValue = "";
            this.Color = this.Color_DefaultValue = (string) null;
            double? nullable3 = new double?();
            this.ColorIndex_DefaultValue = nullable3;
            this.ColorIndex = nullable3;
            this.Colors = this.Colors_DefaultValue = new List<string>();
            this.CompareBase = this.CompareBase_DefaultValue = FlagsSeriesCompareBase.Min;
            nullable3 = new double?(50.0);
            this.CropThreshold_DefaultValue = nullable3;
            this.CropThreshold = nullable3;
            this.Cursor = this.Cursor_DefaultValue = FlagsSeriesCursor.Null;
            this.Data = this.Data_DefaultValue = new List<FlagsSeriesData>();
            this.Description = this.Description_DefaultValue = "undefined";
            nullable1 = new bool?(true);
            this.EnableMouseTracking_DefaultValue = nullable1;
            this.EnableMouseTracking = nullable1;
            this.Events = this.Events_DefaultValue = new FlagsSeriesEvents();
            nullable1 = new bool?(false);
            this.GetExtremesFromAll_DefaultValue = nullable1;
            this.GetExtremesFromAll = nullable1;
            this.Id = this.Id_DefaultValue = "";
            double? nullable4 = new double?();
            this.Index_DefaultValue = nullable4;
            this.Index = nullable4;
            this.Keys = this.Keys_DefaultValue = new List<string>();
            double? nullable5 = new double?();
            this.LegendIndex_DefaultValue = nullable5;
            this.LegendIndex = nullable5;
            this.LineColor = this.LineColor_DefaultValue = "#000000";
            nullable5 = new double?(1.0);
            this.LineWidth_DefaultValue = nullable5;
            this.LineWidth = nullable5;
            this.LinkedTo = this.LinkedTo_DefaultValue = "";
            double? nullable6 = new double?();
            this.MaxPointWidth_DefaultValue = nullable6;
            this.MaxPointWidth = nullable6;
            this.Name = this.Name_DefaultValue = (string) null;
            this.NavigatorOptions = this.NavigatorOptions_DefaultValue = (object) null;
            this.NegativeColor = this.NegativeColor_DefaultValue = "null";
            this.OnKey = this.OnKey_DefaultValue = FlagsSeriesOnKey.Y;
            this.OnSeries = this.OnSeries_DefaultValue = "undefined";
            this.Point = this.Point_DefaultValue = new FlagsSeriesPoint();
            this.PointIntervalUnit = this.PointIntervalUnit_DefaultValue = FlagsSeriesPointIntervalUnit.Null;
            nullable1 = new bool?(false);
            this.Selected_DefaultValue = nullable1;
            this.Selected = nullable1;
            this.Shadow = this.Shadow_DefaultValue = new Shadow()
            {
                Enabled = false
            };
            this.Shape = this.Shape_DefaultValue = FlagsSeriesShape.Flag;
            nullable1 = new bool?(false);
            this.ShowCheckbox_DefaultValue = nullable1;
            this.ShowCheckbox = nullable1;
            nullable1 = new bool?(true);
            this.ShowInLegend_DefaultValue = nullable1;
            this.ShowInLegend = nullable1;
            bool? nullable7 = new bool?();
            this.ShowInNavigator_DefaultValue = nullable7;
            this.ShowInNavigator = nullable7;
            nullable7 = new bool?(false);
            this.SoftThreshold_DefaultValue = nullable7;
            this.SoftThreshold = nullable7;
            this.Stack = this.Stack_DefaultValue = "null";
            nullable6 = new double?(12.0);
            this.StackDistance_DefaultValue = nullable6;
            this.StackDistance = nullable6;
            this.States = this.States_DefaultValue = new FlagsSeriesStates();
            nullable7 = new bool?(true);
            this.StickyTracking_DefaultValue = nullable7;
            this.StickyTracking = nullable7;
            this.Style = this.Style_DefaultValue = new Hashtable()
            {
                {
                    (object) "fontSize",
                    (object) "11px"
                },
                {
                    (object) "fontWeight",
                    (object) "bold"
                }
            };
            this.TextAlign = this.TextAlign_DefaultValue = FlagsSeriesTextAlign.Center;
            nullable6 = new double?(0.0);
            this.Threshold_DefaultValue = nullable6;
            this.Threshold = nullable6;
            this.Title = this.Title_DefaultValue = "A";
            this.Tooltip = this.Tooltip_DefaultValue = new FlagsSeriesTooltip();
            this.Type = this.Type_DefaultValue = FlagsSeriesType.Null;
            nullable7 = new bool?(false);
            this.UseHTML_DefaultValue = nullable7;
            this.UseHTML = nullable7;
            nullable7 = new bool?(true);
            this.Visible_DefaultValue = nullable7;
            this.Visible = nullable7;
            this.XAxis = this.XAxis_DefaultValue = "0";
            nullable6 = new double?(-30.0);
            this.Y_DefaultValue = nullable6;
            this.Y = nullable6;
            this.YAxis = this.YAxis_DefaultValue = "0";
            double? nullable8 = new double?();
            this.ZIndex_DefaultValue = nullable8;
            this.ZIndex = nullable8;
            this.ZoneAxis = this.ZoneAxis_DefaultValue = "y";
            this.Zones = this.Zones_DefaultValue = new List<FlagsSeriesZone>();
        }

        public bool? AllowPointSelect { get; set; }

        private bool? AllowPointSelect_DefaultValue { get; set; }

        public double? AnimationLimit { get; set; }

        private double? AnimationLimit_DefaultValue { get; set; }

        public string ClassName { get; set; }

        private string ClassName_DefaultValue { get; set; }

        public string Color { get; set; }

        private string Color_DefaultValue { get; set; }

        public double? ColorIndex { get; set; }

        private double? ColorIndex_DefaultValue { get; set; }

        public List<string> Colors { get; set; }

        private List<string> Colors_DefaultValue { get; set; }

        public FlagsSeriesCompareBase CompareBase { get; set; }

        private FlagsSeriesCompareBase CompareBase_DefaultValue { get; set; }

        public double? CropThreshold { get; set; }

        private double? CropThreshold_DefaultValue { get; set; }

        public FlagsSeriesCursor Cursor { get; set; }

        private FlagsSeriesCursor Cursor_DefaultValue { get; set; }

        public List<FlagsSeriesData> Data { get; set; }

        private List<FlagsSeriesData> Data_DefaultValue { get; set; }

        public string Description { get; set; }

        private string Description_DefaultValue { get; set; }

        public bool? EnableMouseTracking { get; set; }

        private bool? EnableMouseTracking_DefaultValue { get; set; }

        public FlagsSeriesEvents Events { get; set; }

        private FlagsSeriesEvents Events_DefaultValue { get; set; }

        public bool? GetExtremesFromAll { get; set; }

        private bool? GetExtremesFromAll_DefaultValue { get; set; }

        public new string Id { get; set; }

        private string Id_DefaultValue { get; set; }

        public new double? Index { get; set; }

        private double? Index_DefaultValue { get; set; }

        public List<string> Keys { get; set; }

        private List<string> Keys_DefaultValue { get; set; }

        public new double? LegendIndex { get; set; }

        private double? LegendIndex_DefaultValue { get; set; }

        public string LineColor { get; set; }

        private string LineColor_DefaultValue { get; set; }

        public double? LineWidth { get; set; }

        private double? LineWidth_DefaultValue { get; set; }

        public string LinkedTo { get; set; }

        private string LinkedTo_DefaultValue { get; set; }

        public double? MaxPointWidth { get; set; }

        private double? MaxPointWidth_DefaultValue { get; set; }

        public new string Name { get; set; }

        private string Name_DefaultValue { get; set; }

        public object NavigatorOptions { get; set; }

        private object NavigatorOptions_DefaultValue { get; set; }

        public string NegativeColor { get; set; }

        private string NegativeColor_DefaultValue { get; set; }

        public FlagsSeriesOnKey OnKey { get; set; }

        private FlagsSeriesOnKey OnKey_DefaultValue { get; set; }

        public string OnSeries { get; set; }

        private string OnSeries_DefaultValue { get; set; }

        public FlagsSeriesPoint Point { get; set; }

        private FlagsSeriesPoint Point_DefaultValue { get; set; }

        public FlagsSeriesPointIntervalUnit PointIntervalUnit { get; set; }

        private FlagsSeriesPointIntervalUnit PointIntervalUnit_DefaultValue { get; set; }

        public bool? Selected { get; set; }

        private bool? Selected_DefaultValue { get; set; }

        public Shadow Shadow { get; set; }

        private Shadow Shadow_DefaultValue { get; set; }

        public FlagsSeriesShape Shape { get; set; }

        private FlagsSeriesShape Shape_DefaultValue { get; set; }

        public bool? ShowCheckbox { get; set; }

        private bool? ShowCheckbox_DefaultValue { get; set; }

        public bool? ShowInLegend { get; set; }

        private bool? ShowInLegend_DefaultValue { get; set; }

        public bool? ShowInNavigator { get; set; }

        private bool? ShowInNavigator_DefaultValue { get; set; }

        public bool? SoftThreshold { get; set; }

        private bool? SoftThreshold_DefaultValue { get; set; }

        public new string Stack { get; set; }

        private string Stack_DefaultValue { get; set; }

        public double? StackDistance { get; set; }

        private double? StackDistance_DefaultValue { get; set; }

        public FlagsSeriesStates States { get; set; }

        private FlagsSeriesStates States_DefaultValue { get; set; }

        public bool? StickyTracking { get; set; }

        private bool? StickyTracking_DefaultValue { get; set; }

        public Hashtable Style { get; set; }

        private Hashtable Style_DefaultValue { get; set; }

        public FlagsSeriesTextAlign TextAlign { get; set; }

        private FlagsSeriesTextAlign TextAlign_DefaultValue { get; set; }

        public double? Threshold { get; set; }

        private double? Threshold_DefaultValue { get; set; }

        public string Title { get; set; }

        private string Title_DefaultValue { get; set; }

        public FlagsSeriesTooltip Tooltip { get; set; }

        private FlagsSeriesTooltip Tooltip_DefaultValue { get; set; }

        public FlagsSeriesType Type { get; set; }

        private FlagsSeriesType Type_DefaultValue { get; set; }

        public bool? UseHTML { get; set; }

        private bool? UseHTML_DefaultValue { get; set; }

        public bool? Visible { get; set; }

        private bool? Visible_DefaultValue { get; set; }

        public new string XAxis { get; set; }

        private string XAxis_DefaultValue { get; set; }

        public double? Y { get; set; }

        private double? Y_DefaultValue { get; set; }

        public new string YAxis { get; set; }

        private string YAxis_DefaultValue { get; set; }

        public new double? ZIndex { get; set; }

        private double? ZIndex_DefaultValue { get; set; }

        public string ZoneAxis { get; set; }

        private string ZoneAxis_DefaultValue { get; set; }

        public List<FlagsSeriesZone> Zones { get; set; }

        private List<FlagsSeriesZone> Zones_DefaultValue { get; set; }

        internal override Hashtable ToHashtable()
        {
            Hashtable hashtable = new Hashtable();
            bool? nullable1 = this.AllowPointSelect;
            bool? nullable2 = this.AllowPointSelect_DefaultValue;
            if (nullable1.GetValueOrDefault() != nullable2.GetValueOrDefault() ||
                nullable1.HasValue != nullable2.HasValue)
                hashtable.Add((object) "allowPointSelect", (object) this.AllowPointSelect);
            double? nullable3 = this.AnimationLimit;
            double? nullable4 = this.AnimationLimit_DefaultValue;
            if (nullable3.GetValueOrDefault() != nullable4.GetValueOrDefault() ||
                nullable3.HasValue != nullable4.HasValue)
                hashtable.Add((object) "animationLimit", (object) this.AnimationLimit);
            if (this.ClassName != this.ClassName_DefaultValue)
                hashtable.Add((object) "className", (object) this.ClassName);
            if (this.Color != this.Color_DefaultValue)
                hashtable.Add((object) "color", (object) this.Color);
            nullable4 = this.ColorIndex;
            nullable3 = this.ColorIndex_DefaultValue;
            if (nullable4.GetValueOrDefault() != nullable3.GetValueOrDefault() ||
                nullable4.HasValue != nullable3.HasValue)
                hashtable.Add((object) "colorIndex", (object) this.ColorIndex);
            if (this.Colors != this.Colors_DefaultValue)
                hashtable.Add((object) "colors", (object) this.Colors);
            if (this.CompareBase != this.CompareBase_DefaultValue)
                hashtable.Add((object) "compareBase",
                    (object) Highstock.FirstCharacterToLower(this.CompareBase.ToString()));
            nullable3 = this.CropThreshold;
            nullable4 = this.CropThreshold_DefaultValue;
            if (nullable3.GetValueOrDefault() != nullable4.GetValueOrDefault() ||
                nullable3.HasValue != nullable4.HasValue)
                hashtable.Add((object) "cropThreshold", (object) this.CropThreshold);
            if (this.Cursor != this.Cursor_DefaultValue)
                hashtable.Add((object) "cursor", (object) Highstock.FirstCharacterToLower(this.Cursor.ToString()));
            if (this.Data.Any<FlagsSeriesData>())
                hashtable.Add((object) "data", (object) this.HashifyList((IEnumerable) this.Data));
            if (this.Description != this.Description_DefaultValue)
                hashtable.Add((object) "description", (object) this.Description);
            nullable2 = this.EnableMouseTracking;
            nullable1 = this.EnableMouseTracking_DefaultValue;
            if (nullable2.GetValueOrDefault() != nullable1.GetValueOrDefault() ||
                nullable2.HasValue != nullable1.HasValue)
                hashtable.Add((object) "enableMouseTracking", (object) this.EnableMouseTracking);
            if (this.Events.IsDirty())
                hashtable.Add((object) "events", (object) this.Events.ToHashtable());
            nullable1 = this.GetExtremesFromAll;
            nullable2 = this.GetExtremesFromAll_DefaultValue;
            if (nullable1.GetValueOrDefault() != nullable2.GetValueOrDefault() ||
                nullable1.HasValue != nullable2.HasValue)
                hashtable.Add((object) "getExtremesFromAll", (object) this.GetExtremesFromAll);
            if (this.Id != this.Id_DefaultValue)
                hashtable.Add((object) "id", (object) this.Id);
            nullable4 = this.Index;
            nullable3 = this.Index_DefaultValue;
            if (nullable4.GetValueOrDefault() != nullable3.GetValueOrDefault() ||
                nullable4.HasValue != nullable3.HasValue)
                hashtable.Add((object) "index", (object) this.Index);
            if (this.Keys != this.Keys_DefaultValue)
                hashtable.Add((object) "keys", (object) this.Keys);
            nullable3 = this.LegendIndex;
            nullable4 = this.LegendIndex_DefaultValue;
            if (nullable3.GetValueOrDefault() != nullable4.GetValueOrDefault() ||
                nullable3.HasValue != nullable4.HasValue)
                hashtable.Add((object) "legendIndex", (object) this.LegendIndex);
            if (this.LineColor != this.LineColor_DefaultValue)
                hashtable.Add((object) "lineColor", (object) this.LineColor);
            nullable4 = this.LineWidth;
            nullable3 = this.LineWidth_DefaultValue;
            if (nullable4.GetValueOrDefault() != nullable3.GetValueOrDefault() ||
                nullable4.HasValue != nullable3.HasValue)
                hashtable.Add((object) "lineWidth", (object) this.LineWidth);
            if (this.LinkedTo != this.LinkedTo_DefaultValue)
                hashtable.Add((object) "linkedTo", (object) this.LinkedTo);
            nullable3 = this.MaxPointWidth;
            nullable4 = this.MaxPointWidth_DefaultValue;
            if (nullable3.GetValueOrDefault() != nullable4.GetValueOrDefault() ||
                nullable3.HasValue != nullable4.HasValue)
                hashtable.Add((object) "maxPointWidth", (object) this.MaxPointWidth);
            if (this.Name != this.Name_DefaultValue)
                hashtable.Add((object) "name", (object) this.Name);
            if (this.NavigatorOptions != this.NavigatorOptions_DefaultValue)
                hashtable.Add((object) "navigatorOptions", this.NavigatorOptions);
            if (this.NegativeColor != this.NegativeColor_DefaultValue)
                hashtable.Add((object) "negativeColor", (object) this.NegativeColor);
            if (this.OnKey != this.OnKey_DefaultValue)
                hashtable.Add((object) "onKey", (object) Highstock.FirstCharacterToLower(this.OnKey.ToString()));
            if (this.OnSeries != this.OnSeries_DefaultValue)
                hashtable.Add((object) "onSeries", (object) this.OnSeries);
            if (this.Point.IsDirty())
                hashtable.Add((object) "point", (object) this.Point.ToHashtable());
            if (this.PointIntervalUnit != this.PointIntervalUnit_DefaultValue)
                hashtable.Add((object) "pointIntervalUnit",
                    (object) Highstock.FirstCharacterToLower(this.PointIntervalUnit.ToString()));
            nullable2 = this.Selected;
            nullable1 = this.Selected_DefaultValue;
            if (nullable2.GetValueOrDefault() != nullable1.GetValueOrDefault() ||
                nullable2.HasValue != nullable1.HasValue)
                hashtable.Add((object) "selected", (object) this.Selected);
            if (this.Shadow.IsDirty())
                hashtable.Add((object) "shadow", (object) this.Shadow.ToHashtable());
            if (this.Shape != this.Shape_DefaultValue)
                hashtable.Add((object) "shape", (object) Highstock.FirstCharacterToLower(this.Shape.ToString()));
            nullable1 = this.ShowCheckbox;
            nullable2 = this.ShowCheckbox_DefaultValue;
            if (nullable1.GetValueOrDefault() != nullable2.GetValueOrDefault() ||
                nullable1.HasValue != nullable2.HasValue)
                hashtable.Add((object) "showCheckbox", (object) this.ShowCheckbox);
            nullable2 = this.ShowInLegend;
            nullable1 = this.ShowInLegend_DefaultValue;
            if (nullable2.GetValueOrDefault() != nullable1.GetValueOrDefault() ||
                nullable2.HasValue != nullable1.HasValue)
                hashtable.Add((object) "showInLegend", (object) this.ShowInLegend);
            nullable1 = this.ShowInNavigator;
            nullable2 = this.ShowInNavigator_DefaultValue;
            if (nullable1.GetValueOrDefault() != nullable2.GetValueOrDefault() ||
                nullable1.HasValue != nullable2.HasValue)
                hashtable.Add((object) "showInNavigator", (object) this.ShowInNavigator);
            nullable2 = this.SoftThreshold;
            nullable1 = this.SoftThreshold_DefaultValue;
            if (nullable2.GetValueOrDefault() != nullable1.GetValueOrDefault() ||
                nullable2.HasValue != nullable1.HasValue)
                hashtable.Add((object) "softThreshold", (object) this.SoftThreshold);
            if (this.Stack != this.Stack_DefaultValue)
                hashtable.Add((object) "stack", (object) this.Stack);
            nullable4 = this.StackDistance;
            nullable3 = this.StackDistance_DefaultValue;
            if (nullable4.GetValueOrDefault() != nullable3.GetValueOrDefault() ||
                nullable4.HasValue != nullable3.HasValue)
                hashtable.Add((object) "stackDistance", (object) this.StackDistance);
            if (this.States.IsDirty())
                hashtable.Add((object) "states", (object) this.States.ToHashtable());
            nullable1 = this.StickyTracking;
            nullable2 = this.StickyTracking_DefaultValue;
            if (nullable1.GetValueOrDefault() != nullable2.GetValueOrDefault() ||
                nullable1.HasValue != nullable2.HasValue)
                hashtable.Add((object) "stickyTracking", (object) this.StickyTracking);
            if (this.Style != this.Style_DefaultValue)
                hashtable.Add((object) "style", (object) this.Style);
            if (this.TextAlign != this.TextAlign_DefaultValue)
                hashtable.Add((object) "textAlign",
                    (object) Highstock.FirstCharacterToLower(this.TextAlign.ToString()));
            nullable3 = this.Threshold;
            nullable4 = this.Threshold_DefaultValue;
            if (nullable3.GetValueOrDefault() != nullable4.GetValueOrDefault() ||
                nullable3.HasValue != nullable4.HasValue)
                hashtable.Add((object) "threshold", (object) this.Threshold);
            if (this.Title != this.Title_DefaultValue)
                hashtable.Add((object) "title", (object) this.Title);
            if (this.Tooltip.IsDirty())
                hashtable.Add((object) "tooltip", (object) this.Tooltip.ToHashtable());
            if (this.Type != this.Type_DefaultValue)
                hashtable.Add((object) "type", (object) Highstock.FirstCharacterToLower(this.Type.ToString()));
            nullable2 = this.UseHTML;
            nullable1 = this.UseHTML_DefaultValue;
            if (nullable2.GetValueOrDefault() != nullable1.GetValueOrDefault() ||
                nullable2.HasValue != nullable1.HasValue)
                hashtable.Add((object) "useHTML", (object) this.UseHTML);
            nullable1 = this.Visible;
            nullable2 = this.Visible_DefaultValue;
            if (nullable1.GetValueOrDefault() != nullable2.GetValueOrDefault() ||
                nullable1.HasValue != nullable2.HasValue)
                hashtable.Add((object) "visible", (object) this.Visible);
            if (this.XAxis != this.XAxis_DefaultValue)
                hashtable.Add((object) "xAxis", (object) this.XAxis);
            nullable4 = this.Y;
            nullable3 = this.Y_DefaultValue;
            if (nullable4.GetValueOrDefault() != nullable3.GetValueOrDefault() ||
                nullable4.HasValue != nullable3.HasValue)
                hashtable.Add((object) "y", (object) this.Y);
            if (this.YAxis != this.YAxis_DefaultValue)
                hashtable.Add((object) "yAxis", (object) this.YAxis);
            nullable3 = this.ZIndex;
            nullable4 = this.ZIndex_DefaultValue;
            if (nullable3.GetValueOrDefault() != nullable4.GetValueOrDefault() ||
                nullable3.HasValue != nullable4.HasValue)
                hashtable.Add((object) "zIndex", (object) this.ZIndex);
            if (this.ZoneAxis != this.ZoneAxis_DefaultValue)
                hashtable.Add((object) "zoneAxis", (object) this.ZoneAxis);
            if (this.Zones != this.Zones_DefaultValue)
                hashtable.Add((object) "zones", (object) this.HashifyList((IEnumerable) this.Zones));
            return hashtable;
        }

        internal override string ToJSON()
        {
            Hashtable hashtable = this.ToHashtable();

            if (hashtable.Count > 0)
                return JsonConvert.SerializeObject((object) this.ToHashtable());
            return "";
        }

        internal override bool IsDirty()
        {
            return this.ToHashtable().Count > 0;
        }
    }
}


text:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <RelativeLayout
        android:id="@+id/rl_top"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:orientation="horizontal"
        android:background="@color/main_style">
        <ImageView
            android:id="@+id/iv_back"
            android:layout_width="25dp"
            android:layout_height="25dp"
            android:src="@drawable/back_white"
            android:layout_centerVertical="true"/>
        <TextView
            android:id="@+id/bar_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="评 论"
            android:textSize="20sp"
            android:textColor="#fff"
            android:layout_centerInParent="true"/>

    </RelativeLayout>

    <ListView
        android:id="@+id/lv_kid_list"
        android:layout_marginRight="10dp"
        android:layout_marginLeft="10dp"
        android:dividerHeight="0dp"
        android:divider="#00000000"
        android:scrollbars="none"
        android:layout_below="@+id/rl_top"
        android:layout_above="@+id/remark_bar"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </ListView>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:id="@+id/remark_bar"
        android:background="@color/main_style"

        android:layout_alignParentBottom="true">
        <LinearLayout

            android:focusable="true"
            android:focusableInTouchMode="true"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="7dp"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:orientation="horizontal"
            >
            <EditText
                android:id="@+id/et_remark"
                android:paddingLeft="5dp"
                android:layout_marginTop="5dp"
                android:layout_marginBottom="5dp"
                android:layout_width="0dp"
                android:singleLine="true"
                android:layout_weight="8"

                android:hint="回复楼主"
                android:textColor="#808080"
                android:textColorHint="#f0f0f0"
                android:layout_height="match_parent"
                android:background="@drawable/find_search_shape"
                />
            <Button
                android:id="@+id/bt_remark"
                android:layout_width="0dp"
                android:layout_weight="2"
                android:textColor="#808080"
                android:background="@drawable/goodssearch_shape"
                android:text="回 复"
                android:textSize="15sp"
                android:layout_marginTop="5dp"
                android:layout_marginBottom="5dp"
                android:layout_marginLeft="5dp"
                android:layout_gravity="center"
                android:layout_height="match_parent" />

        </LinearLayout>
    </RelativeLayout>

</RelativeLayout>


text:
from setuptools import setup, find_packages

with open('README.md') as readme_file:
    README = readme_file.read()

install_requires = [
    'chalice==0.1.0',
]

setup(
    name='chalice_view',
    version='0.1.0',
    description="Chalice utils for developing views",
    long_description=README,
    author="Kousuke Takeuchi",
    author_email='k.takeuchi@warrantee.co.jp',
    url='https://github.com/green-latte/chalice-view',
    packages=find_packages(exclude=['tests']),
    install_requires=install_requires,
    license="Apache License 2.0",
    package_data={'chalice_view': ['*.json']},
    include_package_data=True,
    zip_safe=False,
    keywords='chalice-view',
    classifiers=[
        'Development Status :: 2 - Pre-Alpha',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: Apache Software License',
        'Natural Language :: English',
        "Programming Language :: Python :: 2",
        'Programming Language :: Python :: 2.7',
    ],
)


text:
using Core;
using System.Web.Mvc;

namespace Site.Controllers
{
    public class HomeController : SiteController
    {
        //[OutputCache(Duration = Core.Configuration.OutputCacheDuration, VaryByParam = "*")]
        public ActionResult Index()
        {
            return View();
        }
    }
}


text:
/*
 * Cloud Foundry auto-configuration
 * Postgresql connection
 *
 * Auto-configured node modules:
 *
 * "pg" [https://github.com/brianc/node-postgres]
 * - defaults
 * - connect()
 * - new Client()
 */

var sc = require("./service");
var util = require("util");
var Cache = require("./cache").Cache;

function processConfig (config, props) {
  if (typeof config === "string") {
    config = props.url;
  }
  else {
    config = config || {};
    config.host = props.host;
    config.port = props.port;
    config.user = props.username;
    config.password = props.password;
    config.database = props.database;
  }
  return config;
}

function Postgresql () {
  this.type = "postgresql";
  this.cache = new Cache();
  this.supportedModules = {
    "pg" : function (moduleData, props) {
      // defaults
      if (moduleData.hasOwnProperty("defaults")) {
        moduleData.defaults = processConfig(moduleData.defaults, props);
      }

      // connect()
      // this module returns an object, not function, using getPrototypeOf
      if (typeof moduleData === "object") {
        var pgProto = Object.getPrototypeOf(moduleData);
        if ("connect" in pgProto) {
          var oldConnect = pgProto.connect;
          pgProto.connect = function () {
            var args = sc.redefineProps(arguments, [processConfig(arguments[0], props)]);
            return oldConnect.apply(this, args);
          };
        }
      }

      // new Client()
      if ("Client" in moduleData) {
        var oldClient = moduleData.Client;
        var oldClientProto = moduleData.Client.prototype;

        moduleData.Client = (function () {
          var Client = function () {
            var args = sc.redefineProps(arguments, [processConfig(arguments[0], props)]);
            return oldClient.apply(this, args);
          };

          for (var prop in oldClient) {
            Client[prop] = oldClient[prop];
          }

          return Client;
        })();
        moduleData.Client.prototype = oldClientProto;
      }
    }
  };
}

util.inherits(Postgresql, sc.Service);

exports.createNew = function () {
  return new Postgresql();
};


text:
title: The Last One
layout: post
hidden: true
author: NAN528
permalink: /mayday
no-lede: true
---
8:00pm on Monday, April 30th, 2018.

The usual place, one last time.

RSVP for yourself and +n guests the usual way.

Party starts and ends earlier than normal because of finals and because we are old.
Thank you for your continued patronage of NAN528 and we wish you the best.


text:
export const LOGIN_USER_SUCCESS = 'LOGIN_USER_SUCCESS';
export const LOGIN_USER_FAILURE = 'LOGIN_USER_FAILURE';
export const LOGIN_USER_REQUEST = 'LOGIN_USER_REQUEST';
export const LOGOUT_USER = 'LOGOUT_USER';

export const REGISTER_USER_SUCCESS = 'REGISTER_USER_SUCCESS';
export const REGISTER_USER_FAILURE = 'REGISTER_USER_FAILURE';
export const REGISTER_USER_REQUEST = 'REGISTER_USER_REQUEST';

export const FETCH_PROTECTED_DATA_REQUEST = 'FETCH_PROTECTED_DATA_REQUEST';
export const RECEIVE_PROTECTED_DATA = 'RECEIVE_PROTECTED_DATA';

export const REGISTER_POST_SUCCESS = 'REGISTER_POST_SUCCESS';
export const REGISTER_POST_FAILURE = 'REGISTER_POST_FAILURE';
export const REGISTER_POST_REQUEST = 'REGISTER_POST_REQUEST';


text:
layout: post
title: "Prime for April 14, 2013"
date: 2013-04-14 21:50
tags: [prime, movie, node.js]
icons: [nodejs, python, ruby]
---

* [Hitchcock](http://www.imdb.com/title/tt0975645/) — A great movie that tells the story behind how Psycho(1960), the greatest movie of Alfred Hitchcock, was made. It is also a perfect example of entrepreneurship. That's why it is recommended to whom always feels vivacious to produce and searches for the new, by [@Fisbecer](https://twitter.com/Fisbecer/status/323461861829926912).
* [The node.js community is quietly changing the face of open source](http://caines.ca/blog/programming/the-node-js-community-is-quietly-changing-the-face-of-open-source/) — Discusses if keeping the core, standard library of a language small is better by comparing python, ruby and node.js. It seems it is.


text:
import React, { Component} from 'react';

class Item extends Component {
  render() {
    return (
      <div>
        {this.props.children}
      </div>
    );
  }
}

Item.propTypes = {
  id: React.PropTypes.number.isRequired,
  children: React.PropTypes.element.isRequired,
};

export default Item;


text:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.v7.widget.CardView
        android:id="@+id/cv_popular_movie"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        card_view:cardCornerRadius="20dp">

        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/iv_movie_poster"
                android:contentDescription="@string/poster_image_alt"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentTop="true"
                android:layout_centerHorizontal="true" />

            <ProgressBar
                android:id="@+id/pb_movie_poster"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentTop="true"
                android:layout_below="@+id/iv_movie_poster"
                android:layout_centerHorizontal="true" />

            <TextView
                android:id="@+id/tv_movie_poster_error"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/pb_movie_poster"
                android:layout_margin="20dp"
                android:textColor="@android:color/holo_red_light"
                android:textSize="@dimen/card_view_text_size"
                android:text="@string/error_movie_poster"
                android:textAlignment="center"
                android:visibility="invisible" />

            <TextView
                android:id="@+id/tv_movie_title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/tv_movie_poster_error"
                android:padding="10dp"
                android:textColor="#4c4c4c"
                android:textSize="@dimen/card_view_text_size"
                android:textAlignment="center" />

        </RelativeLayout>

    </android.support.v7.widget.CardView>

</LinearLayout>


text:
package org.apache.wicket;

import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.util.tester.WicketTester;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 */
public class RequestEncodingTest extends Assert
{
	/** Log. */
	private static final Logger log = LoggerFactory.getLogger(RequestEncodingTest.class);

	private RedirectApplication application;
	private WicketTester tester;

	/**
	 * @see WicketTestCase#commonBefore()
	 */
	@Before
	public void setUp()
	{
		application = new RedirectApplication();
		tester = new WicketTester(application);
		tester.startPage(RedirectHomePage.class);
		tester.assertRenderedPage(RedirectHomePage.class);
	}

	/**
	 *
	 */
	@After
	public void tearDown()
	{
		tester.destroy();
	}

	/**
	 *
	 */
	@Test
	public void defaultTest()
	{
		tester.startPage(RedirectA.class,
			new PageParameters().set("file", "umlaut-\u00E4-\u00F6-\u00FC"));
		tester.assertRenderedPage(RedirectB.class);

		String url2 = ((RedirectB)tester.getLastRenderedPage()).getInterceptContinuationURL();
		assertTrue(url2.contains("umlaut-%C3%A4-%C3%B6-%C3%BC"));

		tester.clickLink("link");
		tester.assertRenderedPage(RedirectA.class);

		String file = ((RedirectA)tester.getLastRenderedPage()).getFileParameter();
		assertEquals("umlaut-\u00E4-\u00F6-\u00FC", file);

		String document = tester.getLastResponseAsString();
		assertTrue(document.contains("umlaut-\u00E4-\u00F6-\u00FC"));
	}

	/**
	 *
	 */
	@Test
	public void umlautsInRequestUri()
	{
		application.mountPage("Aparameter", RedirectA.class);
		defaultTest();
	}
}


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<TITLE>
com.amazonaws.services.route53 (AWS SDK for Java - 1.4.7)
</TITLE>

<META NAME="date" CONTENT="2013-06-18">

<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../JavaDoc.css" TITLE="Style">

com.amazonaws.services.route53

Interfaces

AmazonRoute53

AmazonRoute53Async

Classes

AmazonRoute53AsyncClient

AmazonRoute53Client


text:
<?php

namespace App\Http\Controllers\Admin;

use App\Base\Controllers\AdminController;
use App\Http\Requests\Admin\PrizeRequest;
use App\Prize;

class PrizeController extends AdminController
{
    private $imageColumn = "picture";
    public function getPrizes()
    {
        $prize = Prize::firstOrFail();
        return $this->getForm($prize);
    }
    public function patchPrizes(Prize $prize, PrizeRequest $request)
    {
        return $this->saveFlashRedirect($prize,$request,$this->imageColumn);
    }
}


text:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package servlet;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Dave
 */
public class Data {
    static ArrayList<Student> student = new ArrayList<Student>();
    static ArrayList<Student> garant = new ArrayList<Student>();
    static ArrayList<Predmet> predmet = new ArrayList<Predmet>();
    static ArrayList<Rozvrh> rozvrh = new ArrayList<Rozvrh>();
    static ArrayList<Prubeh> prubeh = new ArrayList<Prubeh>();

    public void setStudent(Connection con){
        try {
            Statement st = con.createStatement();
            ResultSet rs = st.executeQuery("SELECT * FROM Student");
            student = new ArrayList<Student>();
            while(rs.next()){
                student.add(new Student(rs.getInt(1), rs.getString(2), rs.getString(3)));
            }
        } catch (SQLException ex) {
            Logger.getLogger(Data.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void setGarant(Connection con){
        try {
            Statement st = con.createStatement();
            ResultSet rs = st.executeQuery("SELECT * FROM Garant");
            garant = new ArrayList<Student>();
            while(rs.next()){
                garant.add(new Student(rs.getInt(1), rs.getString(2), rs.getString(3)));
            }
        } catch (SQLException ex) {
            Logger.getLogger(Data.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public void setPredmet(Connection con){
        try {
            Statement st = con.createStatement();
            ResultSet rs = st.executeQuery("SELECT * FROM Predmet");
            predmet = new ArrayList<Predmet>();
            while(rs.next()){
                predmet.add(new Predmet(rs.getInt(1), rs.getString(2),
                        rs.getInt(3), rs.getInt(4)));
            }
        } catch (SQLException ex) {
            Logger.getLogger(Data.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public void setRozvrh(Connection con){
        try {
            Statement st = con.createStatement();
            ResultSet rs = st.executeQuery("SELECT * FROM Rozvrh");
            rozvrh = new ArrayList<Rozvrh>();
            while(rs.next()){
                rozvrh.add(new Rozvrh(rs.getInt(1), rs.getInt(2), rs.getString(3),
                        rs.getString(4), rs.getString(5)));
            }
        } catch (SQLException ex) {
            Logger.getLogger(Data.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public void setPrubeh(Connection con){
        try {
            Statement st = con.createStatement();
            ResultSet rs = st.executeQuery("SELECT * FROM Prubeh");
            prubeh = new ArrayList<Prubeh>();
            while(rs.next()){
                prubeh.add(new Prubeh(rs.getInt(1), rs.getInt(2), rs.getInt(3),
                        rs.getInt(4), rs.getString(5)));
            }
        } catch (SQLException ex) {
            Logger.getLogger(Data.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

}


text:
class AddDateDeliverytoSpreeOrder < ActiveRecord::Migration
  def change
  	add_column :spree_line_items, :delivery_date, :datetime
  end
end


text:
package com.acg12.dao;

import com.acg12.entity.po.Acg12CollectAlbumEntity;
import com.framework.loippi.mybatis.dao.GenericDao;

import java.util.List;

/**
 * DAO - Acg12CollectAlbumEntity(CollectAlbum)
 *
 * @author kcj
 * @version 2.0
 */
public interface Acg12CollectAlbumDao  extends GenericDao<Acg12CollectAlbumEntity, Long> {
	List<Acg12CollectAlbumEntity> findListByPage(Object parameter);
	List<Acg12CollectAlbumEntity> findListNewByPage(Object parameter);
    Long deletes(Object parameter);
}


text:
class AddFeaturesToRevision < ActiveRecord::Migration[4.2]
  def change
    add_column :revisions, :features, :text
  end
end


text:
include_recipe "build-essential"

execute "remove-libtool-packages" do
  user "root"
  command "rpm -qa | grep libtool | rpm -e --nodeps $(xargs)"
  only_if "rpm -qa | grep libtool"
end

remote_file "/tmp/libtool-2.2.8.tar.gz" do
  owner "root"
  group "root"
  mode "0644"
  source "http://ftp.gnu.org/gnu/libtool/libtool-2.2.8.tar.gz"
  backup false
  action :create_if_missing
end

script "install-libtool" do
  interpreter "bash"
  user "root"
  cwd "/tmp"
  code <<-EOH
  tar xzvf libtool-2.2.8.tar.gz
  cd libtool-2.2.8
  ./configure
  make
  make install
  EOH
  not_if "/usr/bin/test -x /usr/local/bin/libtool"
end

cookbook_file "/etc/profile.d/libtool.sh" do
  owner "root"
  group "root"
  mode "0755"
  source "libtool.sh"
  backup false
  action :create_if_missing
end


text:
package com.huibo.mes.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;

import com.huibo.mes.R;

/**
 * @author wangyong
 * @version 1.0
 * @date 2017/6/6 20:28
 */
public class MultipleStatusView extends RelativeLayout {
    public static final int STATUS_CONTENT    = 0x00;
    public static final int STATUS_LOADING    = 0x01;
    public static final int STATUS_EMPTY      = 0x02;
    public static final int STATUS_ERROR      = 0x03;
    public static final int STATUS_NO_NETWORK = 0x04;

    private static final int NULL_RESOURCE_ID = -1;

    private View mEmptyView;
    private View mErrorView;
    private View mLoadingView;
    private View mNoNetworkView;
    private View mContentView;
    private View mEmptyRetryView;
    private View mErrorRetryView;
    private View mNoNetworkRetryView;
    private int  mEmptyViewResId;
    private int  mErrorViewResId;
    private int  mLoadingViewResId;
    private int  mNoNetworkViewResId;
    private int  mContentViewResId;
    private int  mViewStatus;

    private LayoutInflater mInflater;
    private OnClickListener mOnRetryClickListener;
    private final ViewGroup.LayoutParams mLayoutParams =
            new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

    public MultipleStatusView(Context context) {
        this(context, null);
    }

    public MultipleStatusView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MultipleStatusView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MultipleStatusView, defStyleAttr, 0);

        mEmptyViewResId = a.getResourceId(R.styleable.MultipleStatusView_emptyView, R.layout.empty_view);
        mErrorViewResId = a.getResourceId(R.styleable.MultipleStatusView_errorView, R.layout.error_view);
        mLoadingViewResId = a.getResourceId(R.styleable.MultipleStatusView_loadingView, R.layout.loading_view);
        mNoNetworkViewResId = a.getResourceId(R.styleable.MultipleStatusView_noNetworkView, R.layout.no_network_view);
        mContentViewResId = a.getResourceId(R.styleable.MultipleStatusView_contentView, NULL_RESOURCE_ID);
        a.recycle();
    }

    @Override protected void onFinishInflate() {
        super.onFinishInflate();
        mInflater = LayoutInflater.from(getContext());
        showContent();
    }

    /**
     * 获取当前状态
     */
    @SuppressWarnings("unused") public int getViewStatus() {
        return mViewStatus;
    }

    /**
     * 设置重试点击事件
     *
     * @param onRetryClickListener 重试点击事件
     */
    public void setOnRetryClickListener(OnClickListener onRetryClickListener) {
        this.mOnRetryClickListener = onRetryClickListener;
    }

    /**
     * 显示空视图
     */
    public final void showEmpty() {
        mViewStatus = STATUS_EMPTY;
        if (null == mEmptyView) {
            mEmptyView = mInflater.inflate(mEmptyViewResId, null);
            mEmptyRetryView = mEmptyView.findViewById(R.id.empty_retry_view);
            if (null != mOnRetryClickListener && null != mEmptyRetryView) {
                mEmptyRetryView.setOnClickListener(mOnRetryClickListener);
            }
            addView(mEmptyView, 0, mLayoutParams);
        }
        showViewByStatus(mViewStatus);
    }

    /**
     * 显示错误视图
     */
    public final void showError() {
        mViewStatus = STATUS_ERROR;
        if (null == mErrorView) {
            mErrorView = mInflater.inflate(mErrorViewResId, null);
            mErrorRetryView = mErrorView.findViewById(R.id.error_retry_view);
            if (null != mOnRetryClickListener && null != mErrorRetryView) {
                mErrorRetryView.setOnClickListener(mOnRetryClickListener);
            }
            addView(mErrorView, 0, mLayoutParams);
        }
        showViewByStatus(mViewStatus);
    }

    /**
     * 显示加载中视图
     */
    public final void showLoading() {
        mViewStatus = STATUS_LOADING;
        if (null == mLoadingView) {
            mLoadingView = mInflater.inflate(mLoadingViewResId, null);
            addView(mLoadingView, 0, mLayoutParams);
        }
        showViewByStatus(mViewStatus);
    }

    /**
     * 显示无网络视图
     */
    public final void showNoNetwork() {
        mViewStatus = STATUS_NO_NETWORK;
        if (null == mNoNetworkView) {
            mNoNetworkView = mInflater.inflate(mNoNetworkViewResId, null);
            mNoNetworkRetryView = mNoNetworkView.findViewById(R.id.no_network_retry_view);
            if (null != mOnRetryClickListener && null != mNoNetworkRetryView) {
                mNoNetworkRetryView.setOnClickListener(mOnRetryClickListener);
            }
            addView(mNoNetworkView, 0, mLayoutParams);
        }
        showViewByStatus(mViewStatus);
    }

    /**
     * 显示内容视图
     */
    public final void showContent() {
        mViewStatus = STATUS_CONTENT;
        if (null == mContentView) {
            if (mContentViewResId != NULL_RESOURCE_ID) {
                mContentView = mInflater.inflate(mContentViewResId, null);
                addView(mContentView, 0, mLayoutParams);
            } else {
                mContentView = findViewById(R.id.content_view);
            }
        }
        showViewByStatus(mViewStatus);
    }

    private void showViewByStatus(int viewStatus) {
        if (null != mLoadingView) {
            mLoadingView.setVisibility(viewStatus == STATUS_LOADING ? View.VISIBLE : View.GONE);
        }
        if (null != mEmptyView) {
            mEmptyView.setVisibility(viewStatus == STATUS_EMPTY ? View.VISIBLE : View.GONE);
        }
        if (null != mErrorView) {
            mErrorView.setVisibility(viewStatus == STATUS_ERROR ? View.VISIBLE : View.GONE);
        }
        if (null != mNoNetworkView) {
            mNoNetworkView.setVisibility(viewStatus == STATUS_NO_NETWORK ? View.VISIBLE : View.GONE);
        }
        if (null != mContentView) {
            mContentView.setVisibility(viewStatus == STATUS_CONTENT ? View.VISIBLE : View.GONE);
        }
    }

}


text:
#include <linux/compat.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/iommu.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/pci.h>		/* pci_bus_type */
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/vfio.h>
#include <linux/workqueue.h>

#define DRIVER_VERSION  "0.2"
#define DRIVER_AUTHOR   "Alex Williamson <alex.williamson@redhat.com>"
#define DRIVER_DESC     "Type1 IOMMU driver for VFIO"

static bool allow_unsafe_interrupts;
module_param_named(allow_unsafe_interrupts,
		   allow_unsafe_interrupts, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(allow_unsafe_interrupts,
		 "Enable VFIO IOMMU support for on platforms without interrupt remapping support.");

struct vfio_iommu {
	struct iommu_domain	*domain;
	struct mutex		lock;
	struct list_head	dma_list;
	struct list_head	group_list;
	bool			cache;
};

struct vfio_dma {
	struct list_head	next;
	dma_addr_t		iova;		/* Device address */
	unsigned long		vaddr;		/* Process virtual addr */
	long			npage;		/* Number of pages */
	int			prot;		/* IOMMU_READ/WRITE */
};

struct vfio_group {
	struct iommu_group	*iommu_group;
	struct list_head	next;
};

/*
 * This code handles mapping and unmapping of user data buffers
 * into DMA'ble space using the IOMMU
 */

#define NPAGE_TO_SIZE(npage)	((size_t)(npage) << PAGE_SHIFT)

struct vwork {
	struct mm_struct	*mm;
	long			npage;
	struct work_struct	work;
};

/* delayed decrement/increment for locked_vm */
static void vfio_lock_acct_bg(struct work_struct *work)
{
	struct vwork *vwork = container_of(work, struct vwork, work);
	struct mm_struct *mm;

	mm = vwork->mm;
	down_write(&mm->mmap_sem);
	mm->locked_vm += vwork->npage;
	up_write(&mm->mmap_sem);
	mmput(mm);
	kfree(vwork);
}

static void vfio_lock_acct(long npage)
{
	struct vwork *vwork;
	struct mm_struct *mm;

	if (!current->mm)
		return; /* process exited */

	if (down_write_trylock(&current->mm->mmap_sem)) {
		current->mm->locked_vm += npage;
		up_write(&current->mm->mmap_sem);
		return;
	}

	/*
	 * Couldn't get mmap_sem lock, so must setup to update
	 * mm->locked_vm later. If locked_vm were atomic, we
	 * wouldn't need this silliness
	 */
	vwork = kmalloc(sizeof(struct vwork), GFP_KERNEL);
	if (!vwork)
		return;
	mm = get_task_mm(current);
	if (!mm) {
		kfree(vwork);
		return;
	}
	INIT_WORK(&vwork->work, vfio_lock_acct_bg);
	vwork->mm = mm;
	vwork->npage = npage;
	schedule_work(&vwork->work);
}

/*
 * Some mappings aren't backed by a struct page, for example an mmap'd
 * MMIO range for our own or another device.  These use a different
 * pfn conversion and shouldn't be tracked as locked pages.
 */
static bool is_invalid_reserved_pfn(unsigned long pfn)
{
	if (pfn_valid(pfn)) {
		bool reserved;
		struct page *tail = pfn_to_page(pfn);
		struct page *head = compound_trans_head(tail);
		reserved = !!(PageReserved(head));
		if (head != tail) {
			/*
			 * "head" is not a dangling pointer
			 * (compound_trans_head takes care of that)
			 * but the hugepage may have been split
			 * from under us (and we may not hold a
			 * reference count on the head page so it can
			 * be reused before we run PageReferenced), so
			 * we've to check PageTail before returning
			 * what we just read.
			 */
			smp_rmb();
			if (PageTail(tail))
				return reserved;
		}
		return PageReserved(tail);
	}

	return true;
}

static int put_pfn(unsigned long pfn, int prot)
{
	if (!is_invalid_reserved_pfn(pfn)) {
		struct page *page = pfn_to_page(pfn);
		if (prot & IOMMU_WRITE)
			SetPageDirty(page);
		put_page(page);
		return 1;
	}
	return 0;
}

/* Unmap DMA region */
static long __vfio_dma_do_unmap(struct vfio_iommu *iommu, dma_addr_t iova,
			     long npage, int prot)
{
	long i, unlocked = 0;

	for (i = 0; i < npage; i++, iova += PAGE_SIZE) {
		unsigned long pfn;

		pfn = iommu_iova_to_phys(iommu->domain, iova) >> PAGE_SHIFT;
		if (pfn) {
			iommu_unmap(iommu->domain, iova, PAGE_SIZE);
			unlocked += put_pfn(pfn, prot);
		}
	}
	return unlocked;
}

static void vfio_dma_unmap(struct vfio_iommu *iommu, dma_addr_t iova,
			   long npage, int prot)
{
	long unlocked;

	unlocked = __vfio_dma_do_unmap(iommu, iova, npage, prot);
	vfio_lock_acct(-unlocked);
}

static int vaddr_get_pfn(unsigned long vaddr, int prot, unsigned long *pfn)
{
	struct page *page[1];
	struct vm_area_struct *vma;
	int ret = -EFAULT;

	if (get_user_pages_fast(vaddr, 1, !!(prot & IOMMU_WRITE), page) == 1) {
		*pfn = page_to_pfn(page[0]);
		return 0;
	}

	down_read(&current->mm->mmap_sem);

	vma = find_vma_intersection(current->mm, vaddr, vaddr + 1);

	if (vma && vma->vm_flags & VM_PFNMAP) {
		*pfn = ((vaddr - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
		if (is_invalid_reserved_pfn(*pfn))
			ret = 0;
	}

	up_read(&current->mm->mmap_sem);

	return ret;
}

/* Map DMA region */
static int __vfio_dma_map(struct vfio_iommu *iommu, dma_addr_t iova,
			  unsigned long vaddr, long npage, int prot)
{
	dma_addr_t start = iova;
	long i, locked = 0;
	int ret;

	/* Verify that pages are not already mapped */
	for (i = 0; i < npage; i++, iova += PAGE_SIZE)
		if (iommu_iova_to_phys(iommu->domain, iova))
			return -EBUSY;

	iova = start;

	if (iommu->cache)
		prot |= IOMMU_CACHE;

	/*
	 * XXX We break mappings into pages and use get_user_pages_fast to
	 * pin the pages in memory.  It's been suggested that mlock might
	 * provide a more efficient mechanism, but nothing prevents the
	 * user from munlocking the pages, which could then allow the user
	 * access to random host memory.  We also have no guarantee from the
	 * IOMMU API that the iommu driver can unmap sub-pages of previous
	 * mappings.  This means we might lose an entire range if a single
	 * page within it is unmapped.  Single page mappings are inefficient,
	 * but provide the most flexibility for now.
	 */
	for (i = 0; i < npage; i++, iova += PAGE_SIZE, vaddr += PAGE_SIZE) {
		unsigned long pfn = 0;

		ret = vaddr_get_pfn(vaddr, prot, &pfn);
		if (ret) {
			__vfio_dma_do_unmap(iommu, start, i, prot);
			return ret;
		}

		/*
		 * Only add actual locked pages to accounting
		 * XXX We're effectively marking a page locked for every
		 * IOVA page even though it's possible the user could be
		 * backing multiple IOVAs with the same vaddr.  This over-
		 * penalizes the user process, but we currently have no
		 * easy way to do this properly.
		 */
		if (!is_invalid_reserved_pfn(pfn))
			locked++;

		ret = iommu_map(iommu->domain, iova,
				(phys_addr_t)pfn << PAGE_SHIFT,
				PAGE_SIZE, prot);
		if (ret) {
			/* Back out mappings on error */
			put_pfn(pfn, prot);
			__vfio_dma_do_unmap(iommu, start, i, prot);
			return ret;
		}
	}
	vfio_lock_acct(locked);
	return 0;
}

static inline bool ranges_overlap(dma_addr_t start1, size_t size1,
				  dma_addr_t start2, size_t size2)
{
	if (start1 < start2)
		return (start2 - start1 < size1);
	else if (start2 < start1)
		return (start1 - start2 < size2);
	return (size1 > 0 && size2 > 0);
}

static struct vfio_dma *vfio_find_dma(struct vfio_iommu *iommu,
						dma_addr_t start, size_t size)
{
	struct vfio_dma *dma;

	list_for_each_entry(dma, &iommu->dma_list, next) {
		if (ranges_overlap(dma->iova, NPAGE_TO_SIZE(dma->npage),
				   start, size))
			return dma;
	}
	return NULL;
}

static long vfio_remove_dma_overlap(struct vfio_iommu *iommu, dma_addr_t start,
				    size_t size, struct vfio_dma *dma)
{
	struct vfio_dma *split;
	long npage_lo, npage_hi;

	/* Existing dma region is completely covered, unmap all */
	if (start <= dma->iova &&
	    start + size >= dma->iova + NPAGE_TO_SIZE(dma->npage)) {
		vfio_dma_unmap(iommu, dma->iova, dma->npage, dma->prot);
		list_del(&dma->next);
		npage_lo = dma->npage;
		kfree(dma);
		return npage_lo;
	}

	/* Overlap low address of existing range */
	if (start <= dma->iova) {
		size_t overlap;

		overlap = start + size - dma->iova;
		npage_lo = overlap >> PAGE_SHIFT;

		vfio_dma_unmap(iommu, dma->iova, npage_lo, dma->prot);
		dma->iova += overlap;
		dma->vaddr += overlap;
		dma->npage -= npage_lo;
		return npage_lo;
	}

	/* Overlap high address of existing range */
	if (start + size >= dma->iova + NPAGE_TO_SIZE(dma->npage)) {
		size_t overlap;

		overlap = dma->iova + NPAGE_TO_SIZE(dma->npage) - start;
		npage_hi = overlap >> PAGE_SHIFT;

		vfio_dma_unmap(iommu, start, npage_hi, dma->prot);
		dma->npage -= npage_hi;
		return npage_hi;
	}

	/* Split existing */
	npage_lo = (start - dma->iova) >> PAGE_SHIFT;
	npage_hi = dma->npage - (size >> PAGE_SHIFT) - npage_lo;

	split = kzalloc(sizeof *split, GFP_KERNEL);
	if (!split)
		return -ENOMEM;

	vfio_dma_unmap(iommu, start, size >> PAGE_SHIFT, dma->prot);

	dma->npage = npage_lo;

	split->npage = npage_hi;
	split->iova = start + size;
	split->vaddr = dma->vaddr + NPAGE_TO_SIZE(npage_lo) + size;
	split->prot = dma->prot;
	list_add(&split->next, &iommu->dma_list);
	return size >> PAGE_SHIFT;
}

static int vfio_dma_do_unmap(struct vfio_iommu *iommu,
			     struct vfio_iommu_type1_dma_unmap *unmap)
{
	long ret = 0, npage = unmap->size >> PAGE_SHIFT;
	struct vfio_dma *dma, *tmp;
	uint64_t mask;

	mask = ((uint64_t)1 << __ffs(iommu->domain->ops->pgsize_bitmap)) - 1;

	if (unmap->iova & mask)
		return -EINVAL;
	if (unmap->size & mask)
		return -EINVAL;

	/* XXX We still break these down into PAGE_SIZE */
	WARN_ON(mask & PAGE_MASK);

	mutex_lock(&iommu->lock);

	list_for_each_entry_safe(dma, tmp, &iommu->dma_list, next) {
		if (ranges_overlap(dma->iova, NPAGE_TO_SIZE(dma->npage),
				   unmap->iova, unmap->size)) {
			ret = vfio_remove_dma_overlap(iommu, unmap->iova,
						      unmap->size, dma);
			if (ret > 0)
				npage -= ret;
			if (ret < 0 || npage == 0)
				break;
		}
	}
	mutex_unlock(&iommu->lock);
	return ret > 0 ? 0 : (int)ret;
}

static int vfio_dma_do_map(struct vfio_iommu *iommu,
			   struct vfio_iommu_type1_dma_map *map)
{
	struct vfio_dma *dma, *pdma = NULL;
	dma_addr_t iova = map->iova;
	unsigned long locked, lock_limit, vaddr = map->vaddr;
	size_t size = map->size;
	int ret = 0, prot = 0;
	uint64_t mask;
	long npage;

	mask = ((uint64_t)1 << __ffs(iommu->domain->ops->pgsize_bitmap)) - 1;

	/* READ/WRITE from device perspective */
	if (map->flags & VFIO_DMA_MAP_FLAG_WRITE)
		prot |= IOMMU_WRITE;
	if (map->flags & VFIO_DMA_MAP_FLAG_READ)
		prot |= IOMMU_READ;

	if (!prot)
		return -EINVAL; /* No READ/WRITE? */

	if (vaddr & mask)
		return -EINVAL;
	if (iova & mask)
		return -EINVAL;
	if (size & mask)
		return -EINVAL;

	/* XXX We still break these down into PAGE_SIZE */
	WARN_ON(mask & PAGE_MASK);

	/* Don't allow IOVA wrap */
	if (iova + size && iova + size < iova)
		return -EINVAL;

	/* Don't allow virtual address wrap */
	if (vaddr + size && vaddr + size < vaddr)
		return -EINVAL;

	npage = size >> PAGE_SHIFT;
	if (!npage)
		return -EINVAL;

	mutex_lock(&iommu->lock);

	if (vfio_find_dma(iommu, iova, size)) {
		ret = -EBUSY;
		goto out_lock;
	}

	/* account for locked pages */
	locked = current->mm->locked_vm + npage;
	lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
	if (locked > lock_limit && !capable(CAP_IPC_LOCK)) {
		pr_warn("%s: RLIMIT_MEMLOCK (%ld) exceeded\n",
			__func__, rlimit(RLIMIT_MEMLOCK));
		ret = -ENOMEM;
		goto out_lock;
	}

	ret = __vfio_dma_map(iommu, iova, vaddr, npage, prot);
	if (ret)
		goto out_lock;

	/* Check if we abut a region below - nothing below 0 */
	if (iova) {
		dma = vfio_find_dma(iommu, iova - 1, 1);
		if (dma && dma->prot == prot &&
		    dma->vaddr + NPAGE_TO_SIZE(dma->npage) == vaddr) {

			dma->npage += npage;
			iova = dma->iova;
			vaddr = dma->vaddr;
			npage = dma->npage;
			size = NPAGE_TO_SIZE(npage);

			pdma = dma;
		}
	}

	/* Check if we abut a region above - nothing above ~0 + 1 */
	if (iova + size) {
		dma = vfio_find_dma(iommu, iova + size, 1);
		if (dma && dma->prot == prot &&
		    dma->vaddr == vaddr + size) {

			dma->npage += npage;
			dma->iova = iova;
			dma->vaddr = vaddr;

			/*
			 * If merged above and below, remove previously
			 * merged entry.  New entry covers it.
			 */
			if (pdma) {
				list_del(&pdma->next);
				kfree(pdma);
			}
			pdma = dma;
		}
	}

	/* Isolated, new region */
	if (!pdma) {
		dma = kzalloc(sizeof *dma, GFP_KERNEL);
		if (!dma) {
			ret = -ENOMEM;
			vfio_dma_unmap(iommu, iova, npage, prot);
			goto out_lock;
		}

		dma->npage = npage;
		dma->iova = iova;
		dma->vaddr = vaddr;
		dma->prot = prot;
		list_add(&dma->next, &iommu->dma_list);
	}

out_lock:
	mutex_unlock(&iommu->lock);
	return ret;
}

static int vfio_iommu_type1_attach_group(void *iommu_data,
					 struct iommu_group *iommu_group)
{
	struct vfio_iommu *iommu = iommu_data;
	struct vfio_group *group, *tmp;
	int ret;

	group = kzalloc(sizeof(*group), GFP_KERNEL);
	if (!group)
		return -ENOMEM;

	mutex_lock(&iommu->lock);

	list_for_each_entry(tmp, &iommu->group_list, next) {
		if (tmp->iommu_group == iommu_group) {
			mutex_unlock(&iommu->lock);
			kfree(group);
			return -EINVAL;
		}
	}

	/*
	 * TODO: Domain have capabilities that might change as we add
	 * groups (see iommu->cache, currently never set).  Check for
	 * them and potentially disallow groups to be attached when it
	 * would change capabilities (ugh).
	 */
	ret = iommu_attach_group(iommu->domain, iommu_group);
	if (ret) {
		mutex_unlock(&iommu->lock);
		kfree(group);
		return ret;
	}

	group->iommu_group = iommu_group;
	list_add(&group->next, &iommu->group_list);

	mutex_unlock(&iommu->lock);

	return 0;
}

static void vfio_iommu_type1_detach_group(void *iommu_data,
					  struct iommu_group *iommu_group)
{
	struct vfio_iommu *iommu = iommu_data;
	struct vfio_group *group;

	mutex_lock(&iommu->lock);

	list_for_each_entry(group, &iommu->group_list, next) {
		if (group->iommu_group == iommu_group) {
			iommu_detach_group(iommu->domain, iommu_group);
			list_del(&group->next);
			kfree(group);
			break;
		}
	}

	mutex_unlock(&iommu->lock);
}

static void *vfio_iommu_type1_open(unsigned long arg)
{
	struct vfio_iommu *iommu;

	if (arg != VFIO_TYPE1_IOMMU)
		return ERR_PTR(-EINVAL);

	iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
	if (!iommu)
		return ERR_PTR(-ENOMEM);

	INIT_LIST_HEAD(&iommu->group_list);
	INIT_LIST_HEAD(&iommu->dma_list);
	mutex_init(&iommu->lock);

	/*
	 * Wish we didn't have to know about bus_type here.
	 */
	iommu->domain = iommu_domain_alloc(&pci_bus_type);
	if (!iommu->domain) {
		kfree(iommu);
		return ERR_PTR(-EIO);
	}

	/*
	 * Wish we could specify required capabilities rather than create
	 * a domain, see what comes out and hope it doesn't change along
	 * the way.  Fortunately we know interrupt remapping is global for
	 * our iommus.
	 */
	if (!allow_unsafe_interrupts &&
	    !iommu_domain_has_cap(iommu->domain, IOMMU_CAP_INTR_REMAP)) {
		pr_warn("%s: No interrupt remapping support.  Use the module param \"allow_unsafe_interrupts\" to enable VFIO IOMMU support on this platform\n",
		       __func__);
		iommu_domain_free(iommu->domain);
		kfree(iommu);
		return ERR_PTR(-EPERM);
	}

	return iommu;
}

static void vfio_iommu_type1_release(void *iommu_data)
{
	struct vfio_iommu *iommu = iommu_data;
	struct vfio_group *group, *group_tmp;
	struct vfio_dma *dma, *dma_tmp;

	list_for_each_entry_safe(group, group_tmp, &iommu->group_list, next) {
		iommu_detach_group(iommu->domain, group->iommu_group);
		list_del(&group->next);
		kfree(group);
	}

	list_for_each_entry_safe(dma, dma_tmp, &iommu->dma_list, next) {
		vfio_dma_unmap(iommu, dma->iova, dma->npage, dma->prot);
		list_del(&dma->next);
		kfree(dma);
	}

	iommu_domain_free(iommu->domain);
	iommu->domain = NULL;
	kfree(iommu);
}

static long vfio_iommu_type1_ioctl(void *iommu_data,
				   unsigned int cmd, unsigned long arg)
{
	struct vfio_iommu *iommu = iommu_data;
	unsigned long minsz;

	if (cmd == VFIO_CHECK_EXTENSION) {
		switch (arg) {
		case VFIO_TYPE1_IOMMU:
			return 1;
		default:
			return 0;
		}
	} else if (cmd == VFIO_IOMMU_GET_INFO) {
		struct vfio_iommu_type1_info info;

		minsz = offsetofend(struct vfio_iommu_type1_info, iova_pgsizes);

		if (copy_from_user(&info, (void __user *)arg, minsz))
			return -EFAULT;

		if (info.argsz < minsz)
			return -EINVAL;

		info.flags = 0;

		info.iova_pgsizes = iommu->domain->ops->pgsize_bitmap;

		return copy_to_user((void __user *)arg, &info, minsz);

	} else if (cmd == VFIO_IOMMU_MAP_DMA) {
		struct vfio_iommu_type1_dma_map map;
		uint32_t mask = VFIO_DMA_MAP_FLAG_READ |
				VFIO_DMA_MAP_FLAG_WRITE;

		minsz = offsetofend(struct vfio_iommu_type1_dma_map, size);

		if (copy_from_user(&map, (void __user *)arg, minsz))
			return -EFAULT;

		if (map.argsz < minsz || map.flags & ~mask)
			return -EINVAL;

		return vfio_dma_do_map(iommu, &map);

	} else if (cmd == VFIO_IOMMU_UNMAP_DMA) {
		struct vfio_iommu_type1_dma_unmap unmap;

		minsz = offsetofend(struct vfio_iommu_type1_dma_unmap, size);

		if (copy_from_user(&unmap, (void __user *)arg, minsz))
			return -EFAULT;

		if (unmap.argsz < minsz || unmap.flags)
			return -EINVAL;

		return vfio_dma_do_unmap(iommu, &unmap);
	}

	return -ENOTTY;
}

static const struct vfio_iommu_driver_ops vfio_iommu_driver_ops_type1 = {
	.name		= "vfio-iommu-type1",
	.owner		= THIS_MODULE,
	.open		= vfio_iommu_type1_open,
	.release	= vfio_iommu_type1_release,
	.ioctl		= vfio_iommu_type1_ioctl,
	.attach_group	= vfio_iommu_type1_attach_group,
	.detach_group	= vfio_iommu_type1_detach_group,
};

static int __init vfio_iommu_type1_init(void)
{
	if (!iommu_present(&pci_bus_type))
		return -ENODEV;

	return vfio_register_iommu_driver(&vfio_iommu_driver_ops_type1);
}

static void __exit vfio_iommu_type1_cleanup(void)
{
	vfio_unregister_iommu_driver(&vfio_iommu_driver_ops_type1);
}

module_init(vfio_iommu_type1_init);
module_exit(vfio_iommu_type1_cleanup);

MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);