text:
package almhirt.corex.mongo.aggregaterooteventlog

import scala.language.reflectiveCalls
import scala.concurrent._
import scala.concurrent.duration._
import scalaz._, Scalaz._
import scalaz.Validation.FlatMap._
import akka.actor._
import almhirt.common._
import almhirt.aggregates.AggregateRootId
import almhirt.almfuture.all._
import almhirt.almvalidation.kit._
import almhirt.converters.BinaryConverter
import almhirt.configuration._
import almhirt.context._
import almhirt.akkax._
import almhirt.akkax.reporting._
import almhirt.akkax.reporting.Implicits._
import reactivemongo.bson._
import reactivemongo.api._
import reactivemongo.api.indexes.{ Index ⇒ MIndex }
import reactivemongo.api.indexes.IndexType
import reactivemongo.core.commands.GetLastError
import com.typesafe.config.Config
import almhirt.reactivemongox._
import play.api.libs.iteratee._

object MongoAggregateRootEventLog {
  def propsRaw(
    db: DB with DBMetaCommands,
    collectionName: String,
    serializeAggregateRootEvent: AggregateRootEvent ⇒ AlmValidation[BSONDocument],
    deserializeAggregateRootEvent: BSONDocument ⇒ AlmValidation[AggregateRootEvent],
    writeWarnThreshold: FiniteDuration,
    readWarnThreshold: FiniteDuration,
    retrySettings: RetrySettings,
    rwMode: ReadWriteMode.SupportsReading)(implicit ctx: AlmhirtContext): Props =
    Props(new MongoAggregateRootEventLogImpl(
      db,
      collectionName,
      serializeAggregateRootEvent,
      deserializeAggregateRootEvent,
      writeWarnThreshold,
      readWarnThreshold,
      retrySettings,
      rwMode))

  def propsWithDb(
    db: DB with DBMetaCommands,
    serializeAggregateRootEvent: AggregateRootEvent ⇒ AlmValidation[BSONDocument],
    deserializeAggregateRootEvent: BSONDocument ⇒ AlmValidation[AggregateRootEvent],
    configName: Option[String] = None)(implicit ctx: AlmhirtContext): AlmValidation[Props] = {
    import almhirt.configuration._
    import almhirt.almvalidation.kit._
    val path = "almhirt.components.event-logs.aggregate-root-event-log" + configName.map("." + _).getOrElse("")
    (for {
      section ← ctx.config.v[com.typesafe.config.Config](path)
      collectionName ← section.v[String]("collection-name")
      writeWarnThreshold ← section.v[FiniteDuration]("write-warn-threshold")
      readWarnThreshold ← section.v[FiniteDuration]("read-warn-threshold")
      retrySettings ← section.v[RetrySettings]("retry-settings")
      readOnly ← section.v[Boolean]("read-only")
      rwMode ← section.v[ReadWriteMode.SupportsReading]("read-write-mode")
    } yield propsRaw(
      db,
      collectionName,
      serializeAggregateRootEvent,
      deserializeAggregateRootEvent,
      writeWarnThreshold,
      readWarnThreshold,
      retrySettings,
      rwMode)).leftMap(p ⇒ ConfigurationProblem(s"""Failed to configure MongoAggregateRootEventLog @$path.""", cause = Some(p)))
  }

  def propsWithConnection(
    connection: MongoConnection,
    serializeAggregateRootEvent: AggregateRootEvent ⇒ AlmValidation[BSONDocument],
    deserializeAggregateRootEvent: BSONDocument ⇒ AlmValidation[AggregateRootEvent],
    configName: Option[String] = None)(implicit ctx: AlmhirtContext): AlmValidation[Props] = {
    import almhirt.configuration._
    import almhirt.almvalidation.kit._
    val path = "almhirt.components.event-logs.aggregate-root-event-log" + configName.map("." + _).getOrElse("")
    for {
      section ← ctx.config.v[com.typesafe.config.Config](path)
      dbName ← section.v[String]("db-name")
      db ← inTryCatch { Await.result(connection.database(dbName)(ctx.futuresContext), 10.seconds) }
      props ← propsWithDb(
        db,
        serializeAggregateRootEvent,
        deserializeAggregateRootEvent,
        configName)
    } yield props
  }

}

private[almhirt] class MongoAggregateRootEventLogImpl(
    db: DB with DBMetaCommands,
    collectionName: String,
    serializeAggregateRootEvent: AggregateRootEvent ⇒ AlmValidation[BSONDocument],
    deserializeAggregateRootEvent: BSONDocument ⇒ AlmValidation[AggregateRootEvent],
    writeWarnThreshold: FiniteDuration,
    readWarnThreshold: FiniteDuration,
    retrySettings: RetrySettings,
    rwMode: ReadWriteMode.SupportsReading)(implicit override val almhirtContext: AlmhirtContext) extends AlmActor with AlmActorLogging with ControllableActor with StatusReportingActor {

  import almhirt.eventlog.AggregateRootEventLog._

  override val componentControl = LocalComponentControl(self, ComponentControlActions.none, Some(logWarning))

  logInfo(s"""|collectionName: $collectionName
              |read-write-mode: $rwMode""".stripMargin)

  implicit val defaultExecutor = almhirtContext.futuresContext
  val serializationExecutor = almhirtContext.futuresContext

  val projectionFilter = BSONDocument("event" → 1)

  val noSorting = BSONDocument()
  val sortByVersion = BSONDocument("version" → 1)

  private var numEventsReceived = 0L
  private var numEventsReceivedWhileUninitialized = 0L
  private val numDuplicateEventsReceived = new java.util.concurrent.atomic.AtomicLong(0L)
  private val numEventsStored = new java.util.concurrent.atomic.AtomicLong(0L)
  private val numEventsNotStored = new java.util.concurrent.atomic.AtomicLong(0L)

  private val fromBsonDocToAggregateRootEvent: Enumeratee[BSONDocument, AggregateRootEvent] =
    Enumeratee.mapM[BSONDocument] { doc ⇒ Future { documentToAggregateRootEvent(doc).resultOrEscalate }(serializationExecutor) }

  def aggregateRootEventToDocument(aggregateRootEvent: AggregateRootEvent): AlmValidation[BSONDocument] = {
    (for {
      serialized ← serializeAggregateRootEvent(aggregateRootEvent)
    } yield {
      BSONDocument(
        ("_id" → BSONString(aggregateRootEvent.eventId.value)),
        ("aggid" → BSONString(aggregateRootEvent.aggId.value)),
        ("version" → BSONLong(aggregateRootEvent.aggVersion.value)),
        ("type" → BSONString(aggregateRootEvent.getClass().getSimpleName())),
        ("event" → serialized))
    }).leftMap(p ⇒ SerializationProblem(s"""Could not serialize a "${aggregateRootEvent.getClass().getName()}".""", cause = Some(p)))
  }

  def documentToAggregateRootEvent(document: BSONDocument): AlmValidation[AggregateRootEvent] = {
    (document.get("event") match {
      case Some(d: BSONDocument) ⇒
        deserializeAggregateRootEvent(d)
      case Some(x) ⇒
        val msg = s"""Event must be contained as a BSONDocument. It is a "${x.getClass().getName()}"."""
        MappingProblem(msg).failure
      case None ⇒
        NoSuchElementProblem("""BSONDocument for payload(field name = "event") not found""").failure
    }).leftMap { p ⇒
      val docStr = BSONDocument.pretty(document)
      val msg = s"""Could not deserialize BSONDocument with field "_id"=${document.getAs[BSONValue]("_id")} as a domain event."""
      val completeMsg = "$msg\n$docStr"
      val prob = SerializationProblem(completeMsg, cause = Some(p))
      logError(prob.toString)
      prob
    }
  }

  def storeEvent(document: BSONDocument): AlmFuture[Deadline] = {
    rwMode.useForWriteOp { writeConcern ⇒
      val collection = db(collectionName)
      val start = Deadline.now
      for {
        writeResult ← collection.insert(document, writeConcern = writeConcern).toAlmFuture
        _ ← if (writeResult.ok)
          AlmFuture.successful(())
        else {
          val msg = writeResult.writeErrors.mkString(",")
          AlmFuture.failed(PersistenceProblem(msg))
        }
      } yield start
    }
  }

  def commitEvent(event: AggregateRootEvent, respondTo: ActorRef) {
    import almhirt.problem._
    (for {
      serialized ← AlmFuture { aggregateRootEventToDocument(event: AggregateRootEvent) }(serializationExecutor)
      storeRes ← storeEvent(serialized)
    } yield storeRes) onComplete (
      fail ⇒ {
        fail match {
          case ExceptionCaughtProblem(p) ⇒
            p.cause match {
              case Some(CauseIsThrowable(HasAThrowable(dbexn: reactivemongo.core.errors.DatabaseException))) ⇒
                if (dbexn.code == Some(11000)) {
                  logWarning(s"Event(${event.eventId.value}) for aggregate root ${event.aggId.value} already exists")
                  val prob = AlreadyExistsProblem(s"Event(${event.eventId.value}) for aggregate root ${event.aggId.value} already exists", cause = Some(p))
                  respondTo ! AggregateRootEventNotCommitted(event.eventId, prob)
                  numDuplicateEventsReceived.incrementAndGet()
                } else {
                  logError(s"Could not commit aggregate root event:\n$fail")
                  reportMissedEvent(event, CriticalSeverity, fail)
                  reportMajorFailure(fail)
                  respondTo ! AggregateRootEventNotCommitted(event.eventId, fail)
                  numEventsNotStored.incrementAndGet()
                }
              case _ ⇒
                logError(s"Could not commit aggregate root event:\n$fail")
                reportMissedEvent(event, CriticalSeverity, fail)
                reportMajorFailure(fail)
                respondTo ! AggregateRootEventNotCommitted(event.eventId, fail)
                numEventsNotStored.incrementAndGet()
            }
        }
      },
      start ⇒ {
        respondTo ! AggregateRootEventCommitted(event.eventId)
        numEventsStored.incrementAndGet()
        val lap = start.lap
        if (lap > writeWarnThreshold)
          logWarning(s"""Storing aggregate root event "${event.getClass().getSimpleName()}(${event.eventId})" took longer than ${writeWarnThreshold.defaultUnitString}(${lap.defaultUnitString}).""")
      })
  }

  def getAggregateRootEventsDocs(query: BSONDocument, sort: BSONDocument, traverse: TraverseWindow): Enumerator[BSONDocument] = {
    val collection = db(collectionName)
    val enumerator = collection.queryAlm(query, projectionFilter, sort, rwMode.readPreference).traverse(traverse).enumerate[BSONDocument]
    enumerator
  }

  def getAggregateRootEvents(query: BSONDocument, sort: BSONDocument, traverse: TraverseWindow): Enumerator[AggregateRootEvent] = {
    val docsEnumerator = getAggregateRootEventsDocs(query, sort, traverse)
    docsEnumerator.through(fromBsonDocToAggregateRootEvent)
  }

  def createQueryAndSort(m: AggregateRootEventLogQueryManyMessage): (BSONDocument, BSONDocument) = {
    m match {
      case m: GetAllAggregateRootEvents ⇒
        (BSONDocument.empty, BSONDocument.empty)
      case GetAggregateRootEventsFor(aggId, start, end, _) ⇒
        (start, end) match {
          case (FromStart, ToEnd) ⇒
            (BSONDocument("aggid" → BSONString(aggId.value)), sortByVersion)
          case (FromVersion(fromVersion), ToEnd) ⇒
            (BSONDocument(
              "aggid" → BSONString(aggId.value),
              "version" → BSONDocument("$gte" → BSONLong(fromVersion.value))), sortByVersion)
          case (FromStart, ToVersion(toVersion)) ⇒
            (BSONDocument(
              "aggid" → BSONString(aggId.value),
              "version" → BSONDocument("$lte" → BSONLong(toVersion.value))), sortByVersion)
          case (FromVersion(fromVersion), ToVersion(toVersion)) ⇒
            (BSONDocument(
              "aggid" → BSONString(aggId.value),
              "$and" → BSONArray(
                BSONDocument("version" → BSONDocument("$gte" → BSONLong(fromVersion.value))),
                BSONDocument("version" → BSONDocument("$lte" → BSONLong(toVersion.value))))), sortByVersion)
        }
    }
  }

  def fetchAndDispatchAggregateRootEvents(m: AggregateRootEventLogQueryManyMessage, respondTo: ActorRef) {
    val start = Deadline.now
    val (query, sort) = createQueryAndSort(m)
    val eventsEnumerator = getAggregateRootEvents(query, sort, m.traverse)
    val enumeratorWithCallback = eventsEnumerator.onDoneEnumerating({
      val lap = start.lap
      if (lap > readWarnThreshold)
        logWarning(s"""Fetching aggregate root events took longer than ${readWarnThreshold.defaultUnitString}(${lap.defaultUnitString}).""")
    })
    respondTo ! FetchedAggregateRootEvents(enumeratorWithCallback)
  }

  private case object Initialize
  private case object Initialized
  private case class InitializeFailed(prob: Problem)

  def uninitializedReadWrite: Receive = startup() {
    reportsStatusF(onReportRequested = createStatusReport(None)) {
      case Initialize ⇒
        logInfo("Initializing(read/write)")
        val toTry = () ⇒ (for {
          collectinNames ← db.collectionNames
          createonRes ← if (collectinNames.contains(collectionName)) {
            logInfo(s"""Collection "$collectionName" already exists.""")
            Future.successful(false)
          } else {
            logInfo(s"""Collection "$collectionName" does not yet exist.""")
            val collection = db(collectionName)
            collection.indexesManager.ensure(MIndex(List("aggid" → IndexType.Ascending, "version" → IndexType.Descending), name = Some("idx_aggid_version"), unique = false))
          }
        } yield createonRes).toAlmFuture

        context.retryWithLogging[Boolean](
          retryContext = s"Initialize collection $collectionName",
          toTry = toTry,
          onSuccess = createRes ⇒ {
            logInfo(s"""Index on "aggid, version" created: $createRes""")
            self ! Initialized
          },
          onFinalFailure = (t, n, p) ⇒ {
            val prob = MandatoryDataProblem(s"Initialize collection '$collectionName' finally failed after $n attempts and ${t.defaultUnitString}.", cause = Some(p))
            self ! InitializeFailed(PersistenceProblem("Failed to initialize", cause = Some(prob)))
          },
          log = this.log,
          settings = retrySettings,
          actorName = Some("initializes-collection"))

      case Initialized ⇒
        logInfo("Initialized")
        context.become(receiveAggregateRootEventLogMsg)

      case InitializeFailed(prob) ⇒
        logError(s"Initialize failed:\n$prob")
        reportCriticalFailure(prob)
        sys.error(prob.message)

      case m: AggregateRootEventLogMessage ⇒
        val msg = s"""Received domain event log message ${m.getClass().getSimpleName()} while uninitialized."""
        logWarning(msg)
        val problem = ServiceNotReadyProblem(msg)
        m match {
          case CommitAggregateRootEvent(event) ⇒
            numEventsReceivedWhileUninitialized = numEventsReceivedWhileUninitialized + 1L
            sender ! AggregateRootEventNotCommitted(event.eventId, problem)
            reportMissedEvent(event, MajorSeverity, problem)
          case m: GetAllAggregateRootEvents ⇒
            sender ! GetAggregateRootEventsFailed(problem)
          case GetAggregateRootEvent(eventId) ⇒
            sender ! GetAggregateRootEventFailed(eventId, problem)
          case m: GetAggregateRootEventsFor ⇒
            sender ! GetAggregateRootEventsFailed(problem)
        }
    }
  }

  def uninitializedReadOnly: Receive = startup() {
    reportsStatusF(onReportRequested = createStatusReport(None)) {
      case Initialize ⇒
        logInfo("Initializing(read-only)")
        context.retryWithLogging[Unit](
          retryContext = s"Find collection $collectionName",
          toTry = () ⇒ db.collectionNames.toAlmFuture.foldV(
            fail ⇒ fail.failure,
            collectionNames ⇒ {
              if (collectionNames.contains(collectionName))
                ().success
              else
                MandatoryDataProblem(s"""Collection "$collectionName" is not among [${collectionNames.mkString(", ")}] in database "${db.name}".""").failure
            }),
          onSuccess = _ ⇒ { self ! Initialized },
          onFinalFailure = (t, n, p) ⇒ {
            val prob = MandatoryDataProblem(s"Look up collection '$collectionName' finally failed after $n attempts and ${t.defaultUnitString}.", cause = Some(p))
            self ! InitializeFailed(PersistenceProblem("Failed to initialize", cause = Some(prob)))
          },
          log = this.log,
          settings = retrySettings,
          actorName = Some("looks-for-collection"))

      case Initialized ⇒
        logInfo("Initialized")
        context.become(receiveAggregateRootEventLogMsg)

      case InitializeFailed(prob) ⇒
        logError(s"Initialize failed:\n$prob")
        reportCriticalFailure(prob)
        sys.error(prob.message)

      case m: AggregateRootEventLogMessage ⇒
        val msg = s"""Received domain event log message ${m.getClass().getSimpleName()} while uninitialized in read only mode."""
        logWarning(msg)
        val problem = ServiceNotReadyProblem(msg)
        m match {
          case CommitAggregateRootEvent(event) ⇒
            numEventsReceivedWhileUninitialized = numEventsReceivedWhileUninitialized + 1L
            sender ! AggregateRootEventNotCommitted(event.eventId, problem)
          case m: GetAllAggregateRootEvents ⇒
            sender ! GetAggregateRootEventsFailed(problem)
          case GetAggregateRootEvent(eventId) ⇒
            sender ! GetAggregateRootEventFailed(eventId, problem)
          case m: GetAggregateRootEventsFor ⇒
            sender ! GetAggregateRootEventsFailed(problem)
        }
    }
  }

  def receiveAggregateRootEventLogMsg: Receive = running() {
    reportsStatusF(onReportRequested = options ⇒ createStatusReport(Some(db.collection(collectionName).count().map(_.toLong)))(options)) {
      case CommitAggregateRootEvent(event) ⇒
        commitEvent(event, sender())

      case m: AggregateRootEventLogQueryManyMessage ⇒
        fetchAndDispatchAggregateRootEvents(m, sender())

      case GetAggregateRootEvent(eventId) ⇒
        val collection = db(collectionName)
        val query = BSONDocument("_id" → BSONString(eventId.value))
        (for {
          doc ← collection.find(query).cursor(readPreference = rwMode.readPreference).headOption.toAlmFuture
          aggregateRootEvent ← AlmFuture {
            doc match {
              case None    ⇒ None.success
              case Some(d) ⇒ documentToAggregateRootEvent(d).map(Some(_))
            }
          }(serializationExecutor)
        } yield aggregateRootEvent).mapOrRecoverThenPipeTo(
          eventOpt ⇒ FetchedAggregateRootEvent(eventId, eventOpt),
          problem ⇒ {
            logError(problem.toString())
            reportMajorFailure(problem)
            GetAggregateRootEventFailed(eventId, problem)
          })(sender())
    }
  }

  private def createStatusReport(numEvents: Option[AlmFuture[Long]])(options: StatusReportOptions): AlmFuture[StatusReport] = {
    val baseRep = StatusReport("AggregateEventLog").withComponentState(componentState) addMany (
      "number-of-events-received" -> numEventsReceived,
      "number-of-events-received-while-uninitialized" -> numEventsReceivedWhileUninitialized,
      "number-of-duplicate-events-received" -> numDuplicateEventsReceived.get,
      "number-of-events-stored" -> numEventsStored.get,
      "number-of-events-not-stored" -> numEventsNotStored.get,
      "collection-name" -> collectionName)

    for {
      totalEvents ← numEvents match {
        case None      ⇒ AlmFuture.successful(None)
        case Some(fut) ⇒ fut.materializedValidation.map(Some(_))
      }
    } yield baseRep ~ ("events-persisted" -> totalEvents)
  }

  override def receive =
    if (rwMode.supportsWriting)
      uninitializedReadWrite
    else
      uninitializedReadOnly

  override def preStart() {
    super.preStart()
    registerComponentControl()
    registerStatusReporter(description = Some("AggregateEventLog based on MongoDB"))
    context.parent ! ActorMessages.ConsiderMeForReporting
    self ! Initialize
  }

  override def postStop() {
    super.postStop()
    deregisterComponentControl()
    deregisterStatusReporter()
  }

}


text:
package at.illecker.storm.commons.svm.featurevector;

import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import at.illecker.storm.commons.Configuration;
import at.illecker.storm.commons.Dataset;
import at.illecker.storm.commons.postagger.ArkPOSTagger;
import at.illecker.storm.commons.postagger.GatePOSTagger;
import at.illecker.storm.commons.preprocessor.Preprocessor;
import at.illecker.storm.commons.tfidf.TfIdfNormalization;
import at.illecker.storm.commons.tfidf.TfType;
import at.illecker.storm.commons.tfidf.TweetTfIdf;
import at.illecker.storm.commons.tokenizer.Tokenizer;
import at.illecker.storm.commons.tweet.Tweet;
import cmu.arktweetnlp.Tagger.TaggedToken;
import edu.stanford.nlp.ling.TaggedWord;

public class CombinedFeatureVectorGenerator extends FeatureVectorGenerator {
  private static final Logger LOG = LoggerFactory
      .getLogger(CombinedFeatureVectorGenerator.class);

  private final boolean m_useTaggedWords;
  private SentimentFeatureVectorGenerator m_sentimentFeatureVectorGenerator = null;
  private TfIdfFeatureVectorGenerator m_tfidfFeatureVectorGenerator = null;
  private POSFeatureVectorGenerator m_POSFeatureVectorGenerator = null;

  public CombinedFeatureVectorGenerator(boolean useTaggedWords,
      boolean normalizePOSCounts, TweetTfIdf tweetTfIdf) {
    m_useTaggedWords = useTaggedWords;

    m_sentimentFeatureVectorGenerator = new SentimentFeatureVectorGenerator(1);

    m_POSFeatureVectorGenerator = new POSFeatureVectorGenerator(useTaggedWords,
        normalizePOSCounts,
        m_sentimentFeatureVectorGenerator.getFeatureVectorSize() + 1);

    m_tfidfFeatureVectorGenerator = new TfIdfFeatureVectorGenerator(tweetTfIdf,
        m_sentimentFeatureVectorGenerator.getFeatureVectorSize()
            + m_POSFeatureVectorGenerator.getFeatureVectorSize() + 1);

    LOG.info("VectorSize: " + getFeatureVectorSize());
  }

  @Override
  public int getFeatureVectorSize() {
    return m_sentimentFeatureVectorGenerator.getFeatureVectorSize()
        + m_POSFeatureVectorGenerator.getFeatureVectorSize()
        + m_tfidfFeatureVectorGenerator.getFeatureVectorSize();
  }

  @Override
  public Map<Integer, Double> generateFeatureVectorFromTaggedWords(
      List<TaggedWord> tweet) {
    if (!m_useTaggedWords) {
      throw new RuntimeException(
          "Use TaggedWords was set to false! generateFeatureVectorFromTaggedWords is not applicable!");
    }

    Map<Integer, Double> featureVector = m_sentimentFeatureVectorGenerator
        .generateFeatureVectorFromTaggedWords(tweet);

    featureVector.putAll(m_POSFeatureVectorGenerator
        .generateFeatureVectorFromTaggedWords(tweet));

    featureVector.putAll(m_tfidfFeatureVectorGenerator
        .generateFeatureVectorFromTaggedWords(tweet));

    return featureVector;
  }

  @Override
  public Map<Integer, Double> generateFeatureVectorFromTaggedTokens(
      List<TaggedToken> tweet) {
    if (m_useTaggedWords) {
      throw new RuntimeException(
          "Use TaggedWords was set to true! generateFeatureVectorFromTaggedTokens is not applicable!");
    }

    Map<Integer, Double> featureVector = m_sentimentFeatureVectorGenerator
        .generateFeatureVectorFromTaggedTokens(tweet);

    featureVector.putAll(m_POSFeatureVectorGenerator
        .generateFeatureVectorFromTaggedTokens(tweet));

    featureVector.putAll(m_tfidfFeatureVectorGenerator
        .generateFeatureVectorFromTaggedTokens(tweet));

    return featureVector;
  }

  public static void main(String[] args) {
    boolean extendedTest = false;
    boolean useArkPOSTagger = true;
    boolean usePOSTags = true; // use POS tags in terms
    Preprocessor preprocessor = Preprocessor.getInstance();

    // load tweets
    List<Tweet> tweets = null;
    if (extendedTest) {
      // SemEval2013
      Dataset dataset = Configuration.getDataSetSemEval2013();
      tweets = dataset.getTrainTweets(true);
    } else { // test tweets
      tweets = Tweet.getTestTweets();
    }

    // Tokenize
    List<List<String>> tokenizedTweets = Tokenizer.tokenizeTweets(tweets);

    if (useArkPOSTagger) {
      ArkPOSTagger arkPOSTagger = ArkPOSTagger.getInstance();

      // Preprocess only
      long startTime = System.currentTimeMillis();
      List<List<String>> preprocessedTweets = preprocessor
          .preprocessTweets(tokenizedTweets);
      LOG.info("Preprocess finished after "
          + (System.currentTimeMillis() - startTime) + " ms");

      // Ark POS Tagging
      startTime = System.currentTimeMillis();
      List<List<TaggedToken>> taggedTweets = arkPOSTagger
          .tagTweets(preprocessedTweets);
      LOG.info("Ark POS Tagger finished after "
          + (System.currentTimeMillis() - startTime) + " ms");

      // Generate CombinedFeatureVectorGenerator
      TweetTfIdf tweetTfIdf = TweetTfIdf.createFromTaggedTokens(taggedTweets,
          TfType.RAW, TfIdfNormalization.COS, usePOSTags);
      CombinedFeatureVectorGenerator cfvg = new CombinedFeatureVectorGenerator(
          false, true, tweetTfIdf);

      // Combined Feature Vector Generation
      for (List<TaggedToken> taggedTokens : taggedTweets) {
        Map<Integer, Double> combinedFeatureVector = cfvg
            .generateFeatureVectorFromTaggedTokens(taggedTokens);

        // Build feature vector string
        String featureVectorStr = "";
        for (Map.Entry<Integer, Double> feature : combinedFeatureVector
            .entrySet()) {
          featureVectorStr += " " + feature.getKey() + ":" + feature.getValue();
        }
        LOG.info("Tweet: '" + taggedTokens + "'");
        LOG.info("CombinedFeatureVector: " + featureVectorStr);
      }

    } else {
      GatePOSTagger gatePOSTagger = GatePOSTagger.getInstance();

      // Preprocess and tag
      long startTime = System.currentTimeMillis();
      List<List<TaggedWord>> preprocessedTweets = preprocessor
          .preprocessAndTagTweets(tokenizedTweets);
      LOG.info("PreprocessAndTag finished after "
          + (System.currentTimeMillis() - startTime) + " ms");

      // Gate POS Tagging
      startTime = System.currentTimeMillis();
      List<List<TaggedWord>> taggedTweets = gatePOSTagger
          .tagTweets(preprocessedTweets);
      LOG.info("Gate POS Tagger finished after "
          + (System.currentTimeMillis() - startTime) + " ms");

      // Generate CombinedFeatureVectorGenerator
      TweetTfIdf tweetTfIdf = TweetTfIdf.createFromTaggedWords(taggedTweets,
          TfType.RAW, TfIdfNormalization.COS, usePOSTags);
      CombinedFeatureVectorGenerator cfvg = new CombinedFeatureVectorGenerator(
          true, true, tweetTfIdf);

      // Combined Feature Vector Generation
      for (List<TaggedWord> taggedWords : taggedTweets) {
        Map<Integer, Double> combinedFeatureVector = cfvg
            .generateFeatureVectorFromTaggedWords(taggedWords);

        // Build feature vector string
        String featureVectorStr = "";
        for (Map.Entry<Integer, Double> feature : combinedFeatureVector
            .entrySet()) {
          featureVectorStr += " " + feature.getKey() + ":" + feature.getValue();
        }
        LOG.info("Tweet: '" + taggedWords + "'");
        LOG.info("CombinedFeatureVector: " + featureVectorStr);
      }
    }
  }

}

redpajama_set_name: RedPajamaGithub


text:
// Package signer implements a CA signer that uses keys stored on local disk.
package signer

import (
	"context"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"strings"
	"time"

	capi "k8s.io/api/certificates/v1beta1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apiserver/pkg/server/dynamiccertificates"
	certificatesinformers "k8s.io/client-go/informers/certificates/v1beta1"
	clientset "k8s.io/client-go/kubernetes"
	capihelper "k8s.io/kubernetes/pkg/apis/certificates/v1beta1"
	"k8s.io/kubernetes/pkg/controller/certificates"
	"k8s.io/kubernetes/pkg/controller/certificates/authority"
)

type CSRSigningController struct {
	certificateController *certificates.CertificateController
	dynamicCertReloader   dynamiccertificates.ControllerRunner
}

func NewCSRSigningController(
	client clientset.Interface,
	csrInformer certificatesinformers.CertificateSigningRequestInformer,
	caFile, caKeyFile string,
	certTTL time.Duration,
) (*CSRSigningController, error) {
	signer, err := newSigner(caFile, caKeyFile, client, certTTL)
	if err != nil {
		return nil, err
	}

	return &CSRSigningController{
		certificateController: certificates.NewCertificateController(
			"csrsigning",
			client,
			csrInformer,
			signer.handle,
		),
		dynamicCertReloader: signer.caProvider.caLoader,
	}, nil
}

// Run the main goroutine responsible for watching and syncing jobs.
func (c *CSRSigningController) Run(workers int, stopCh <-chan struct{}) {
	go c.dynamicCertReloader.Run(workers, stopCh)

	c.certificateController.Run(workers, stopCh)
}

type signer struct {
	caProvider *caProvider

	client  clientset.Interface
	certTTL time.Duration
}

func newSigner(caFile, caKeyFile string, client clientset.Interface, certificateDuration time.Duration) (*signer, error) {
	caProvider, err := newCAProvider(caFile, caKeyFile)
	if err != nil {
		return nil, err
	}

	ret := &signer{
		caProvider: caProvider,
		client:     client,
		certTTL:    certificateDuration,
	}
	return ret, nil
}

func (s *signer) handle(csr *capi.CertificateSigningRequest) error {
	// Ignore unapproved requests
	if !certificates.IsCertificateRequestApproved(csr) {
		return nil
	}

	// Fast-path to avoid any additional processing if the CSRs signerName does
	// not have a 'kubernetes.io/' prefix.
	if !strings.HasPrefix(*csr.Spec.SignerName, "kubernetes.io/") {
		return nil
	}

	x509cr, err := capihelper.ParseCSR(csr.Spec.Request)
	if err != nil {
		return fmt.Errorf("unable to parse csr %q: %v", csr.Name, err)
	}
	if !requestValidForSignerName(x509cr, csr.Spec.Usages, *csr.Spec.SignerName) {
		// TODO: mark the CertificateRequest as being in a terminal state and
		//  communicate to the user why the request has been refused.
		return nil
	}
	cert, err := s.sign(x509cr, csr.Spec.Usages)
	if err != nil {
		return fmt.Errorf("error auto signing csr: %v", err)
	}
	csr.Status.Certificate = cert
	_, err = s.client.CertificatesV1beta1().CertificateSigningRequests().UpdateStatus(context.TODO(), csr, metav1.UpdateOptions{})
	if err != nil {
		return fmt.Errorf("error updating signature for csr: %v", err)
	}
	return nil
}

func (s *signer) sign(x509cr *x509.CertificateRequest, usages []capi.KeyUsage) ([]byte, error) {
	currCA, err := s.caProvider.currentCA()
	if err != nil {
		return nil, err
	}
	der, err := currCA.Sign(x509cr.Raw, authority.PermissiveSigningPolicy{
		TTL:    s.certTTL,
		Usages: usages,
	})
	if err != nil {
		return nil, err
	}
	return pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: der}), nil
}

func requestValidForSignerName(req *x509.CertificateRequest, usages []capi.KeyUsage, signerName string) bool {
	// Only handle CSRs with the specific known signerNames.
	switch signerName {
	case capi.KubeletServingSignerName:
		return capihelper.IsKubeletServingCSR(req, usages)
	case capi.KubeAPIServerClientKubeletSignerName:
		return capihelper.IsKubeletClientCSR(req, usages)
	case capi.KubeAPIServerClientSignerName:
		return validAPIServerClientUsages(usages)
	case capi.LegacyUnknownSignerName:
		// No restrictions are applied to the legacy-unknown signerName to
		// maintain backward compatibility in v1beta1.
		return true
	default:
		return false
	}
}

func validAPIServerClientUsages(usages []capi.KeyUsage) bool {
	hasClientAuth := false
	for _, u := range usages {
		switch u {
		// these usages are optional
		case capi.UsageDigitalSignature, capi.UsageKeyEncipherment:
		case capi.UsageClientAuth:
			hasClientAuth = true
		default:
			return false
		}
	}
	return hasClientAuth
}


text:
package com.intellij.lang.java;

import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.editorActions.CodeDocumentationUtil;
import com.intellij.codeInsight.javadoc.JavaDocExternalFilter;
import com.intellij.codeInsight.javadoc.JavaDocInfoGenerator;
import com.intellij.codeInsight.javadoc.JavaDocUtil;
import com.intellij.lang.CodeDocumentationAwareCommenter;
import com.intellij.lang.LangBundle;
import com.intellij.lang.LanguageCommenters;
import com.intellij.lang.documentation.CodeDocumentationProvider;
import com.intellij.lang.documentation.ExternalDocumentationProvider;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.VirtualFileSystem;
import com.intellij.openapi.vfs.ex.http.HttpFileSystem;
import com.intellij.psi.*;
import com.intellij.psi.impl.beanProperties.BeanPropertyElement;
import com.intellij.psi.impl.source.javadoc.PsiDocParamRef;
import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTag;
import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

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

/**
 * @author Maxim.Mossienko
 */
public class JavaDocumentationProvider implements CodeDocumentationProvider, ExternalDocumentationProvider {
  private static final Logger LOG = Logger.getInstance("#" + JavaDocumentationProvider.class.getName());
  private static final String LINE_SEPARATOR = "\n";

  @NonNls private static final String PARAM_TAG = "@param";
  @NonNls private static final String RETURN_TAG = "@return";
  @NonNls private static final String THROWS_TAG = "@throws";
  @NonNls public static final String HTML_EXTENSION = ".html";
  @NonNls public static final String PACKAGE_SUMMARY_FILE = "package-summary.html";

  public String getQuickNavigateInfo(PsiElement element, PsiElement originalElement) {
    if (element instanceof PsiClass) {
      return generateClassInfo((PsiClass)element);
    }
    else if (element instanceof PsiMethod) {
      return generateMethodInfo((PsiMethod)element);
    }
    else if (element instanceof PsiField) {
      return generateFieldInfo((PsiField)element);
    }
    else if (element instanceof PsiVariable) {
      return generateVariableInfo((PsiVariable)element);
    }
    else if (element instanceof PsiPackage) {
      return generatePackageInfo((PsiPackage)element);
    }
    else if (element instanceof BeanPropertyElement) {
      return generateMethodInfo(((BeanPropertyElement) element).getMethod());
    }
    return null;
  }

  public List<String> getUrlFor(final PsiElement element, final PsiElement originalElement) {
    return getExternalJavaDocUrl(element);
  }

  private static void newLine(StringBuffer buffer) {
    // Don't know why space has to be added after newline for good text alignment...
    buffer.append("\n ");
  }

  private static void generateType(@NonNls StringBuffer buffer, PsiType type, PsiElement context) {
    if (type instanceof PsiPrimitiveType) {
      buffer.append(type.getCanonicalText());

      return;
    }

    if (type instanceof PsiWildcardType) {
      PsiWildcardType wc = ((PsiWildcardType)type);
      PsiType bound = wc.getBound();

      buffer.append("?");

      if (bound != null) {
        buffer.append(wc.isExtends() ? " extends " : " super ");
        generateType(buffer, bound, context);
      }
    }

    if (type instanceof PsiArrayType) {
      generateType(buffer, ((PsiArrayType)type).getComponentType(), context);
      if (type instanceof PsiEllipsisType) {
        buffer.append("...");
      }
      else {
        buffer.append("[]");
      }

      return;
    }

    if (type instanceof PsiClassType) {
      PsiClassType.ClassResolveResult result = ((PsiClassType)type).resolveGenerics();
      PsiClass psiClass = result.getElement();
      PsiSubstitutor psiSubst = result.getSubstitutor();

      if (psiClass == null || psiClass instanceof PsiTypeParameter) {
        buffer.append(type.getPresentableText());
        return;
      }

      buffer.append(JavaDocUtil.getShortestClassName(psiClass, context));

      if (psiClass.hasTypeParameters()) {
        StringBuffer subst = new StringBuffer();
        boolean goodSubst = true;

        PsiTypeParameter[] params = psiClass.getTypeParameters();

        subst.append("<");
        for (int i = 0; i < params.length; i++) {
          PsiType t = psiSubst.substitute(params[i]);

          if (t == null) {
            goodSubst = false;
            break;
          }

          generateType(subst, t, context);

          if (i < params.length - 1) {
            subst.append(", ");
          }
        }

        if (goodSubst) {
          subst.append(">");
          String text = subst.toString();

          buffer.append(text);
        }
      }
    }
  }

  private static void generateInitializer(StringBuffer buffer, PsiVariable variable) {
    PsiExpression initializer = variable.getInitializer();
    if (initializer != null) {
      String text = initializer.getText().trim();
      int index1 = text.indexOf('\n');
      if (index1 < 0) index1 = text.length();
      int index2 = text.indexOf('\r');
      if (index2 < 0) index2 = text.length();
      int index = Math.min(index1, index2);
      boolean trunc = index < text.length();
      text = text.substring(0, index);
      buffer.append(" = ");
      buffer.append(text);
      if (trunc) {
        buffer.append("...");
      }
    }
  }

  private static void generateModifiers(StringBuffer buffer, PsiElement element) {
    String modifiers = PsiFormatUtil.formatModifiers(element, PsiFormatUtil.JAVADOC_MODIFIERS_ONLY);

    if (modifiers.length() > 0) {
      buffer.append(modifiers);
      buffer.append(" ");
    }
  }

  private static String generatePackageInfo(PsiPackage aPackage) {
    return aPackage.getQualifiedName();
  }

  @SuppressWarnings({"HardCodedStringLiteral"})
  private static String generateClassInfo(PsiClass aClass) {
    StringBuffer buffer = new StringBuffer();

    if (aClass instanceof PsiAnonymousClass) return LangBundle.message("java.terms.anonymous.class");

    PsiFile file = aClass.getContainingFile();
    final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(aClass.getProject()).getFileIndex();
    VirtualFile vFile = file.getVirtualFile();
    if (vFile != null && (fileIndex.isInLibrarySource(vFile) || fileIndex.isInLibraryClasses(vFile))) {
      final List<OrderEntry> orderEntries = fileIndex.getOrderEntriesForFile(vFile);
      if (orderEntries.size() > 0) {
        final OrderEntry orderEntry = orderEntries.get(0);
        buffer.append("[").append(orderEntry.getPresentableName()).append("] ");
      }
    }
    else {
      final Module module = ModuleUtil.findModuleForPsiElement(file);
      if (module != null) {
        buffer.append('[').append(module.getName()).append("] ");
      }
    }

    if (file instanceof PsiJavaFile) {
      String packageName = ((PsiJavaFile)file).getPackageName();
      if (packageName.length() > 0) {
        buffer.append(packageName);
        newLine(buffer);
      }
    }

    generateModifiers(buffer, aClass);

    final String classString = aClass.isAnnotationType() ? "java.terms.annotation.interface"
                               : aClass.isInterface()
                                 ? "java.terms.interface"
                                 : aClass instanceof PsiTypeParameter
                                   ? "java.terms.type.parameter"
                                   : aClass.isEnum() ? "java.terms.enum" : "java.terms.class";
    buffer.append(LangBundle.message(classString)).append(" ");

    buffer.append(JavaDocUtil.getShortestClassName(aClass, aClass));

    if (aClass.hasTypeParameters()) {
      PsiTypeParameter[] parms = aClass.getTypeParameters();

      buffer.append("<");

      for (int i = 0; i < parms.length; i++) {
        PsiTypeParameter p = parms[i];

        buffer.append(p.getName());

        PsiClassType[] refs = p.getExtendsList().getReferencedTypes();

        if (refs.length > 0) {
          buffer.append(" extends ");

          for (int j = 0; j < refs.length; j++) {
            generateType(buffer, refs[j], aClass);

            if (j < refs.length - 1) {
              buffer.append(" & ");
            }
          }
        }

        if (i < parms.length - 1) {
          buffer.append(", ");
        }
      }

      buffer.append(">");
    }

    PsiClassType[] refs;
    if (!aClass.isEnum() && !aClass.isAnnotationType()) {
      PsiReferenceList extendsList = aClass.getExtendsList();
      refs = extendsList == null ? PsiClassType.EMPTY_ARRAY : extendsList.getReferencedTypes();
      if (refs.length > 0 || !aClass.isInterface() && !"java.lang.Object".equals(aClass.getQualifiedName())) {
        buffer.append(" extends ");
        if (refs.length == 0) {
          buffer.append("Object");
        }
        else {
          for (int i = 0; i < refs.length; i++) {
            generateType(buffer, refs[i], aClass);

            if (i < refs.length - 1) {
              buffer.append(", ");
            }
          }
        }
      }
    }

    refs = aClass.getImplementsListTypes();
    if (refs.length > 0) {
      newLine(buffer);
      buffer.append("implements ");
      for (int i = 0; i < refs.length; i++) {
        generateType(buffer, refs[i], aClass);

        if (i < refs.length - 1) {
          buffer.append(", ");
        }
      }
    }

    return buffer.toString();
  }

  @SuppressWarnings({"HardCodedStringLiteral"})
  public static String generateMethodInfo(PsiMethod method) {
    StringBuffer buffer = new StringBuffer();

    PsiClass parentClass = method.getContainingClass();

    if (parentClass != null) {
      buffer.append(JavaDocUtil.getShortestClassName(parentClass, method));
      newLine(buffer);
    }

    generateModifiers(buffer, method);

    PsiTypeParameter[] params = method.getTypeParameters();

    if (params.length > 0) {
      buffer.append("<");
      for (int i = 0; i < params.length; i++) {
        PsiTypeParameter param = params[i];

        buffer.append(param.getName());

        PsiClassType[] extendees = param.getExtendsList().getReferencedTypes();

        if (extendees.length > 0) {
          buffer.append(" extends ");

          for (int j = 0; j < extendees.length; j++) {
            generateType(buffer, extendees[j], method);

            if (j < extendees.length - 1) {
              buffer.append(" & ");
            }
          }
        }

        if (i < params.length - 1) {
          buffer.append(", ");
        }
      }
      buffer.append("> ");
    }

    if (method.getReturnType() != null) {
      generateType(buffer, method.getReturnType(), method);
      buffer.append(" ");
    }

    buffer.append(method.getName());

    buffer.append(" (");
    PsiParameter[] parms = method.getParameterList().getParameters();
    for (int i = 0; i < parms.length; i++) {
      PsiParameter parm = parms[i];
      generateType(buffer, parm.getType(), method);
      buffer.append(" ");
      if (parm.getName() != null) {
        buffer.append(parm.getName());
      }
      if (i < parms.length - 1) {
        buffer.append(", ");
      }
    }

    buffer.append(")");

    PsiClassType[] refs = method.getThrowsList().getReferencedTypes();
    if (refs.length > 0) {
      newLine(buffer);
      buffer.append(" throws ");
      for (int i = 0; i < refs.length; i++) {
        PsiClass throwsClass = refs[i].resolve();

        if (throwsClass != null) {
          buffer.append(JavaDocUtil.getShortestClassName(throwsClass, method));
        }
        else {
          buffer.append(refs[i].getPresentableText());
        }

        if (i < refs.length - 1) {
          buffer.append(", ");
        }
      }
    }

    return buffer.toString();
  }

  private static String generateFieldInfo(PsiField field) {
    StringBuffer buffer = new StringBuffer();
    PsiClass parentClass = field.getContainingClass();

    if (parentClass != null && !(parentClass instanceof PsiAnonymousClass)) {
      buffer.append(JavaDocUtil.getShortestClassName(parentClass, field));
      newLine(buffer);
    }

    generateModifiers(buffer, field);

    generateType(buffer, field.getType(), field);
    buffer.append(" ");
    buffer.append(field.getName());

    generateInitializer(buffer, field);

    return buffer.toString();
  }

  private static String generateVariableInfo(PsiVariable variable) {
    StringBuffer buffer = new StringBuffer();

    generateModifiers(buffer, variable);

    generateType(buffer, variable.getType(), variable);

    buffer.append(" ");

    buffer.append(variable.getName());
    generateInitializer(buffer, variable);

    return buffer.toString();
  }

  public PsiComment findExistingDocComment(final PsiComment comment) {
    if (comment instanceof PsiDocComment) {
      final PsiDocCommentOwner owner = ((PsiDocComment)comment).getOwner();
      if (owner != null) {
        return owner.getDocComment();
      }
    }
    return null;
  }

  public String generateDocumentationContentStub(PsiComment _comment) {
    final PsiDocCommentOwner commentOwner = ((PsiDocComment)_comment).getOwner();
    final Project project = commentOwner.getProject();
    final StringBuilder builder = StringBuilderSpinAllocator.alloc();
    try {
      final CodeDocumentationAwareCommenter commenter = (CodeDocumentationAwareCommenter)LanguageCommenters.INSTANCE
        .forLanguage(commentOwner.getLanguage());
      if (commentOwner instanceof PsiMethod) {
        PsiMethod psiMethod = (PsiMethod)commentOwner;
        final PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
        final Map<String, String> param2Description = new HashMap<String, String>();
        final PsiMethod[] superMethods = psiMethod.findSuperMethods();
        for (PsiMethod superMethod : superMethods) {
          final PsiDocComment comment = superMethod.getDocComment();
          if (comment != null) {
            final PsiDocTag[] params = comment.findTagsByName("param");
            for (PsiDocTag param : params) {
              final PsiElement[] dataElements = param.getDataElements();
              if (dataElements != null) {
                String paramName = null;
                for (PsiElement dataElement : dataElements) {
                  if (dataElement instanceof PsiDocParamRef) {
                    paramName = dataElement.getReference().getCanonicalText();
                    break;
                  }
                }
                if (paramName != null) {
                  param2Description.put(paramName, param.getText());
                }
              }
            }
          }
        }
        for (PsiParameter parameter : parameters) {
          String description = param2Description.get(parameter.getName());
          if (description != null) {
            builder.append(CodeDocumentationUtil.createDocCommentLine("", project, commenter));
            if (description.indexOf('\n') > -1) description = description.substring(0, description.lastIndexOf('\n'));
            builder.append(description);
          }
          else {
            builder.append(CodeDocumentationUtil.createDocCommentLine(PARAM_TAG, project, commenter));
            builder.append(parameter.getName());
          }
          builder.append(LINE_SEPARATOR);
        }

        final PsiTypeParameterList typeParameterList = psiMethod.getTypeParameterList();
        if (typeParameterList != null) {
          createTypeParamsListComment(builder, project, commenter, typeParameterList);
        }
        if (psiMethod.getReturnType() != null && psiMethod.getReturnType() != PsiType.VOID) {
          builder.append(CodeDocumentationUtil.createDocCommentLine(RETURN_TAG, project, commenter));
          builder.append(LINE_SEPARATOR);
        }

        final PsiJavaCodeReferenceElement[] references = psiMethod.getThrowsList().getReferenceElements();
        for (PsiJavaCodeReferenceElement reference : references) {
          builder.append(CodeDocumentationUtil.createDocCommentLine(THROWS_TAG, project, commenter));
          builder.append(reference.getText());
          builder.append(LINE_SEPARATOR);
        }
      }
      else if (commentOwner instanceof PsiClass) {
        final PsiTypeParameterList typeParameterList = ((PsiClass)commentOwner).getTypeParameterList();
        if (typeParameterList != null) {
          createTypeParamsListComment(builder, project, commenter, typeParameterList);
        }
      }
      return builder.length() > 0 ? builder.toString() : null;
    }
    finally {
      StringBuilderSpinAllocator.dispose(builder);
    }
  }

  private static void createTypeParamsListComment(final StringBuilder buffer,
                                                  final Project project,
                                                  final CodeDocumentationAwareCommenter commenter,
                                                  final PsiTypeParameterList typeParameterList) {
    final PsiTypeParameter[] typeParameters = typeParameterList.getTypeParameters();
    for (PsiTypeParameter typeParameter : typeParameters) {
      buffer.append(CodeDocumentationUtil.createDocCommentLine(PARAM_TAG, project, commenter));
      buffer.append("<").append(typeParameter.getName()).append(">");
      buffer.append(LINE_SEPARATOR);
    }
  }

  public String generateDoc(final PsiElement element, final PsiElement originalElement) {
    if (element instanceof PsiMethodCallExpression) {
      return getMethodCandidateInfo((PsiMethodCallExpression)element);
    }

    //external documentation finder
    return generateExternalJavadoc(element);
  }

  public PsiElement getDocumentationElementForLookupItem(final PsiManager psiManager, final Object object, final PsiElement element) {
    return null;
  }

  @Nullable
  public static String generateExternalJavadoc(final PsiElement element) {
    final JavaDocInfoGenerator javaDocInfoGenerator = new JavaDocInfoGenerator(element.getProject(), element);
    final List<String> docURLs = getExternalJavaDocUrl(element);
    return JavaDocExternalFilter.filterInternalDocInfo(javaDocInfoGenerator.generateDocInfo(docURLs));
  }

  @Nullable
  private static String fetchExternalJavadoc(final PsiElement element, String fromUrl, JavaDocExternalFilter filter) {
    try {
      String externalDoc = filter.getExternalDocInfoForElement(fromUrl, element);
      if (externalDoc != null && externalDoc.length() > 0) {
        return externalDoc;
      }
    }
    catch (Exception e) {
      //try to generate some javadoc
    }
    return null;
  }

  private String getMethodCandidateInfo(PsiMethodCallExpression expr) {
    final PsiResolveHelper rh = JavaPsiFacade.getInstance(expr.getProject()).getResolveHelper();
    final CandidateInfo[] candidates = rh.getReferencedMethodCandidates(expr, true);
    final String text = expr.getText();
    if (candidates.length > 0) {
      @NonNls final StringBuffer sb = new StringBuffer();

      for (final CandidateInfo candidate : candidates) {
        final PsiElement element = candidate.getElement();

        if (!(element instanceof PsiMethod)) {
          continue;
        }

        final String str = PsiFormatUtil.formatMethod((PsiMethod)element, candidate.getSubstitutor(),
                                                      PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.SHOW_PARAMETERS,
                                                      PsiFormatUtil.SHOW_TYPE);
        createElementLink(sb, element, StringUtil.escapeXml(str));
      }

      return CodeInsightBundle.message("javadoc.candiates", text, sb);
    }

    return CodeInsightBundle.message("javadoc.candidates.not.found", text);
  }

  private static void createElementLink(@NonNls final StringBuffer sb, final PsiElement element, final String str) {
    sb.append("  <a href=\"psi_element://");
    sb.append(JavaDocUtil.getReferenceText(element.getProject(), element));
    sb.append("\">");
    sb.append(str);
    sb.append("</a>");
    sb.append("<br>");
  }

  @Nullable
  public static List<String> getExternalJavaDocUrl(final PsiElement element) {
    List<String> urls = null;

    if (element instanceof PsiClass) {
      urls = findUrlForClass((PsiClass)element);
    }
    else if (element instanceof PsiField) {
      PsiField field = (PsiField)element;
      PsiClass aClass = field.getContainingClass();
      if (aClass != null) {
        urls = findUrlForClass(aClass);
        if (urls != null) {
          for (int i = 0; i < urls.size(); i++) {
            urls.set(i, urls.get(i) + "#" + field.getName());
          }
        }
      }
    }
    else if (element instanceof PsiMethod) {
      PsiMethod method = (PsiMethod)element;
      PsiClass aClass = method.getContainingClass();
      if (aClass != null) {
        final List<String> classUrls = findUrlForClass(aClass);

        if (classUrls != null) {
          urls = new ArrayList<String>();
          String signature = PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY,
                                                        PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS | PsiFormatUtil.SHOW_RAW_NON_TOP_TYPE,
                                                        PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.SHOW_FQ_CLASS_NAMES | PsiFormatUtil.SHOW_RAW_NON_TOP_TYPE, 999);
          for (String classUrl : classUrls) {
            urls.add(classUrl + "#" + signature);
          }
          signature = PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY,
                                                        PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS,
                                                        PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.SHOW_FQ_CLASS_NAMES, 999);
          for (String classUrl : classUrls) {
            urls.add(classUrl + "#" + signature);
          }
        }
      }
    }
    else if (element instanceof PsiPackage) {
      urls = findUrlForPackage((PsiPackage)element);
    }
    else if (element instanceof PsiDirectory) {
      PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(((PsiDirectory)element));
      if (aPackage != null) {
        urls = findUrlForPackage(aPackage);
      }
    }

    if (urls == null) {
      return null;
    }
    else {
      for (int i = 0; i < urls.size(); i++) {
        urls.set(i, FileUtil.toSystemIndependentName(urls.get(i)));
      }
      return urls;
    }
  }

  @Nullable
  public static List<String> findUrlForClass(PsiClass aClass) {
    String qName = aClass.getQualifiedName();
    if (qName == null) return null;
    PsiFile file = aClass.getContainingFile();
    if (!(file instanceof PsiJavaFile)) return null;
    String packageName = ((PsiJavaFile)file).getPackageName();

    String relPath;
    if (packageName.length() > 0) {
      relPath = packageName.replace('.', '/') + '/' + qName.substring(packageName.length() + 1) + HTML_EXTENSION;
    }
    else {
      relPath = qName + HTML_EXTENSION;
    }

    final PsiFile containingFile = aClass.getContainingFile();
    if (containingFile == null) return null;
    final VirtualFile virtualFile = containingFile.getVirtualFile();
    if (virtualFile == null) return null;

    return findUrlForVirtualFile(containingFile.getProject(), virtualFile, relPath);
  }

  @Nullable
  public static List<String> findUrlForVirtualFile(final Project project, final VirtualFile virtualFile, final String relPath) {
    final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
    Module module = fileIndex.getModuleForFile(virtualFile);
    if (module == null) {
      final VirtualFileSystem fs = virtualFile.getFileSystem();
      if (fs instanceof JarFileSystem) {
        final VirtualFile jar = ((JarFileSystem)fs).getVirtualFileForJar(virtualFile);
        if (jar != null) {
          module = fileIndex.getModuleForFile(jar);
        }
      }
    }
    if (module != null) {
      String[] javadocPaths = ModuleRootManager.getInstance(module).getRootUrls(JavadocOrderRootType.getInstance());
      final List<String> httpRoots = getHttpRoots(javadocPaths, relPath);
      // if found nothing and the file is from library classes, fall back to order entries
      if (httpRoots != null || !fileIndex.isInLibraryClasses(virtualFile)) {
        return httpRoots;
      }
    }

    final List<OrderEntry> orderEntries = fileIndex.getOrderEntriesForFile(virtualFile);
    for (OrderEntry orderEntry : orderEntries) {
      final String[] files = orderEntry.getUrls(JavadocOrderRootType.getInstance());
      final List<String> httpRoot = getHttpRoots(files, relPath);
      if (httpRoot != null) return httpRoot;
    }
    return null;
  }

  @Nullable
  public static List<String> getHttpRoots(final String[] roots, String relPath) {
    final ArrayList<String> result = new ArrayList<String>();
    for (String root : roots) {
      final VirtualFile virtualFile = VirtualFileManager.getInstance().findFileByUrl(root);
      if (virtualFile != null) {
        if (virtualFile.getFileSystem() instanceof HttpFileSystem) {
          String url = virtualFile.getUrl();
          if (!url.endsWith("/")) url += "/";
          result.add(url + relPath);
        }
        else {
          VirtualFile file = virtualFile.findFileByRelativePath(relPath);
          if (file != null) result.add(file.getUrl());
        }
      }
    }

    return result.isEmpty() ? null : result;
  }

  @Nullable
  public static List<String> findUrlForPackage(PsiPackage aPackage) {
    String qName = aPackage.getQualifiedName();
    qName = qName.replace('.', '/') + '/' + PACKAGE_SUMMARY_FILE;
    for (PsiDirectory directory : aPackage.getDirectories()) {
      List<String> url = findUrlForVirtualFile(aPackage.getProject(), directory.getVirtualFile(), qName);
      if (url != null) {
        return url;
      }
    }
    return null;
  }

  public PsiElement getDocumentationElementForLink(final PsiManager psiManager, final String link, final PsiElement context) {
    return JavaDocUtil.findReferenceTarget(psiManager, link, context);
  }

  public String fetchExternalDocumentation(final Project project, PsiElement element, final List<String> docUrls) {
    return fetchExternalJavadoc(element, project, docUrls);
  }

  public static String fetchExternalJavadoc(PsiElement element, final Project project, final List<String> docURLs) {
    final JavaDocExternalFilter docFilter = new JavaDocExternalFilter(project);

    return fetchExternalJavadoc(element, docURLs, docFilter);
  }

  public static String fetchExternalJavadoc(PsiElement element, List<String> docURLs, @NotNull JavaDocExternalFilter docFilter) {
    if (docURLs != null) {
      for (String docURL : docURLs) {
        try {
          final String javadoc = fetchExternalJavadoc(element, docURL, docFilter);
          if (javadoc != null) return javadoc;
        }
        catch (IndexNotReadyException e) {
          throw e;
        }
        catch (Exception e) {
          LOG.info(e); //connection problems should be ignored
        }
      }
    }
    return null;
  }
}


text:
using Newtonsoft.Json;

namespace VaultSharp.V1.SecretsEngines.Transit
{
    /// <summary>
    /// Represents a single Encryption item.
    /// </summary>
    public class EncryptionItem
    {
        /// <summary>
        /// [required]
        /// Specifies base64 encoded plaintext to be encrypted.
        /// </summary>
        [JsonProperty("plaintext")]
        public string Base64EncodedPlainText { get; set; }

        /// <summary>
        /// [required]
        ///  Specifies the base64 encoded context for key derivation.
        ///  This is required if key derivation is enabled for this key.
        /// </summary>
        [JsonProperty("context")]
        public string Base64EncodedContext { get; set; }

        /// <summary>
        /// [optional]
        ///  Specifies the version of the key to use for encryption.
        ///  If not set, uses the latest version.
        ///  Must be greater than or equal to the key's min_encryption_version, if set.
        /// </summary>
        [JsonProperty("key_version")]
        public int? KeyVersion { get; set; }

        /// <summary>
        /// [optional]
        /// Specifies the base64 encoded nonce value.
        /// This must be provided if convergent encryption is enabled for this key and the key was generated with Vault 0.6.1.
        /// Not required for keys created in 0.6.2+.
        /// The value must be exactly 96 bits (12 bytes) long and the user must ensure that for any given context
        /// (and thus, any given encryption key) this nonce value is never reused.
        /// </summary>
        [JsonProperty("nonce")]
        public string Nonce { get; set; }

        /// <summary>
        /// [required/optional]
        /// This parameter is required when encryption key is expected to be created.
        /// When performing an upsert operation, the type of key to create.
        /// </summary>
        [JsonProperty("type")]
        public TransitKeyType KeyType { get; set; }

        /// <summary>
        /// This parameter will only be used when a key is expected to be created.
        /// Whether to support convergent encryption.
        /// This is only supported when using a key with key derivation enabled and will require all requests to carry both a
        /// context and 96-bit (12-byte) nonce.
        /// The given nonce will be used in place of a randomly generated nonce.
        /// As a result, when the same context and nonce are supplied, the same ciphertext is generated.
        /// It is very important when using this mode that you ensure that all nonces are unique for a given context.
        /// Failing to do so will severely impact the ciphertext's security.
        /// </summary>
        /// <value>
        ///   <c>true</c> if [convergent encryption]; otherwise, <c>false</c>.
        /// </value>
        [JsonProperty("convergent_encryption")]
        public bool ConvergentEncryption { get; set; }

        /// <summary>
        /// Initializes a new instance of <see cref="EncryptionItem"/>.
        /// </summary>
        public EncryptionItem()
        {
            KeyType = TransitKeyType.aes256_gcm96;
        }
    }
}


text:
<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~ Copyright 2014 JBoss Inc
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~       http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.guvnor</groupId>
    <artifactId>guvnor</artifactId>
    <version>6.3.0-SNAPSHOT</version>
  </parent>

  <artifactId>guvnor-webapp</artifactId>
  <packaging>war</packaging>

  <name>Guvnor Workbench - WebApp</name>
  <description>Guvnor Workbench - WebApp</description>

  <dependencies>

    <dependency>
      <groupId>com.github.gwtbootstrap</groupId>
      <artifactId>gwt-bootstrap</artifactId>
    </dependency>
    <dependency>
      <groupId>commons-lang</groupId>
      <artifactId>commons-lang</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.lucene</groupId>
      <artifactId>lucene-core</artifactId>
    </dependency>
    <dependency>
      <groupId>org.jboss.errai</groupId>
      <artifactId>errai-bus</artifactId>
    </dependency>
    <dependency>
      <groupId>org.jboss.errai</groupId>
      <artifactId>errai-common</artifactId>
    </dependency>
    <dependency>
      <groupId>org.jboss.errai</groupId>
      <artifactId>errai-ioc</artifactId>
    </dependency>
    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-project-api</artifactId>
    </dependency>
    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-services-api</artifactId>
    </dependency>
    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-services-backend</artifactId>
    </dependency>
    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-structure-api</artifactId>
    </dependency>
    <dependency>
      <groupId>org.kie.uberfire</groupId>
      <artifactId>kie-uberfire-widgets-commons</artifactId>
    </dependency>
    <dependency>
      <groupId>org.kie.uberfire</groupId>
      <artifactId>kie-uberfire-metadata-api</artifactId>
    </dependency>
    <dependency>
      <groupId>org.uberfire</groupId>
      <artifactId>uberfire-api</artifactId>
    </dependency>
    <dependency>
      <groupId>org.uberfire</groupId>
      <artifactId>uberfire-backend-server</artifactId>
    </dependency>
    <dependency>
      <groupId>org.uberfire</groupId>
      <artifactId>uberfire-client-api</artifactId>
    </dependency>
    <dependency>
      <groupId>org.uberfire</groupId>
      <artifactId>uberfire-commons</artifactId>
    </dependency>
    <dependency>
      <groupId>org.uberfire</groupId>
      <artifactId>uberfire-io</artifactId>
    </dependency>
    <dependency>
      <groupId>org.uberfire</groupId>
      <artifactId>uberfire-nio2-api</artifactId>
    </dependency>
    <dependency>
      <groupId>org.uberfire</groupId>
      <artifactId>uberfire-nio2-model</artifactId>
    </dependency>
    <dependency>
      <groupId>org.uberfire</groupId>
      <artifactId>uberfire-security-api</artifactId>
    </dependency>
    <dependency>
      <groupId>org.uberfire</groupId>
      <artifactId>uberfire-security-server</artifactId>
    </dependency>
    <dependency>
      <groupId>org.uberfire</groupId>
      <artifactId>uberfire-workbench-client</artifactId>
    </dependency>

    <!-- Hack: ANT bundled with kie-ci needs to be excluded when running on Jetty -->
    <!-- It is added back for other Application Servers in their respective assemblies -->
    <dependency>
      <groupId>org.kie</groupId>
      <artifactId>kie-ci</artifactId>
      <exclusions>
        <exclusion>
          <groupId>org.apache.ant</groupId>
          <artifactId>ant</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <!--Logs-->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
    </dependency>
    <!-- This is a war file, so logback is not in scope test, but in scope compile -->
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
    </dependency>

    <!-- Guvnor -->

    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-asset-mgmt-backend</artifactId>
    </dependency>

    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-structure-backend</artifactId>
    </dependency>

    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-structure-client</artifactId>
    </dependency>

    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-services-api</artifactId>
    </dependency>

    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-m2repo-editor-api</artifactId>
    </dependency>

    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-m2repo-editor-client</artifactId>
    </dependency>

    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-m2repo-editor-backend</artifactId>
    </dependency>

    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-inbox-api</artifactId>
    </dependency>

    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-inbox-client</artifactId>
    </dependency>

    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-inbox-backend</artifactId>
    </dependency>

    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-project-api</artifactId>
    </dependency>

    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-project-backend</artifactId>
    </dependency>

    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-workingset-api</artifactId>
    </dependency>

    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-workingset-client</artifactId>
    </dependency>

    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-project-builder</artifactId>
    </dependency>

    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-message-console-api</artifactId>
    </dependency>

    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-message-console-backend</artifactId>
    </dependency>

    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-message-console-client</artifactId>
    </dependency>

    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-organizationalunit-manager</artifactId>
    </dependency>

    <dependency>
      <groupId>org.guvnor</groupId>
      <artifactId>guvnor-rest-backend</artifactId>
    </dependency>

    <!-- REST exception handling -->
    <dependency>
      <groupId>org.kie.remote</groupId>
      <artifactId>kie-remote-common</artifactId>
    </dependency>

    <!-- UberFire Extension -->
    <dependency>
      <groupId>org.kie.uberfire</groupId>
      <artifactId>kie-uberfire-metadata-commons-io</artifactId>
    </dependency>

    <dependency>
      <groupId>org.kie.uberfire</groupId>
      <artifactId>kie-uberfire-metadata-backend-lucene</artifactId>
    </dependency>

    <!-- UberFire -->
    <dependency>
      <groupId>org.uberfire</groupId>
      <artifactId>uberfire-all</artifactId>
    </dependency>

    <dependency>
      <groupId>org.uberfire</groupId>
      <artifactId>uberfire-workbench-processors</artifactId>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>org.uberfire</groupId>
      <artifactId>uberfire-panel-manager-nswe</artifactId>
      <scope>provided</scope>
    </dependency>

    <!-- Errai AS -->
    <dependency>
      <groupId>org.jboss.errai</groupId>
      <artifactId>errai-jboss-as-support</artifactId>
    </dependency>

    <!-- CDI Integration Modules -->
    <dependency>
      <groupId>org.jboss.errai</groupId>
      <artifactId>errai-cdi-client</artifactId>
    </dependency>

    <dependency>
      <groupId>org.jboss.errai</groupId>
      <artifactId>errai-javax-enterprise</artifactId>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>org.jboss.errai</groupId>
      <artifactId>errai-weld-integration</artifactId>
    </dependency>

    <dependency>
      <groupId>org.jboss.errai</groupId>
      <artifactId>errai-cdi-jetty</artifactId>
    </dependency>

    <!-- Weld Modules -->
    <dependency>
      <groupId>org.jboss.weld.se</groupId>
      <artifactId>weld-se-core</artifactId>
    </dependency>

    <dependency>
      <groupId>org.jboss.weld.servlet</groupId>
      <artifactId>weld-servlet-core</artifactId>
    </dependency>

    <!-- GWT and GWT Extensions -->
    <dependency>
      <groupId>com.google.gwt</groupId>
      <artifactId>gwt-user</artifactId>
      <scope>provided</scope>
    </dependency>

    <!-- Rouge imports to avoid OSGi errors -->
    <dependency>
      <groupId>org.osgi</groupId>
      <artifactId>org.osgi.core</artifactId>
    </dependency>

    <dependency>
      <groupId>com.sun.xml.bind</groupId>
      <artifactId>jaxb-impl</artifactId>
    </dependency>

    <dependency>
      <groupId>com.sun.xml.bind</groupId>
      <artifactId>jaxb-xjc</artifactId>
    </dependency>

    <dependency>
      <groupId>org.jboss.resteasy</groupId>
      <artifactId>resteasy-jaxrs</artifactId>
    </dependency>

    <!--JUnit for Test scenarios -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
    </dependency>

  </dependencies>

  <build>

    <resources>
      <!-- Include src/main/java in order not to break the Eclipse GWT plug-in -->
      <resource>
        <directory>src/main/java</directory>
      </resource>
      <!-- Include module descriptors from src/main/resources in order not to break the Intellij GWT plug-in -->
      <resource>
        <directory>src/main/resources</directory>
      </resource>
    </resources>

    <plugins>

      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>gwt-maven-plugin</artifactId>
        <configuration>
          <deploy>${project.build.directory}/gwt-symbols-deploy</deploy>
          <localWorkers>1</localWorkers>
          <module>org.guvnor.FastCompiledGuvnorWorkbench</module>
          <logLevel>INFO</logLevel>
          <compileSourcesArtifacts>

            <!-- Guvnor -->
            <compileSourcesArtifact>org.guvnor:guvnor-structure-api</compileSourcesArtifact>
            <compileSourcesArtifact>org.guvnor:guvnor-structure-client</compileSourcesArtifact>
            <compileSourcesArtifact>org.guvnor:guvnor-inbox-api</compileSourcesArtifact>
            <compileSourcesArtifact>org.guvnor:guvnor-inbox-client</compileSourcesArtifact>
            <compileSourcesArtifact>org.guvnor:guvnor-m2repo-editor-api</compileSourcesArtifact>
            <compileSourcesArtifact>org.guvnor:guvnor-m2repo-editor-client</compileSourcesArtifact>
            <compileSourcesArtifact>org.guvnor:guvnor-workingset-api</compileSourcesArtifact>
            <compileSourcesArtifact>org.guvnor:guvnor-workingset-client</compileSourcesArtifact>
            <compileSourcesArtifact>org.guvnor:guvnor-services-api</compileSourcesArtifact>
            <compileSourcesArtifact>org.guvnor:guvnor-project-api</compileSourcesArtifact>
            <compileSourcesArtifact>org.guvnor:guvnor-message-console-api</compileSourcesArtifact>
            <compileSourcesArtifact>org.guvnor:guvnor-message-console-client</compileSourcesArtifact>
            <compileSourcesArtifact>org.guvnor:guvnor-organizationalunit-manager</compileSourcesArtifact>

            <!-- UberFire -->
            <compileSourcesArtifact>org.uberfire:uberfire-commons</compileSourcesArtifact>
            <compileSourcesArtifact>org.uberfire:uberfire-nio2-model</compileSourcesArtifact>
            <compileSourcesArtifact>org.uberfire:uberfire-api</compileSourcesArtifact>
            <compileSourcesArtifact>org.uberfire:uberfire-js</compileSourcesArtifact>
            <compileSourcesArtifact>org.uberfire:uberfire-security-api</compileSourcesArtifact>
            <compileSourcesArtifact>org.uberfire:uberfire-security-client</compileSourcesArtifact>
            <compileSourcesArtifact>org.uberfire:uberfire-client-api</compileSourcesArtifact>
            <compileSourcesArtifact>org.uberfire:uberfire-workbench-client</compileSourcesArtifact>
            <compileSourcesArtifact>org.uberfire:uberfire-workbench-client-backend</compileSourcesArtifact>
            <compileSourcesArtifact>org.uberfire:uberfire-backend-api</compileSourcesArtifact>

          </compileSourcesArtifacts>
          <runTarget>org.guvnor.GuvnorWorkbench/GuvnorWorkbench.html</runTarget>
          <extraJvmArgs>-Xmx2048m -XX:MaxPermSize=256m -Xms2048m -XX:PermSize=128m -Xss1M</extraJvmArgs>
          <server>org.jboss.errai.cdi.server.gwt.JettyLauncher</server>
          <!-- drools-compiler has dependency on org.eclipse.jdt.core.compiler:ecj:jar:3.5.1:compile, see http://code.google.com/p/google-web-toolkit/issues/detail?id=4479 -->
          <gwtSdkFirstInClasspath>true</gwtSdkFirstInClasspath>
        </configuration>
        <executions>
          <execution>
            <id>gwt-clean</id>
            <phase>clean</phase>
            <goals>
              <goal>clean</goal>
            </goals>
          </execution>
          <execution>
            <id>gwt-compile</id>
            <goals>
              <goal>resources</goal>
              <goal>compile</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <configuration>
          <packagingExcludes>**/javax/**/*.*,**/client/**/*.class,**/*.symbolMap</packagingExcludes>
          <archive>
            <addMavenDescriptor>false</addMavenDescriptor>
          </archive>
        </configuration>
      </plugin>

      <!-- Tests are skipped by default because they require additional GWT dependencies. Run mvn with
        -Pintegration-test to enable testing. -->
      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
          <skipTests>true</skipTests>
        </configuration>
      </plugin>

      <plugin>
        <artifactId>maven-clean-plugin</artifactId>
        <configuration>
          <filesets>
            <fileset>
              <directory>${basedir}</directory>
              <includes>
                <include>.errai/**</include>
                <include>.niogit/**</include>
              </includes>
            </fileset>
          </filesets>
        </configuration>
      </plugin>
    </plugins>

    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.eclipse.m2e</groupId>
          <artifactId>lifecycle-mapping</artifactId>
          <configuration>
            <lifecycleMappingMetadata>
              <pluginExecutions>
                <pluginExecution>
                  <pluginExecutionFilter>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>gwt-maven-plugin</artifactId>
                    <versionRange>[2.3.0,)</versionRange>
                    <goals>
                      <goal>resources</goal>
                    </goals>
                  </pluginExecutionFilter>
                  <action>
                    <execute/>
                    <execute/>
                  </action>
                </pluginExecution>
              </pluginExecutions>
            </lifecycleMappingMetadata>
          </configuration>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>

  <profiles>
    <profile>
      <id>fullProfile</id>

      <activation>
        <property>
          <name>full</name>
        </property>
      </activation>

      <dependencies>
        <!-- Add back ANT when building full profile as it's needed by AS7 and Tomcat -->
        <dependency>
          <groupId>org.apache.ant</groupId>
          <artifactId>ant</artifactId>
        </dependency>
      </dependencies>

      <build>
        <plugins>
          <plugin><!-- Keep in sync with soa profile -->
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>gwt-maven-plugin</artifactId>
            <configuration>
              <!-- Build all GWT permutations and optimize them -->
              <module>org.guvnor.GuvnorWorkbench</module>
              <draftCompile>false</draftCompile>
              <localWorkers>4</localWorkers>
              <extraJvmArgs>-Xmx4096m -XX:MaxPermSize=256m -Xms2048m -XX:PermSize=128m -Xss1M</extraJvmArgs>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>

</project>


text:
<?php

class Mage_Adminhtml_Model_System_Config_Source_Cms_Page
{

    protected $_options;

    public function toOptionArray()
    {
        if (!$this->_options) {
            $this->_options = Mage::getResourceModel('cms/page_collection')
                ->load()->toOptionIdArray();
        }
        return $this->_options;
    }

}


text:
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/include/usr/runtime/runtime.H $                           */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2012,2015                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

#ifndef __RUNTIME_H
#define __RUNTIME_H

#include <stdint.h>
#include <builtins.h>
#include <errl/errlentry.H>

namespace RUNTIME
{

/**
 * @brief Populate attributes in mainstore for HostServices
 *
 * @return errlHndl_t  NULL on success
 */
errlHndl_t populate_attributes( void );

/**
 * @brief Populate node attributes in mainstore for HostServices
 *
 * @return errlHndl_t NULL on Success
 */
errlHndl_t populate_node_attributes( uint64_t i_nodeNum );

/**
 * @brief  Add the host data mainstore location to VMM
 *
 * @description  If running with the standard PHYP payload this function
 *    will map all supported HDAT sections into the VMM to allow access
 *    from user space.  When running in standalone (no payload) mode,
 *    some reserved memory will be mapped in for testcases.  If AVPs are
 *    enabled, no memory will be mapped and the PAYLOAD_KIND attribute
 *    will be set appropriately.
 *
 * @return errlHndl_t  NULL on success
 */
errlHndl_t load_host_data( void );

/**
 * HDAT Sections
 */
enum SectionId
{
    FIRST_SECTION,        //< Placeholder for arrays
    HSVC_NODE_DATA = FIRST_SECTION, //< HostServices Node Attributes
    HSVC_SYSTEM_DATA,     //< HostServices System Attributes
    IPLPARMS_SYSTEM,      //< IPL Parms
    MS_DUMP_SRC_TBL,      //< MDST: Memory Dump Source Table
    MS_DUMP_DST_TBL,      //< MDDT: Memory Dump Destination Table
    MS_DUMP_RESULTS_TBL,  //< MDRT: Memory Dump Results Table
    SPIRA_S,              //< SPIRA-S
    SPIRA_H,              //< SPIRA-H
    SPIRA_L,              //< Legacy SPIRA
    NACA,                 //< NACA
    LAST_SECTION = NACA   //< Placeholder for arrays
};

/**
 * @brief  Get a pointer to the beginning of a particular section of
 *         the host data memory.
 *
 * @description  The returned pointer will not include any header hdat header
 *     information.
 *
 * @param[in] i_section  Chunk of data to find
 * @param[in] i_instance  Instance of section when there are multiple entries
 * @param[out] o_dataAddr  Physical memory address of data
 * @param[out] o_dataSize  Size of data in bytes, 0 on error, DATA_SIZE_UNKNOWN if unknown
 *
 * @return errlHndl_t  NULL on success
 */
errlHndl_t get_host_data_section( SectionId i_section,
                                  uint64_t i_instance,
                                  uint64_t& o_dataAddr,
                                  size_t& o_dataSize );
const size_t DATA_SIZE_UNKNOWN = 0xFFFFFFFFFFFFFFFF;

/**
 * @brief  Store the actual count of a section in local memory.
 *
 * @param[in] i_section  Chunk of data to update
 * @param[in] i_count   Actual number of entries
 *
 */
void saveActualCount( RUNTIME::SectionId i_id,
                      uint16_t i_count );

/**
 * @brief  Write the stored actual count to SPIRA
 *
 * @param[in] i_section  Chunk of data to update
 *
 * @return errlHndl_t  NULL on success
 */
errlHndl_t writeActualCount( RUNTIME::SectionId i_id );

/*
 * @brief  Retrieve and log FFDC data relevant to a given section of
 *         host data memory
 *
 * @param[in] i_section  Relevant section
 * @param[inout] io_errlog  Log to append FFDC to
 *
 * @return errlHndl_t  NULL on success
 */
void add_host_data_ffdc( SectionId i_section,
                         errlHndl_t& io_errlog );

/*
 * @brief Set the PAYLOAD_BASE attribute
 * @param[in] i_payloadAddress in MEGABYTES
 */
void setPayloadBaseAddress(uint64_t i_payloadAddress);

/*
 * @brief Clear out any cached data and rediscover the location
 *        of the HDAT memory
 */
void rediscover_hdat( void );

}

#endif


text:
package itest

import (
	"context"
	"math"
	"strings"
	"time"

	"github.com/lightningnetwork/lnd"
	"github.com/lightningnetwork/lnd/lnrpc"
	"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
	"github.com/lightningnetwork/lnd/lntest"
	"github.com/lightningnetwork/lnd/lnwire"
)

func testHtlcErrorPropagation(net *lntest.NetworkHarness, t *harnessTest) {
	ctxb := context.Background()

	// In this test we wish to exercise the daemon's correct parsing,
	// handling, and propagation of errors that occur while processing a
	// multi-hop payment.
	const chanAmt = lnd.MaxBtcFundingAmount

	// First establish a channel with a capacity of 0.5 BTC between Alice
	// and Bob.
	ctxt, _ := context.WithTimeout(ctxb, channelOpenTimeout)
	chanPointAlice := openChannelAndAssert(
		ctxt, t, net, net.Alice, net.Bob,
		lntest.OpenChannelParams{
			Amt: chanAmt,
		},
	)
	ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
	if err := net.Alice.WaitForNetworkChannelOpen(ctxt, chanPointAlice); err != nil {
		t.Fatalf("channel not seen by alice before timeout: %v", err)
	}

	cType, err := channelCommitType(net.Alice, chanPointAlice)
	if err != nil {
		t.Fatalf("unable to get channel type: %v", err)
	}

	commitFee := cType.calcStaticFee(0)
	assertBaseBalance := func() {
		// Alice has opened a channel with Bob with zero push amount, so
		// it's remote balance is zero.
		expBalanceAlice := &lnrpc.ChannelBalanceResponse{
			LocalBalance: &lnrpc.Amount{
				Sat: uint64(chanAmt - commitFee),
				Msat: uint64(lnwire.NewMSatFromSatoshis(
					chanAmt - commitFee,
				)),
			},
			RemoteBalance:            &lnrpc.Amount{},
			UnsettledLocalBalance:    &lnrpc.Amount{},
			UnsettledRemoteBalance:   &lnrpc.Amount{},
			PendingOpenLocalBalance:  &lnrpc.Amount{},
			PendingOpenRemoteBalance: &lnrpc.Amount{},
			// Deprecated fields.
			Balance: int64(chanAmt - commitFee),
		}
		assertChannelBalanceResp(t, net.Alice, expBalanceAlice)

		// Bob has a channel with Alice and another with Carol, so it's
		// local and remote balances are both chanAmt - commitFee.
		expBalanceBob := &lnrpc.ChannelBalanceResponse{
			LocalBalance: &lnrpc.Amount{
				Sat: uint64(chanAmt - commitFee),
				Msat: uint64(lnwire.NewMSatFromSatoshis(
					chanAmt - commitFee,
				)),
			},
			RemoteBalance: &lnrpc.Amount{
				Sat: uint64(chanAmt - commitFee),
				Msat: uint64(lnwire.NewMSatFromSatoshis(
					chanAmt - commitFee,
				)),
			},
			UnsettledLocalBalance:    &lnrpc.Amount{},
			UnsettledRemoteBalance:   &lnrpc.Amount{},
			PendingOpenLocalBalance:  &lnrpc.Amount{},
			PendingOpenRemoteBalance: &lnrpc.Amount{},
			// Deprecated fields.
			Balance: int64(chanAmt - commitFee),
		}
		assertChannelBalanceResp(t, net.Bob, expBalanceBob)
	}

	// Since we'd like to test some multi-hop failure scenarios, we'll
	// introduce another node into our test network: Carol.
	carol, err := net.NewNode("Carol", nil)
	if err != nil {
		t.Fatalf("unable to create new nodes: %v", err)
	}

	// Next, we'll create a connection from Bob to Carol, and open a
	// channel between them so we have the topology: Alice -> Bob -> Carol.
	// The channel created will be of lower capacity that the one created
	// above.
	ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
	if err := net.ConnectNodes(ctxt, net.Bob, carol); err != nil {
		t.Fatalf("unable to connect bob to carol: %v", err)
	}
	ctxt, _ = context.WithTimeout(ctxb, channelOpenTimeout)
	const bobChanAmt = lnd.MaxBtcFundingAmount
	chanPointBob := openChannelAndAssert(
		ctxt, t, net, net.Bob, carol,
		lntest.OpenChannelParams{
			Amt: chanAmt,
		},
	)

	// Ensure that Alice has Carol in her routing table before proceeding.
	nodeInfoReq := &lnrpc.NodeInfoRequest{
		PubKey: carol.PubKeyStr,
	}
	checkTableTimeout := time.After(time.Second * 10)
	checkTableTicker := time.NewTicker(100 * time.Millisecond)
	defer checkTableTicker.Stop()

out:
	// TODO(roasbeef): make into async hook for node announcements
	for {
		select {
		case <-checkTableTicker.C:
			ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
			_, err := net.Alice.GetNodeInfo(ctxt, nodeInfoReq)
			if err != nil && strings.Contains(err.Error(),
				"unable to find") {

				continue
			}

			break out
		case <-checkTableTimeout:
			t.Fatalf("carol's node announcement didn't propagate within " +
				"the timeout period")
		}
	}

	// With the channels, open we can now start to test our multi-hop error
	// scenarios. First, we'll generate an invoice from carol that we'll
	// use to test some error cases.
	const payAmt = 10000
	invoiceReq := &lnrpc.Invoice{
		Memo:  "kek99",
		Value: payAmt,
	}
	ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
	carolInvoice, err := carol.AddInvoice(ctxt, invoiceReq)
	if err != nil {
		t.Fatalf("unable to generate carol invoice: %v", err)
	}

	carolPayReq, err := carol.DecodePayReq(ctxb,
		&lnrpc.PayReqString{
			PayReq: carolInvoice.PaymentRequest,
		})
	if err != nil {
		t.Fatalf("unable to decode generated payment request: %v", err)
	}

	// Before we send the payment, ensure that the announcement of the new
	// channel has been processed by Alice.
	ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
	if err := net.Alice.WaitForNetworkChannelOpen(ctxt, chanPointBob); err != nil {
		t.Fatalf("channel not seen by alice before timeout: %v", err)
	}

	// Before we start sending payments, subscribe to htlc events for each
	// node.
	ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
	defer cancel()

	aliceEvents, err := net.Alice.RouterClient.SubscribeHtlcEvents(
		ctxt, &routerrpc.SubscribeHtlcEventsRequest{},
	)
	if err != nil {
		t.Fatalf("could not subscribe events: %v", err)
	}

	bobEvents, err := net.Bob.RouterClient.SubscribeHtlcEvents(
		ctxt, &routerrpc.SubscribeHtlcEventsRequest{},
	)
	if err != nil {
		t.Fatalf("could not subscribe events: %v", err)
	}

	carolEvents, err := carol.RouterClient.SubscribeHtlcEvents(
		ctxt, &routerrpc.SubscribeHtlcEventsRequest{},
	)
	if err != nil {
		t.Fatalf("could not subscribe events: %v", err)
	}

	// For the first scenario, we'll test the cancellation of an HTLC with
	// an unknown payment hash.
	// TODO(roasbeef): return failure response rather than failing entire
	// stream on payment error.
	sendReq := &routerrpc.SendPaymentRequest{
		PaymentHash:    makeFakePayHash(t),
		Dest:           carol.PubKey[:],
		Amt:            payAmt,
		FinalCltvDelta: int32(carolPayReq.CltvExpiry),
		TimeoutSeconds: 60,
		FeeLimitMsat:   noFeeLimitMsat,
	}
	sendAndAssertFailure(
		t, net.Alice,
		sendReq, lnrpc.PaymentFailureReason_FAILURE_REASON_INCORRECT_PAYMENT_DETAILS,
	)
	assertLastHTLCError(
		t, net.Alice,
		lnrpc.Failure_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS,
	)

	// We expect alice and bob to each have one forward and one forward
	// fail event at this stage.
	assertHtlcEvents(t, 1, 1, 0, routerrpc.HtlcEvent_SEND, aliceEvents)
	assertHtlcEvents(t, 1, 1, 0, routerrpc.HtlcEvent_FORWARD, bobEvents)

	// Carol should have a link failure because the htlc failed on her
	// incoming link.
	assertLinkFailure(
		t, routerrpc.HtlcEvent_RECEIVE,
		routerrpc.FailureDetail_UNKNOWN_INVOICE, carolEvents,
	)

	// The balances of all parties should be the same as initially since
	// the HTLC was canceled.
	assertBaseBalance()

	// Next, we'll test the case of a recognized payHash but, an incorrect
	// value on the extended HTLC.
	htlcAmt := lnwire.NewMSatFromSatoshis(1000)
	sendReq = &routerrpc.SendPaymentRequest{
		PaymentHash:    carolInvoice.RHash,
		Dest:           carol.PubKey[:],
		Amt:            int64(htlcAmt.ToSatoshis()), // 10k satoshis are expected.
		FinalCltvDelta: int32(carolPayReq.CltvExpiry),
		TimeoutSeconds: 60,
		FeeLimitMsat:   noFeeLimitMsat,
	}
	sendAndAssertFailure(
		t, net.Alice,
		sendReq, lnrpc.PaymentFailureReason_FAILURE_REASON_INCORRECT_PAYMENT_DETAILS,
	)
	assertLastHTLCError(
		t, net.Alice,
		lnrpc.Failure_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS,
	)

	// We expect alice and bob to each have one forward and one forward
	// fail event at this stage.
	assertHtlcEvents(t, 1, 1, 0, routerrpc.HtlcEvent_SEND, aliceEvents)
	assertHtlcEvents(t, 1, 1, 0, routerrpc.HtlcEvent_FORWARD, bobEvents)

	// Carol should have a link failure because the htlc failed on her
	// incoming link.
	assertLinkFailure(
		t, routerrpc.HtlcEvent_RECEIVE,
		routerrpc.FailureDetail_INVOICE_UNDERPAID, carolEvents,
	)

	// The balances of all parties should be the same as initially since
	// the HTLC was canceled.
	assertBaseBalance()

	// Next we'll test an error that occurs mid-route due to an outgoing
	// link having insufficient capacity. In order to do so, we'll first
	// need to unbalance the link connecting Bob<->Carol.
	//
	// To do so, we'll push most of the funds in the channel over to
	// Alice's side, leaving on 10k satoshis of available balance for bob.
	// There's a max payment amount, so we'll have to do this
	// incrementally.
	chanReserve := int64(chanAmt / 100)
	amtToSend := int64(chanAmt) - chanReserve - 20000
	amtSent := int64(0)
	for amtSent != amtToSend {
		// We'll send in chunks of the max payment amount. If we're
		// about to send too much, then we'll only send the amount
		// remaining.
		toSend := int64(math.MaxUint32)
		if toSend+amtSent > amtToSend {
			toSend = amtToSend - amtSent
		}

		invoiceReq = &lnrpc.Invoice{
			Value: toSend,
		}
		ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
		carolInvoice2, err := carol.AddInvoice(ctxt, invoiceReq)
		if err != nil {
			t.Fatalf("unable to generate carol invoice: %v", err)
		}
		sendAndAssertSuccess(
			t, net.Bob,
			&routerrpc.SendPaymentRequest{
				PaymentRequest: carolInvoice2.PaymentRequest,
				TimeoutSeconds: 60,
				FeeLimitMsat:   noFeeLimitMsat,
			},
		)

		// For each send bob makes, we need to check that bob has a
		// forward and settle event for his send, and carol has a
		// settle event for her receive.
		assertHtlcEvents(
			t, 1, 0, 1, routerrpc.HtlcEvent_SEND, bobEvents,
		)
		assertHtlcEvents(
			t, 0, 0, 1, routerrpc.HtlcEvent_RECEIVE, carolEvents,
		)

		amtSent += toSend
	}

	// At this point, Alice has 50mil satoshis on her side of the channel,
	// but Bob only has 10k available on his side of the channel. So a
	// payment from Alice to Carol worth 100k satoshis should fail.
	invoiceReq = &lnrpc.Invoice{
		Value: 100000,
	}
	ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
	carolInvoice3, err := carol.AddInvoice(ctxt, invoiceReq)
	if err != nil {
		t.Fatalf("unable to generate carol invoice: %v", err)
	}

	sendReq = &routerrpc.SendPaymentRequest{
		PaymentRequest: carolInvoice3.PaymentRequest,
		TimeoutSeconds: 60,
		FeeLimitMsat:   noFeeLimitMsat,
	}
	sendAndAssertFailure(
		t, net.Alice,
		sendReq, lnrpc.PaymentFailureReason_FAILURE_REASON_NO_ROUTE,
	)
	assertLastHTLCError(
		t, net.Alice, lnrpc.Failure_TEMPORARY_CHANNEL_FAILURE,
	)

	// Alice should have a forwarding event and a forwarding failure.
	assertHtlcEvents(t, 1, 1, 0, routerrpc.HtlcEvent_SEND, aliceEvents)

	// Bob should have a link failure because the htlc failed on his
	// outgoing link.
	assertLinkFailure(
		t, routerrpc.HtlcEvent_FORWARD,
		routerrpc.FailureDetail_INSUFFICIENT_BALANCE, bobEvents,
	)

	// Generate new invoice to not pay same invoice twice.
	ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
	carolInvoice, err = carol.AddInvoice(ctxt, invoiceReq)
	if err != nil {
		t.Fatalf("unable to generate carol invoice: %v", err)
	}

	// For our final test, we'll ensure that if a target link isn't
	// available for what ever reason then the payment fails accordingly.
	//
	// We'll attempt to complete the original invoice we created with Carol
	// above, but before we do so, Carol will go offline, resulting in a
	// failed payment.
	shutdownAndAssert(net, t, carol)

	// Reset mission control to forget the temporary channel failure above.
	ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
	_, err = net.Alice.RouterClient.ResetMissionControl(
		ctxt, &routerrpc.ResetMissionControlRequest{},
	)
	if err != nil {
		t.Fatalf("unable to reset mission control: %v", err)
	}

	sendAndAssertFailure(
		t, net.Alice,
		&routerrpc.SendPaymentRequest{
			PaymentRequest: carolInvoice.PaymentRequest,
			TimeoutSeconds: 60,
			FeeLimitMsat:   noFeeLimitMsat,
		},
		lnrpc.PaymentFailureReason_FAILURE_REASON_NO_ROUTE,
	)
	assertLastHTLCError(t, net.Alice, lnrpc.Failure_UNKNOWN_NEXT_PEER)

	// Alice should have a forwarding event and subsequent fail.
	assertHtlcEvents(t, 1, 1, 0, routerrpc.HtlcEvent_SEND, aliceEvents)

	// Bob should have a link failure because he could not find the next
	// peer.
	assertLinkFailure(
		t, routerrpc.HtlcEvent_FORWARD,
		routerrpc.FailureDetail_NO_DETAIL, bobEvents,
	)

	// Finally, immediately close the channel. This function will also
	// block until the channel is closed and will additionally assert the
	// relevant channel closing post conditions.
	ctxt, _ = context.WithTimeout(ctxb, channelCloseTimeout)
	closeChannelAndAssert(ctxt, t, net, net.Alice, chanPointAlice, false)

	// Force close Bob's final channel.
	ctxt, _ = context.WithTimeout(ctxb, channelCloseTimeout)
	closeChannelAndAssert(ctxt, t, net, net.Bob, chanPointBob, true)

	// Cleanup by mining the force close and sweep transaction.
	cleanupForceClose(t, net, net.Bob, chanPointBob)
}

// assertLinkFailure checks that the stream provided has a single link failure
// the the failure detail provided.
func assertLinkFailure(t *harnessTest,
	eventType routerrpc.HtlcEvent_EventType,
	failureDetail routerrpc.FailureDetail,
	client routerrpc.Router_SubscribeHtlcEventsClient) {

	event := assertEventAndType(t, eventType, client)

	linkFail, ok := event.Event.(*routerrpc.HtlcEvent_LinkFailEvent)
	if !ok {
		t.Fatalf("expected forwarding failure, got: %T", linkFail)
	}

	if linkFail.LinkFailEvent.FailureDetail != failureDetail {
		t.Fatalf("expected: %v, got: %v", failureDetail,
			linkFail.LinkFailEvent.FailureDetail)
	}
}