anchor.diff:  
   === Enqueue FlowFiles
   
  -
  +Before triggering a Processor to run, it is usually necessary to enqueue FlowFiles for the Processor to process.
  +This can be achieved by using the `enqueue` methods of the `TestRunner` class. The `enqueue` method has several
  +different overrides, and allows data to be added in the form of a `byte[]`, `InputStream`, or `Path`. Each of these
  +methods also supports a variation that allows a `Map<String, String>` to be added to support FlowFile attributes.
  +
  +Additionally, there is an `enqueue` method that takes a var-args of FlowFile objects. This can be useful, for example,
  +to obtain the output of a Processor and then feed this to the input of the Processor. 
   
   
   === Run the Processor
   
  -
  -
  -=== Validate Output Counts
  -
  -
  -
  -=== Validate Output Results
  -
  -
  -
  -=== Mocking Connections
  -
  +After configuring the Controller Services and enqueuing the necessary FlowFiles, the Processor can be triggered
  +to run by calling the `run` method of `TestRunner`. If this method is called without any arguments, it will
  +invoke any method in the Processor with an `@OnScheduled` annotation, call the Processor's `onTrigger` method once,
  +and then run the `@OnUnscheduled` and finally `@OnStopped` methods.
  +
  +If it is desirable to run several iterations of the `onTrigger` method before the other `@OnUnscheduled` and 
  +`@OnStopped` life-cycle events are triggered, the `run(int)` method can be used to specify now many iterations
  +of `onTrigger` should be called.
  +
  +There are times when we want to trigger the Processor to run but not trigger the `@OnUnscheduled` and `@OnStopped`
  +life-cycle events. This is useful, for instance, to inspect the Processor's state before these events occur. This
  +can be achieved using the `run(int, boolean)` and passing `false` as the second argument. After doing this, though,
  +calling the `@OnScheduled` life-cycle methods could cause an issue. As a result, we can now run `onTrigger` again
  +without causing these events to occur by using the `run(int,boolean,boolean)` version of the `run` method and
  +passing `false` as the third argument.
  +
  +If it is useful to test behavior that occurs with multiple threads, this can also be achieved by calling the
  +`setThreadCount` method of `TestRunner`. The default is 1 thread. If using multiple threads, it is important
  +to remember that the `run` call of `TestRunner` specifies how many times the Processor should be triggered, not
  +the number of times that the Processor should be triggered per thread. So, if the thread count is set to 2 but
  +`run(1)` is called, only a single thread will be used. 
  +
  +
  +=== Validate Output
  +
  +After a Processor has finished running, a unit test will generally want to validate that the FlowFiles went where
  +they were expected to go. This can be achieved using the `TestRunners` `assertAllFlowFilesTransferred` and 
  +`assertTransferCount` methods. The former method takes as arguments a Relationship and an integer to dictate how many
  +FlowFiles should have been transferred to that Relationship. The method will fail the unit test unless this number of
  +FlowFiles were transferred to the given Relationship *or* if any FlowFile was transferred to any other Relationship.
  +The `assertTransferCount` method validates only that the FlowFile count was the expected number for the given Relationship.
  +
  +After validating the counts, we can then obtain the actual output FlowFiles via the `getFlowFilesForRelationship` method.
  +This method returns a `List<MockFlowFile>`. It's important to note that the type of the List is `MockFlowFile`, rather
  +than the `FlowFile` interface. This is done because `MockFlowFile` comes with many methods for validating the contents.
  +
  +For example, `MockFlowFile` has methods for asserting that FlowFile Attributes exist (`assertAttributeExists`), asserting
  +that other attributes are not present (`assertAttributeNotExists`), or that Attributes have the correct value
  +(`assertAttributeEquals`, `assertAttributeNotEquals`). Similar methods exist for verifying the contents of the FlowFile.
  +The contents of a FlowFile can be compared to a `byte[]`, and `InputStream`, a file, or a String. If the data is expected
  +to be textual, the String version is preferred, as it provides a more intuitive error message if the output is not
  +as expected. 
  +
  +
  +
  +=== Mocking External Resources
  +
  +One of the biggest problems when testing a NiFi processor that connects to a remote resource is that we don't want to
  +actually connect to some remote resource from a unit test. We can stand up a simple server ourselves in the unit test
  +and configure the Processor to communicate with it, but then we have to understand and implement the server-specific
  +specification and may not be able to properly send back error messages, etc. that we would like for testing.
  +
  +Generally, the approach taken here is to have a method in the Processor that is responsible for obtaining a connection
  +or a client to a remote resource. We generally mark this method as protected. In the unit test, instead of creating
  +the `TestRunner` by calling `TestRunners.newTestRunner(Class)` and providing the Processor class, we instead create
  +a subclass of the Processor in our unit test and use this:
  +
  +[source,java]
  +----
  +@Test
  +public void testConnectionFailure() {
  +	final TestRunner runner = TestRunners.newTestRunner(new MyProcessor() {
  +		protected Client getClient() {
  +			// Return a mocked out client here.
  +			return new Client() {
  +				public void connect() throws IOException {
  +					throw new IOException();
  +				}
  +				
  +				// ...
  +				// other client methods
  +				// ...
  +			};
  +		}
  +	});
  +	
  +	// rest of unit test.
  +}
  +----  
  +
  +This allows us to implement a Client that mocks out all of the network communications and returns the different
  +error results that we want to test, as well as ensure that our logic is correct for handling successful calls
  +to the client.
   
   
   === Additional Testing Capabilities
  +
   In addition to the above-mentioned capabilities provided by the
   testing framework, the TestRunner provides several
   convenience methods for verifying the behavior of a Processor. Methods
  
positive.code: 
  == Introduction
  
  This Developer Guide is written by developers for developers. It is expected that before reading this
  guide, you have a basic understanding of Apache NiFi (incubating) and the concepts of dataflow. If not,
  please see the link:overview.html[NiFi Overview] and the link:user-guide.html[NiFi User Guide] to familiar
  yourself with the concepts of NiFi.
  
  This guide also assumes that the reader is familiar with Java 7 and Apache Maven.
  
  The intent of this guide is to provide the reader with the information needed to understand how NiFi extensions
  are developed and help to explain the thought process behind developing the components.
  
  
  [[components]]
  == NiFi Components
  
  NiFi provides several extension points to provide developers the
  ability to add functionality
  to the application to meet their needs. The following list provides a
  high-level description
  of the most common extension points:
  
  - Processor
      - The Processor interface is the mechanism through which NiFi
  exposes access to
        FlowFiles, their attributes, and their content. The Processor is
  the basic building
        block used to comprise a NiFi dataflow. This interface is used
  to accomplish
        all of the following tasks:
  
          - Create FlowFiles
          - Read FlowFile content
          - Write FlowFile content
          - Read FlowFile attributes
          - Update FlowFile attributes
          - Ingest data
          - Egress data
          - Route data
          - Extract data
          - Modify data
  
  - ReportingTask
      - The ReportingTask interface is a mechanism that NiFi exposes to allow metrics,
        monitoring information, and internal NiFI state to be published to external
        sources, such as log files, e-mail, and remote web services.
  
  - ControllerService
      - A ControllerService provides shared state across Processors, other ControllerServices,
        and ReportingTasks within a single JVM. An example use case may include loading a very
        large dataset into memory. By performing this work in a ControllerService, the data
        can be loaded once and be exposed to all Processors via this service.
  
  - FlowFilePrioritizer
      - The FlowFilePrioritizer interface provides a mechanism by which FlowFiles
        in a queue can be prioritized, or sorted, so that the FlowFiles can be processed in an order
        that is most effective for a particular use case.
  
  - AuthorityProvider
      - An AuthorityProvide is responsible for determining which privileges and roles, if any,
        a given user should be granted.
  
  
  
negative.code: 
  
  
  == How to contribute to Apache NiFi
  
  We are always excited to have contributions from the community - especially from new contributors!
  We are interested in accepting contributions of code, as well as documentation and even artwork that
  can be applied as icons or styling to the application.
  
  
  === Technologies
  
  The back end of Apache NiFi is written in Java. The web tier makes use of JAX-RS and JavaScript is extensively
  used to provide a user interface. We depend on several third-party JavaScript libraries, including D3 and JQuery,
  among others. We make use of Apache Maven for our builds and Git for our version control system.
  
  
  === Where to Start?
  
  link:http://issues.apache.org/jira/browse/NIFI[NiFi's Jira page] can be used to find tickets that are tagged as "beginner",
  or you can dig into any of the tickets for creating Processors. Processors should be self-contained and not rely on other
  outside components (except for Controller Services), so they make for excellent starting points for new NiFi developers to
  get started. This exposes the developer to the NiFi API and is the most extensible part of the dataflow system.
  
  
  === Supplying a contribution
  
  Contributions can be provided either by creating a patch:
  
  `git format-patch`
  
  and attaching that patch to a ticket, or by generating a Pull Request.
  
  
  === Contact Us
  
  The developer mailing list (dev@nifi.incubator.apache.org) is monitored pretty closely, and we tend to respond pretty
  quickly. If you have a question, don't hesitate to shoot us an e-mail - we're here to help! Unfortunately, though, e-mails
  can get lost in the shuffle, so if you do send an e-mail and don't get a response within a day or two, it's our fault - don't
  worry about bothering us. Just ping the mailing list again.
  
  