text:
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.components.browser_ui.widget.dragreorder;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;

import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.core.graphics.ColorUtils;
import androidx.core.view.ViewCompat;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;

import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.ObserverList;
import org.chromium.components.browser_ui.widget.R;

import java.util.Collections;
import java.util.List;

/**
 * Adapter for a {@link RecyclerView} that manages drag-reorderable lists.
 *
 * @param <T> The type of item that inhabits this adapter's list
 */
public abstract class DragReorderableListAdapter<T> extends RecyclerView.Adapter<ViewHolder> {
    private static final int ANIMATION_DELAY_MS = 100;

    protected final Context mContext;

    // keep track of the list and list managers
    protected ItemTouchHelper mItemTouchHelper;
    private ItemTouchHelper.Callback mTouchHelperCallback;
    protected List<T> mElements;
    protected RecyclerView mRecyclerView;

    // keep track of how this item looks
    private final int mDraggedBackgroundColor;
    private final float mDraggedElevation;

    protected DragStateDelegate mDragStateDelegate;

    private int mStart;
    private ObserverList<DragListener> mListeners = new ObserverList<>();

    /**
     * A callback for touch actions on drag-reorderable lists.
     */
    private class DragTouchCallback extends ItemTouchHelper.Callback {
        // The view that is being dragged now; null means no view is being dragged now;
        private @Nullable ViewHolder mBeingDragged;

        @Override
        public int getMovementFlags(RecyclerView recyclerView, ViewHolder viewHolder) {
            // this method may be called multiple times until the view is dropped
            // ensure there is only one bookmark being dragged
            if ((mBeingDragged == viewHolder || mBeingDragged == null)
                    && isActivelyDraggable(viewHolder)) {
                return makeMovementFlags(
                        ItemTouchHelper.UP | ItemTouchHelper.DOWN, 0 /* swipe flags */);
            }
            return makeMovementFlags(0, 0);
        }

        @Override
        public boolean onMove(RecyclerView recyclerView, ViewHolder current, ViewHolder target) {
            int from = current.getAdapterPosition();
            int to = target.getAdapterPosition();
            if (from == to) return false;
            Collections.swap(mElements, from, to);
            notifyItemMoved(from, to);
            return true;
        }

        @Override
        public void onSelectedChanged(ViewHolder viewHolder, int actionState) {
            super.onSelectedChanged(viewHolder, actionState);

            // similar to getMovementFlags, this method may be called multiple times
            if (actionState == ItemTouchHelper.ACTION_STATE_DRAG && mBeingDragged != viewHolder) {
                mBeingDragged = viewHolder;
                mStart = viewHolder.getAdapterPosition();
                onDragStateChange(true);
                updateVisualState(true, viewHolder);
            }
        }

        @Override
        public void clearView(RecyclerView recyclerView, ViewHolder viewHolder) {
            super.clearView(recyclerView, viewHolder);
            // no need to commit change if recycler view is not attached to window, e.g.:
            // dragging is terminated by destroying activity
            if (viewHolder.getAdapterPosition() != mStart && recyclerView.isAttachedToWindow()) {
                // Commit the position change for the dragged item when it's dropped and
                // recyclerView has finished layout computing
                recyclerView.post(() -> setOrder(mElements));
            }
            // the row has been dropped, even though it is possible at same row
            mBeingDragged = null;
            onDragStateChange(false);
            updateVisualState(false, viewHolder);
        }

        @Override
        public boolean isLongPressDragEnabled() {
            return mDragStateDelegate.getDragActive();
        }

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

        @Override
        public void onSwiped(ViewHolder viewHolder, int direction) {
            // no-op
        }

        @Override
        public boolean canDropOver(
                RecyclerView recyclerView, ViewHolder current, ViewHolder target) {
            boolean currentDraggable = isPassivelyDraggable(current);
            boolean targetDraggable = isPassivelyDraggable(target);
            return currentDraggable && targetDraggable;
        }

        /**
         * Update the visual state of this row.
         *
         * @param dragged    Whether this row is currently being dragged.
         * @param viewHolder The DraggableRowViewHolder that is holding this row's content.
         */
        private void updateVisualState(boolean dragged, ViewHolder viewHolder) {
            // Animate background colors and elevations
            ViewCompat.animate(viewHolder.itemView)
                    .translationZ(dragged ? mDraggedElevation : 0)
                    .withEndAction(
                            ()
                                    -> viewHolder.itemView.setBackgroundColor(
                                            dragged ? mDraggedBackgroundColor : Color.TRANSPARENT))
                    .setDuration(ANIMATION_DELAY_MS)
                    .start();
        }
    }

    /**
     * Listens to drag actions in a drag-reorderable list.
     */
    public interface DragListener {
        /**
         * Called when drag starts or ends.
         *
         * @param drag True iff drag is currently on.
         */
        void onDragStateChange(boolean drag);
    }

    /**
     * Construct a DragReorderableListAdapter.
     *
     * @param context The context for that this DragReorderableListAdapter occupies.
     */
    public DragReorderableListAdapter(Context context) {
        mContext = context;

        Resources resource = context.getResources();
        // Set the alpha to 90% when dragging which is 230/255
        mDraggedBackgroundColor = ColorUtils.setAlphaComponent(
                ApiCompatibilityUtils.getColor(resource, R.color.default_bg_color_elev_1),
                resource.getInteger(R.integer.list_item_dragged_alpha));
        mDraggedElevation = resource.getDimension(R.dimen.list_item_dragged_elevation);
    }

    @Override
    public int getItemCount() {
        return mElements.size();
    }

    protected T getItemByPosition(int position) {
        return mElements.get(position);
    }

    /**
     * Enables drag & drop interaction on the RecyclerView that this adapter is attached to.
     */
    public void enableDrag() {
        if (mItemTouchHelper == null) {
            mTouchHelperCallback = new DragTouchCallback();
            mItemTouchHelper = new ItemTouchHelper(mTouchHelperCallback);
        }
        mItemTouchHelper.attachToRecyclerView(mRecyclerView);
    }

    /**
     * Disables drag & drop interaction.
     */
    public void disableDrag() {
        if (mItemTouchHelper != null) mItemTouchHelper.attachToRecyclerView(null);
    }

    /**
     * Sets the order of the items in the drag-reorderable list.
     *
     * @param order The new order for the items.
     */
    protected abstract void setOrder(List<T> order);

    /**
     * Returns true iff a drag can start on viewHolder.
     *
     * @param viewHolder The view holder of interest.
     * @return True iff a drag can start on viewHolder.
     */
    protected abstract boolean isActivelyDraggable(ViewHolder viewHolder);

    /**
     * Returns true iff another item can be dragged over viewHolder.
     *
     * @param viewHolder The view holder of interest.
     * @return True iff other items can be dragged over viewHolder.
     */
    protected abstract boolean isPassivelyDraggable(ViewHolder viewHolder);

    /**
     * Get the item inside of a view holder.
     *
     * @param holder The view holder of interest.
     * @return The item contained by holder.
     */
    protected T getItemByHolder(ViewHolder holder) {
        return getItemByPosition(mRecyclerView.getChildLayoutPosition(holder.itemView));
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        mRecyclerView = recyclerView;
    }

    @Override
    public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
        mRecyclerView = null;
    }

    /**
     * Set the drag state delegate for this adapter.
     * It is expected that the drag state delegate will be set through calling this method.
     *
     * @param delegate The drag state delegate for this adapter.
     */
    protected void setDragStateDelegate(DragStateDelegate delegate) {
        mDragStateDelegate = delegate;
    }

    /**
     * @param l The drag listener to be added.
     */
    public void addDragListener(DragListener l) {
        mListeners.addObserver(l);
    }

    /**
     * @param l The drag listener to be added.
     */
    public void removeDragListener(DragListener l) {
        mListeners.removeObserver(l);
    }

    /**
     * Called when drag state changes (drag starts / ends), and notifies all listeners.
     *
     * @param drag True iff drag is currently on.
     */
    private void onDragStateChange(boolean drag) {
        for (DragListener l : mListeners) {
            l.onDragStateChange(drag);
        }
    }

    /**
     * Simulate a drag. All items that are involved in the drag must be visible (no scrolling).
     *
     * @param start The index of the ViewHolder that you want to drag.
     * @param end The index this ViewHolder should be dragged to and dropped at.
     */
    @VisibleForTesting
    public void simulateDragForTests(int start, int end) {
        ViewHolder viewHolder = mRecyclerView.findViewHolderForAdapterPosition(start);
        mItemTouchHelper.startDrag(viewHolder);
        int increment = start < end ? 1 : -1;
        int i = start;
        while (i != end) {
            i += increment;
            mTouchHelperCallback.onMove(
                    mRecyclerView, viewHolder, mRecyclerView.findViewHolderForAdapterPosition(i));
        }
        mTouchHelperCallback.onSelectedChanged(viewHolder, ItemTouchHelper.ACTION_STATE_IDLE);
        mTouchHelperCallback.clearView(mRecyclerView, viewHolder);
    }
}


text:
import _plotly_utils.basevalidators

class FunnelareaValidator(_plotly_utils.basevalidators.CompoundArrayValidator):
    def __init__(
        self, plotly_name="funnelarea", parent_name="layout.template.data", **kwargs
    ):
        super(FunnelareaValidator, self).__init__(
            plotly_name=plotly_name,
            parent_name=parent_name,
            data_class_str=kwargs.pop("data_class_str", "Funnelarea"),
            data_docs=kwargs.pop(
                "data_docs",
                """
""",
            ),
            **kwargs
        )

redpajama_set_name: RedPajamaGithub


text:
${package}

public class ${mainClass} {
    public static void main(String[] args) {
        System.out.println("Hello RoboVM");
    }
}


text:
<?xml version="1.0" encoding="UTF-8"?>

<!--
  ~ Licensed to the Apache Software Foundation (ASF) under one or more
  ~ contributor license agreements.  See the NOTICE file distributed with
  ~ this work for additional information regarding copyright ownership.
  ~ The ASF licenses this file to You 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.
  -->

<!DOCTYPE acl PUBLIC "-//GemStone Systems, Inc.//GemFire XML Authorization 1.0//EN"
        "org/apache/geode/security/templates/authz5_5.dtd" >
<acl>

  <role name="reader">
    <user>gemfire1</user>
    <user>gemfire2</user>
    <user>gemfire3</user>
    <user>gemfire4</user>
    <user>gemfire5</user>
  </role>

  <role name="writer">
    <user>gemfire1</user>
    <user>gemfire2</user>
    <user>gemfire6</user>
    <user>gemfire7</user>
    <user>gemfire8</user>
  </role>

  <role name="cacheOps">
    <user>gemfire1</user>
    <user>gemfire2</user>
  </role>

  <role name="queryRegions">
    <user>gemfire9</user>
    <user>gemfire10</user>
  </role>

  <permission role="cacheOps">
    <operation>QUERY</operation>
    <operation>EXECUTE_CQ</operation>
    <operation>STOP_CQ</operation>
    <operation>CLOSE_CQ</operation>
  </permission>

  <permission role="reader">
    <operation>GET</operation>
    <operation>REGISTER_INTEREST</operation>
    <operation>UNREGISTER_INTEREST</operation>
    <operation>KEY_SET</operation>
    <operation>CONTAINS_KEY</operation>
    <operation>EXECUTE_FUNCTION</operation>
  </permission>

  <permission role="writer">
    <operation>PUT</operation>
    <operation>PUTALL</operation>
    <operation>DESTROY</operation>
    <operation>INVALIDATE</operation>
    <operation>REGION_CLEAR</operation>
  </permission>

  <permission role="queryRegions" regions="Portfolios,/Positions//,/AuthRegion">
    <operation>QUERY</operation>
    <operation>EXECUTE_CQ</operation>
    <operation>STOP_CQ</operation>
    <operation>CLOSE_CQ</operation>
  </permission>

</acl>


text:
package info.nightscout.android.settings;

import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;

import info.nightscout.android.R;
import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper;

public class SettingsActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_settings);

        /* set fragment */
        getFragmentManager().beginTransaction().replace(R.id.settings_frame, new SettingsFragment()).commit();

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setTitle("Settings");
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                finish();
                break;
        }
        return true;
    }

    @Override
    protected void attachBaseContext(Context newBase) {
        super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
    }
}


text:
% Making a new parser from scratch

Writing a parser is a very fun, interactive process, but sometimes a daunting task. How do you test it? How to  see ambiguities in specifications?

nom is designed to abstract data manipulation (counting array offsets, converting to structures, etc) while providing a safe, composable API. It also takes care of making the code easy to test and read, but it can be confusing at first, if you are not familiar with parser combinators, or if you are not used to Rust macros.

This document is here to help you in getting started with nom. If you need more specific help, please ping `geal` on IRC (mozilla, freenode, geeknode, oftc), go to `#nom` on Mozilla IRC, or on the [Gitter chat room](https://gitter.im/Geal/nom).

# First step: the initial research

A big part of the initial work lies in accumulating enough documentation and samples to understand the format. The specification is useful, but specifications represent an "official" point of view, that may not be the real world usage. Any blog post or open source code is useful, because it shows how people understand the format, and how they work around each other's bugs (if you think a specification ensures every implementation is consistent with the others, think again).

You should get a lot of samples (file or network traces) to test your code. The easy way is to use a small number of samples coming from the same source and develop everything around them, to realize later that they share a very specific bug.

# Code organization

While it is tempting to insert the parsing code right inside the rest of the logic, it usually results in  unmaintainable code, and makes testing challenging. Parser combinators, the parsing technique used in nom, assemble a lot of small functions to make powerful parsers. This means that those functions only depend on their input, not on an external state. This makes it easy to parse the input partially, and to test those functions independently.

Usually, you can separate the parsing functions in their own module, so you could have a `src/lib.rs`file containing this:

```rust
# #[macro_use] extern crate nom;
# use nom::IResult;
# fn main() {
  fn take_wrapper(input: &[u8], i: u8) -> IResult<&[u8],&[u8]> { take!(input, i * 10) }

// will make a parser taking 20 bytes
  named!(parser, apply!(take_wrapper, 2));
# }

```

```ignore
#[macro_use]
extern crate nom;
pub mod parser;
```

And use the methods and structure from `parser` there. The `src/parser.rs` would then import nom functions and structures if needed:

```rust
# #[macro_use] extern crate nom;
use nom::{be_u16, be_u32};
# fn main() {}
```

# Writing a first parser

Let's parse a simple expression like `(12345)`. nom parsers are functions that use the `nom::IResult` type everywhere. As an example, a parser taking a byte slice `&[u8]` and returning a 32 bits unsigned integer `u32` would have this signature: `fn parse_u32(input: &[u8]) -> IResult<&[u8], u32>`.

The `IResult` type depends on the input and output types, and an optional custom error type. This enum can either contain `Done(i,o)` containing the remaining input and the output value, an error, or an indication that more data is needed.

```ignore
# #[macro_use] extern crate nom;
# use nom::{Err,Needed};
#[derive(Debug,PartialEq,Eq,Clone)]
pub enum IResult<I,O,E=u32> {
  Done(I,O),
  Error(Err<I,E>),
  Incomplete(Needed)
}
# fn main() {}
```

nom uses this type everywhere. Every combination of parsers will pattern match on this to know if it must return a value, an error, consume more data, etc. But this is done behind the scenes most of the time.

nom provides a macro for function definition, called `named!`:

```rust
# #[macro_use] extern crate nom;
# fn main() {}
named!(my_function( &[u8] ) -> &[u8], tag!("abcd"));

named!(my_function2<&[u8], &[u8]>, tag!("abcd"));

named!(my_function3, tag!("abcd"));
```

But you could as easily define the function yourself like this:

```rust
# #[macro_use] extern crate nom;
# fn main() {}
# use nom::IResult;
fn my_function(input: &[u8]) -> IResult<&[u8], &[u8]> {
  tag!(input, "abcd")
}
```

Note that we pass the input to the first parser in the manual definition, while we do not when we use `named!`. This is a macro trick specific to nom: every parser takes the input as first parameter, and the macros take care of giving the remaining input to the next parser. As an example, take a simple parser like the following one, which recognizes the word "hello" then takes the next 5 bytes:

```rust
# #[macro_use] extern crate nom;
# fn main() {}
named!(prefixed, preceded!(tag!("hello"), take!(5)));
```

Once the macros have expanded, this would correspond to:

```ignore
# #[macro_use] extern crate nom;
# fn main() {}
fn prefixed(i: &[u8]) -> ::nom::IResult<&[u8], &[u8]> {
    {
        match {
                  #[inline(always)]
                  fn as_bytes<T: ::nom::AsBytes>(b: &T) -> &[u8] {
                      b.as_bytes()
                  }
                  let expected = "hello";
                  let bytes = as_bytes(&expected);
                  {
                      let res: ::nom::IResult<&[u8], &[u8]> =
                          if bytes.len() > i.len() {
                              ::nom::IResult::Incomplete(::nom::Needed::Size(bytes.len()))
                          } else if &i[0..bytes.len()] == bytes {
                              ::nom::IResult::Done(&i[bytes.len()..],
                                                   &i[0..bytes.len()])
                          } else {
                              ::nom::IResult::Error(::nom::Err::Position(::nom::ErrorKind::Tag,
                                                                         i))
                          };
                      res
                  }
              } {
            ::nom::IResult::Error(a) => ::nom::IResult::Error(a),
            ::nom::IResult::Incomplete(i) => ::nom::IResult::Incomplete(i),
            ::nom::IResult::Done(i1, _) => {
                match {
                          let cnt = 5 as usize;
                          let res: ::nom::IResult<&[u8], &[u8]> =
                              if i1.len() < cnt {
                                  ::nom::IResult::Incomplete(::nom::Needed::Size(cnt))
                              } else {
                                  ::nom::IResult::Done(&i1[cnt..],
                                                       &i1[0..cnt])
                              };
                          res
                      } {
                    ::nom::IResult::Error(a) => ::nom::IResult::Error(a),
                    ::nom::IResult::Incomplete(i) =>
                    ::nom::IResult::Incomplete(i),
                    ::nom::IResult::Done(i2, o2) => {
                        ::nom::IResult::Done(i2, o2)
                    }
                }
            }
        }
    }
}
```

While this may look like a lot of code, the compiler and the CPU will happily optimize everything, do not worry. You can see that the function matches on the result of the first parser, stops there if it returned an error or incomplete, and if it returned a value, takes the remaining input `i1`, applies the second parser on it, then matches on the result (and returns the value `o2` and the remaining input `i2`).

A lot of complex patterns are implemented that way: generic macros combining other macros or functions. This will handle partial consumption and passing data slices for you.

Since it is easy to combine small parsers, I encourage you to write small functions corresponding to specific parts of the format, test them independently, then combine them in more general parsers.

# Finding the right combinator

nom has a lot of different combinators, depending on the use case. They are all described in the [reference](http://rust.unhandledexpression.com/nom/).

[Basic functions](http://rust.unhandledexpression.com/nom/#functions) are available. They deal mostly in recognizing character types, like `alphanumeric` or `digit`. They also parse big endian and little endian integers and floats of multiple sizes.

Most of the macros are there to combine parsers, and they do not depend on the input type. this is the case for all of those defined in [src/macros.rs](https://github.com/Geal/nom/blob/master/src/macros.rs). The reference indicates a [possible type signature](http://rust.unhandledexpression.com/nom/#macros) for what the macros expect and return. In case of doubt, the documentation often indicates a [code example](http://rust.unhandledexpression.com/nom/macro.many0!.html) after the macro definition.

## Type specific combinators

Byte slice related macros can be found in [src/bytes.rs](https://github.com/Geal/nom/blob/master/src/bytes.rs). This file contains the following combinators: `tag!`, `is_not!`, `is_a!`, `escaped!`, `escaped_transform!`, `take_while!`, `take_while1!`, `take_till!`, `take!`, `take_str!`, `take_until_and_consume!`, `take_until_either!`, `take_until_either_and_consume`.

Bit stream related macros are in [src/bits.rs](https://github.com/Geal/nom/blob/master/src/bits.rs).

Character related macros are in [src/character.rs](https://github.com/Geal/nom/blob/master/src/character.rs).

Regular expression related macros are in [src/regexp.rs](https://github.com/Geal/nom/blob/master/src/regexp.rs).

# Testing the parsers

Once you have a parser function, a good trick is to test it on a lot of the samples you gathered, and integrate this to your unit tests. To that end, put all of the test files in a folder like `assets` and refer to test files like this:

```ignore
  #[test]
  fn header_test() {
    let data = include_bytes!("../assets/axolotl-piano.gif");
    println!("bytes:\n{}", &data[0..100].to_hex(8));
    let res = header(data);
```

The `include_bytes!` macro (provided by Rust's standard library) will integrate the file as a byte slice in your code. You can then just refer to the part of the input the parser has to handle via its offset. Here, we take the first 100 bytes of a GIF file to parse its header (complete code [here](https://github.com/Geal/gif.rs/blob/master/src/parser.rs#L305-L309)).

If your parser handles textual data, you can just use a lot of strings directly in the test, like this:

```ignore
#[test]
fn factor_test() {
  assert_eq!(factor(&b"3"[..]),       IResult::Done(&b""[..], 3));
  assert_eq!(factor(&b" 12"[..]),     IResult::Done(&b""[..], 12));
  assert_eq!(factor(&b"537  "[..]),   IResult::Done(&b""[..], 537));
  assert_eq!(factor(&b"  24   "[..]), IResult::Done(&b""[..], 24));
}
```

The more samples and test cases you get, the more you can experiment with your parser design.

# Debugging the parsers

While Rust macros are really useful to get a simpler syntax, they can sometimes give cryptic errors. As an example, `named!(manytag, many0!(take!(5)));` would result in the following error:

```ignore
<nom macros>:6:38: 6:41 error: mismatched types:
 expected `&[u8]`,
    found `collections::vec::Vec<&[u8]>`
(expected &-ptr,
    found struct `collections::vec::Vec`) [E0308]
<nom macros>:6 } $ crate:: IResult:: Done ( input , res ) } ) ; ( $ i : expr , $ f : expr )
                                                    ^~~
<nom macros>:20:1: 20:34 note: in this expansion of many0! (defined in <nom macros>)
tests/arithmetic.rs:13:1: 13:35 note: in this expansion of named! (defined in <nom macros>)
<nom macros>:6:38: 6:41 help: run `rustc --explain E0308` to see a detailed explanation
error: aborting due to previous error
```

This particular one is caused by `named!` generating a function returning a `IResult< &[u8], &[u8] >`, while `many0!(take!(5))` returns a `IResult< &[u8], Vec<&[u8]> >`.

There are a few tools you can use to debug how code is generated.

## trace_macros

The `trace_macros` feature show how macros are applied. To use it, add `#![feature(trace_macros)]` at the top of your file (you need Rust nightly for this), then apply it like this:

```ignore
trace_macros!(true);
named!(manytag< Vec<&[u8]> >, many0!(take!(5)));
trace_macros!(false);
```

It will result in the following output during compilation:

```ignore
named! { manytag , many0 ! ( take ! ( 5 ) ) }
many0! { i , take ! ( 5 ) }
take! { input , 5 }
```

## Pretty printing

rustc can show how code is expanded with the option `--pretty=expanded`. If you want to use it with cargo, use the following command line: `cargo rustc <cargo options> -- -Z unstable-options --pretty=expanded`

It will print the `manytag` function like this:

```rust
# #[macro_use] extern crate nom;
# fn main() {}
fn manytag(i: &[u8]) -> ::nom::IResult<&[u8], Vec<&[u8]>> {
    {
        let mut res = Vec::new();
        let mut input = i;
        while let ::nom::IResult::Done(i, o) =
                  {
                      let cnt = 5 as usize;
                      let res: ::nom::IResult<&[u8], &[u8]> =
                          if input.len() < cnt {
                              ::nom::IResult::Incomplete(::nom::Needed::Size(cnt))
                          } else {
                              ::nom::IResult::Done(&input[cnt..],
                                                   &input[0..cnt])
                          };
                      res
                  } {
            if i.len() == input.len() { break ; }
            res.push(o);
            input = i;
        }
        ::nom::IResult::Done(input, res)
    }
}
```


text:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xemio.GameLibrary.Content.Loading;
using Xemio.GameLibrary.Game.Scenes.Transitions;
using Xemio.GameLibrary.Game.Timing;
using Xemio.GameLibrary.Input;
using Xemio.GameLibrary.Logging;
using Xemio.GameLibrary.Rendering;
using Xemio.GameLibrary.Content;

namespace Xemio.GameLibrary.Game.Scenes
{
    public abstract class Scene : SceneContainer, IEnumerable<Scene>
    {
        #region Logger
        private static readonly Logger logger = LogManager.GetCurrentClassLogger();
        #endregion

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="Scene"/> class.
        /// </summary>
        protected Scene()
        {
            this.IsVisible = true;
            this.IsPaused = false;

            this.LoadingReport = new SceneLoadingReport();
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets the parent.
        /// </summary>
        public SceneContainer Parent { get; internal set; }
        /// <summary>
        /// Gets the loading report.
        /// </summary>
        public ILoadingHandler LoadingReport { get; protected internal set; }
        /// <summary>
        /// Gets a value indicating whether this <see cref="Scene"/> is loaded.
        /// </summary>
        public bool IsLoaded { get; private set; }
        /// <summary>
        /// Gets a value indicating whether this <see cref="Scene"/> is loading.
        /// </summary>
        public bool IsLoading { get; private set; }
        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="Scene"/> is visible.
        /// </summary>
        public bool IsVisible { get; set; }
        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="Scene"/> is paused.
        /// </summary>
        public bool IsPaused { get; set; }
        /// <summary>
        /// Gets a value indicating the index during a game tick.
        /// </summary>
        public virtual int TickIndex
        {
            get { return 0; }
        }
        /// <summary>
        /// Gets a value indicating the index during the rendering process.
        /// </summary>
        public virtual int RenderIndex
        {
            get { return 0; }
        }
        #endregion

        #region Helper Properties
        /// <summary>
        /// Gets the serializer.
        /// </summary>
        protected SerializationManager Serializer
        {
            get { return XGL.Components.Require<SerializationManager>(); }
        }
        /// <summary>
        /// Gets the content manager.
        /// </summary>
        protected ContentManager ContentManager
        {
            get { return XGL.Components.Require<ContentManager>(); }
        }
        /// <summary>
        /// Gets the mouse listener.
        /// </summary>
        protected InputManager InputManager
        {
            get { return XGL.Components.Get<InputManager>(); }
        }
        /// <summary>
        /// Gets the local player input.
        /// </summary>
        protected PlayerInput Input
        {
            get { return this.InputManager.LocalInput; }
        }
        /// <summary>
        /// Gets the scene manager.
        /// </summary>
        protected SceneManager SceneManager
        {
            get { return XGL.Components.Get<SceneManager>(); }
        }
        #endregion

        #region Internal Methods
        /// <summary>
        /// Loads the content for the specified scene.
        /// </summary>
        internal void LoadContentIfNeeded()
        {
            if (!this.IsLoaded && !this.IsLoading)
            {
                logger.Info("Starting content loading for {0}.", this);

                this.IsLoading = true;
                Action action = () =>
                {
                    var loader = new BatchedContentLoader(this.LoadingReport);

                    this.LoadContent(loader);
                    loader.ExecuteBatchedActions();

                    this.IsLoaded = true;
                    this.IsLoading = false;

                    logger.Info("Content for {0} loaded.", this);
                };

                Task.Factory.StartNew(action, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default);
            }
        }
        #endregion

        #region Methods
        /// <summary>
        /// Transitions the scene to the specified one.
        /// </summary>
        /// <typeparam name="TTransition">The type of the transition.</typeparam>
        /// <param name="scene">The scene.</param>
        protected void TransitionTo<TTransition>(Scene scene) where TTransition : ITransition, new()
        {
            this.TransitionTo(scene, new TTransition());
        }
        /// <summary>
        /// Transitions the scene to the specified one.
        /// </summary>
        /// <param name="scene">The scene.</param>
        /// <param name="transition">The transition.</param>
        protected void TransitionTo(Scene scene, ITransition transition)
        {
            this.TransitionTo(new TransitionScene(transition, this, scene));
        }
        /// <summary>
        /// Transitions the scene to the specified one.
        /// </summary>
        /// <param name="scene">The scene.</param>
        protected void TransitionTo(Scene scene)
        {
            this.SceneManager.Add(scene);
            this.Remove();
        }
        /// <summary>
        /// Brings the scene to the front.
        /// </summary>
        public void BringToFront()
        {
            this.SceneManager.Remove(this);
            this.SceneManager.Add(this);
        }
        /// <summary>
        /// Removes this scene.
        /// </summary>
        public void Remove()
        {
            if (this.Parent != null)
            {
                this.Parent.Remove(this);
            }
        }
        /// <summary>
        /// Loads the scenes content including textures, brushes, fonts, pens etc.
        /// </summary>
        /// <param name="loader">The content loader.</param>
        public virtual void LoadContent(IContentLoader loader)
        {
        }
        /// <summary>
        /// Called when the scene was added to a parent.
        /// </summary>
        public virtual void OnEnter()
        {

        }
        /// <summary>
        /// Called when the scene gets removed from it's parent.
        /// </summary>
        public virtual void OnLeave()
        {

        }
        #endregion

        #region IEnumerable<Scene> Member
        /// <summary>
        /// Gets the enumerator.
        /// </summary>
        public IEnumerator<Scene> GetEnumerator()
        {
            return this.Scenes.GetEnumerator();
        }
        #endregion

        #region IEnumerable Member
        /// <summary>
        /// Gets the enumerator.
        /// </summary>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
        #endregion
    }
}


text:
#ifndef XMLSERIAL_LIST_H
#define XMLSERIAL_LIST_H

#include <list>
#include <sstream>
#include "xmlserial.h"

namespace XMLSERIALNAMESPACE {
	// if T is not "shiftable"
	template<typename T,typename A>
	struct TypeInfo<std::list<T,A>,
	typename Type_If<!IsShiftable<T>::atall,void>::type> {
		inline static const char *namestr() { return "list"; }
		template<typename S>
		inline static void addotherattr(XMLTagInfo &fields,
				const std::list<T,A> &, S &) { }
		inline static bool isshort(const std::list<T,A> &) { return false; }
		inline static bool isinline(const std::list<T,A> &) { return false; }
		template<typename S>
		inline static void save(const std::list<T,A> &l,
				S &os,int indent) {
			os << std::endl;
			int c=0;
			for(typename std::list<T,A>::const_iterator i=l.begin();
					i!=l.end();++i,++c) {
				XMLTagInfo fields;
				SaveWrapper(*i,fields,os,indent+1);
			}
			Indent(os,indent);
		}
		template<typename S>
		inline static void load(std::list<T,A> &l, const XMLTagInfo &info,
				S &is) {
			l.clear();
			XMLTagInfo eleminfo;
			while(1) {
				ReadTag(is,eleminfo);
				if (eleminfo.isend && !eleminfo.isstart) {
					if (eleminfo.name == namestr()) {
						return;
					}
					throw streamexception(std::string("Stream Input Format Error: expected end tag for ")+namestr()+", received end tag for "+eleminfo.name);
				}
#if _cplusplus <= 199711L
				l.push_back(T());
#else
				l.emplace_back();
#endif
				LoadWrapper(l.back(),eleminfo,is);
			}
		}
	};

	// If T is "shiftable"
	template<typename T,typename A>
	struct TypeInfo<std::list<T,A>,
				typename Type_If<IsShiftable<T>::atall,void>::type> {
		inline static const char *namestr() {
			static char *ret = TName("list",1,TypeInfo<T>::namestr());
			return ret;
		}
		template<typename S>
		inline static void addotherattr(XMLTagInfo &fields, const std::list<T,A> &l, S &os) {
			fields.attr["nelem"] = T2str(l.size());
		}
		inline static bool isshort(const std::list<T,A> &) { return false; }
		inline static bool isinline(const std::list<T,A> &) { return false; }
		template<typename S>
		inline static void save(const std::list<T,A> &l,
				S &os, int indent) {
			for(typename std::list<T,A>::const_iterator i=l.begin();i!=l.end();++i)
				os << *i << ' ';
		}
		template<typename S>
		inline static void load(std::list<T,A> &l, const XMLTagInfo &info,
				S &is) {
			std::map<std::string,std::string>::const_iterator ni
								= info.attr.find("nelem");
			if (ni == info.attr.end())
				throw streamexception("Stream Input Format Error: list (when elements are saved with <<) needs nelem attribute");
			int n = atoi(ni->second.c_str());

			for(int i=0;i<n;i++) {
#if _cplusplus <= 199711L
				l.push_back(T());
#else
                    l.emplace_back();
#endif
				is >> l.back();
			}
			ReadEndTag(is,namestr());
		}
	};

}
#endif


text:
cask "font-josefin-slab" do
  version :latest
  sha256 :no_check

  url "https://github.com/google/fonts/trunk/ofl/josefinslab",
      verified: "github.com/google/fonts/",
      using:    :svn
  name "Josefin Slab"
  homepage "https://fonts.google.com/specimen/Josefin+Slab"

  font "JosefinSlab-Italic[wght].ttf"
  font "JosefinSlab[wght].ttf"
end


text:
title: Aftermarket ASP.NET MVC - Part 5 - Feature Folders
layout: post
---

This is **part 5** of a multi-part series on "fixing" some of the inherit design problems with ASP.NET MVC.

- [Part 1 - Introduction]({% post_url 2016-01-05-bridging-aspnet-mvc-part-1 %})
- [Part 2 - The View Engine]({% post_url 2016-01-05-bridging-aspnet-mvc-part-2-the-view-engine %})
- [Part 3 - View Model Conventions]({% post_url 2016-01-07-bridging-aspnet-mvc-part-3-view-model-conventions %})
- [Part 4 - Routing and URL Generation]({% post_url 2016-01-13-bridging-aspnet-mvc-part-4-routing-and-urls %})
- [Part 5 - Feature Folders]({% post_url 2016-02-19-aftermarket-aspnet-mvc-part-5-feature-folders %})
- Part 6 - ActionResults and Content Negotiation

I've also setup a [repository on GitHub](https://github.com/jdaigle/aspnetmvc5demo) that includes many of these experiments and implementations.

Expanding on the theme from last time:

> Don't let your routing solution dictate how to organize your code.

ASP.NET MVC establishes the convention of putting all of your *controllers* inside of a `Controllers\` directory and all of your *views* instead of a `Views\` directory. This is, no surprise, extremely similar to the convention established by [Rails](http://rubyonrails.org/). Remember that Rails was the new-hotness when ASP.NET MVC was first developed around 2007-2008.

A prototypical ASP.NET MVC source code layout:

    MyApp/
    ├── assets/
    │   ├── site.css
    ├── Controllers/
    │   ├── HomeController.cs
    │   ├── ProductsController.cs
    ├── Views/
    │   ├── Home/
    │   │   ├── HomePage.cshtml
    │   │   ├── AboutPage.cshtml
    │   ├── Products/
    │   │   ├── Index.cshtml
    │   │   ├── Detail.cshtml
    │   ├── Shared/
    │   │   ├── _Layout.cshtml
    │   ├── _ViewStart.cshtml
    │   ├── Web.config

Yuck!

A lot of people have written about how this is just a terrible way to organize your code. At the top level, you don't see *your application*. You see an MVC framework details leaking through.

I *should* be able to organization my code based on *feature* instead of what type of class it is.

    MyApp/
    ├── assets/
    │   ├── site.css
    ├── Home/
    │   ├── HomeController.cs
    │   ├── HomePage.cshtml
    │   ├── HomePageViewModel.cs
    │   ├── About.cshtml
    │   ├── AboutViewModel.cs
    ├── Products/
    │   ├── ProductsController.cs
    │   ├── Index.cshtml
    │   ├── IndexViewModel.cs
    │   ├── Detail.cshtml
    │   ├── DetailViewModel.cs
    ├── SharedViews/
    │   ├── _Layout.cshtml
    ├── _ViewStart.cshtml
    ├── Web.config

Now you can look at the project structure and get a sense of what the app is! Additionally, all of the code related to a feature is in close proximity. In my opinion this makes development easier, possibly even faster.

### A Quick Word About *Areas*

In theory, the *Areas* feature can get you pretty close to this model out of the box. However I'm not a fan of *Areas*. They were originally designed to work sort of like "sub-projects". In theory they can physically live in their own assemblies, but this causes problems. But at the end of the day *Areas* still suffer, though internally, from the same organizational problems.

I prefer to avoid areas.

### Making Feature Folders Work

Unfortunately *Feature Folders* won't necessarily work out-of-the-box. There are a few things we need to tweak.

First, as a mentioned in [a previous article]({% post_url 2016-01-13-bridging-aspnet-mvc-part-4-routing-and-urls %}), assigning routes to individual actions is important.

Second, the default view engine only knows to look for *views* inside of `Views\`. But we can subclass the default engine using [the technique I wrote about here]({% post_url 2016-01-05-bridging-aspnet-mvc-part-2-the-view-engine %}) to make it work.

Inside the traditional `Views\` directory lives a special `Web.config`. This does two things: 1) it makes the Razor tooling work and 2) it prevents access to the cshtml files in the directory tree as "web pages" (as the views are commonly deployed, and then compiled at runtime). We may move *some* of the config to root the `Web.config` of our project.

First, we need to register and include the `RazorWebSectionGroup`.

    <configSections>
        <sectionGroup name="system.web.webPages.razor"
                      type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup,
                            System.Web.WebPages.Razor, Version=3.0.0.0,
                            Culture=neutral, PublicKeyToken=31BF3856AD364E35">

        </sectionGroup>
    </configSections>

    <system.web.webPages.razor>
        <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory,
                           System.Web.Mvc, Version=5.2.3.0,
                           Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <pages pageBaseType="System.Web.Mvc.WebViewPage">
        <namespaces>
            <add namespace="System.Web.Mvc" />
            <add namespace="System.Web.Mvc.Ajax" />
            <add namespace="System.Web.Mvc.Html" />
            <add namespace="System.Web.Routing" />
        </namespaces>
        </pages>
    </system.web.webPages.razor>

This essentially makes the Razor tooling and compilation work.

Next, under `<handlers>` in `<system.webServer>` we need to add:

    <add name="BlockViewHandler"
         path="*.cshtml"
         verb="*"
         preCondition="integratedMode"
         type="System.Web.HttpNotFoundHandler" />

In the default `Views\Web.config`, this handler is registered with the `path="*"`. But we don't want to block access to *all files*, just our cshtml files. Finally we can add an `appSetting` to turn off "webpages":

    <add key="webpages:Enabled" value="false" />

Unless you want normal web pages to work... and why would you at this point? In which case you'll need to leave them enabled and perhaps tweak the handler to not exclude the pages you want.

Alternatively you can copy the default `Views\Web.config` into each of your feature folders. But that's ugly and possibly un-maintainable.

Another interesting problem man run into: if you have a folder named `Foo\`, and a URL such as `~\Foo\` that matches that directory name, by default `System.Web.Routing` won't match that URL because it's a physical folder on disk. In order to force `System.Web.Routing` to match that URL, we need to set `RouteTable.Routes.RouteExistingFiles = true;`. This setting changes the behavior so that it *does not* first check that a file exists before attempting to find a route.

I also encourage setting up routes that explicitly ignore your static assets (CSS/JS, images, HTML files, etc.) to help with performance.

### Things Might Get Better with ASP.NET Core

*Feature Folders almost just work.* I think some of the decisions made in ASP.NET MVC are partially due to adopting the conventions of Rails-like frameworks, but also partly to workaround the inherit properties of ASP.NET.

In ASP.NET, traditionally, you deploy everything as a file. You're static content and your dynamic content (ASPX pages) are mixed. There's no routing, and URLs are reflective of the physical layout of files on disk.

But in almost any modern web application, except for static content, *URLs are an abstraction* over dynamic content.

Luckily ASP.NET Core throws away *everything* and starts from *scratch*. We may, for instance, have a project structure which looks like this:

    MyApp/
    ├── wwwroot/
    │   ├── assets/
    │   │   ├── site.css
    ├── Home/
    │   ├── HomeController.cs
    │   ├── HomePage.cshtml
    │   ├── HomePageViewModel.cs
    │   ├── About.cshtml
    │   ├── AboutViewModel.cs
    ├── Products/
    │   ├── ProductsController.cs
    │   ├── Index.cshtml
    │   ├── IndexViewModel.cs
    │   ├── Detail.cshtml
    │   ├── DetailViewModel.cs
    ├── SharedViews/
    │   ├── _Layout.cshtml
    ├── _ViewStart.cshtml

As you can see, they've introduced a `wwwroot` directory. This is a special folder which contains all of the static content that will be deployed too the root of the web application on the server. Everything else in the project *is just code*.

Fun fact: while you may compile this before deployment, it should be noted that ASP.NET Core has a new build model where it will compile your code at runtime *and* detect changes recompile and relaunch.


text:
package regexodus.derivative;

/**
 * Ported to Java from http://blog.errstr.com/2013/01/22/implementing-a-more-powerful-regex/
 * D_c(~L) = ~(D_c(L))
 * δ(~L) = ~(δ(L))
 */
public class Complement extends RegEx {
    private RegEx lang;

    private Complement(RegEx lang) {
        this.lang = lang;
    }

    @Override
    public RegEx derive(char[] c, int idx) {
        return new Complement(lang.derive(c, idx).shareParent(parent)).shareParent(parent);
    }

    @Override
    public boolean emptySuccess() {
        return !lang.emptySuccess();
    }

    @Override
    public int kind() {
        return COMPLEMENT;
    }

    @Override
    public void reset() {
        if(midway)
            return;
        midway = true;
        lang.reset();
        midway = false;
    }
}


text:
package org.mvel2.optimizers.impl.refl.nodes;

import org.mvel2.compiler.ExecutableStatement;
import org.mvel2.integration.VariableResolverFactory;

import java.lang.reflect.Method;

import static org.mvel2.util.ParseTools.getBestCandidate;
import static org.mvel2.util.ParseTools.getWidenedTarget;

public class MethodAccessor extends InvokableAccessor {

  private Method method;

  public Object getValue(Object ctx, Object elCtx, VariableResolverFactory vars) {
    if (!coercionNeeded) {
      try {
        if (nextNode != null) {
          return nextNode.getValue(method.invoke(ctx, executeAll(elCtx, vars, method)), elCtx, vars);
        }
        else {
          return method.invoke(ctx, executeAll(elCtx, vars, method));
        }
      }
      catch (IllegalArgumentException e) {
        if (ctx != null && method.getDeclaringClass() != ctx.getClass()) {
          Method o = getBestCandidate(parameterTypes, method.getName(), ctx.getClass(), ctx.getClass().getMethods(), true);
          if (o != null) {
            return executeOverrideTarget(getWidenedTarget(o), ctx, elCtx, vars);
          }
        }

        coercionNeeded = true;
        return getValue(ctx, elCtx, vars);
      }
      catch (Exception e) {
        throw new RuntimeException("cannot invoke method: " + method.getName(), e);
      }

    }
    else {
      try {
        if (nextNode != null) {
          return nextNode.getValue(method.invoke(ctx, executeAndCoerce(parameterTypes, elCtx, vars, method.isVarArgs())), elCtx, vars);
        }
        else {
          return method.invoke(ctx, executeAndCoerce(parameterTypes, elCtx, vars, method.isVarArgs()));
        }
      }
      catch (IllegalArgumentException e) {
        Object[] vs = executeAndCoerce(parameterTypes, elCtx, vars, false);
        Method newMeth;
        if ((newMeth = getWidenedTarget(getBestCandidate(vs, method.getName(), ctx.getClass(),
            ctx.getClass().getMethods(), false))) != null) {
          return executeOverrideTarget(newMeth, ctx, elCtx, vars);
        }
        else {
          throw e;
        }
      }
      catch (Exception e) {
        throw new RuntimeException("cannot invoke method: " + method.getName(), e);
      }
    }
  }

  private Object executeOverrideTarget(Method o, Object ctx, Object elCtx, VariableResolverFactory vars) {
    if (!coercionNeeded) {
      try {
        try {
          if (nextNode != null) {
            return nextNode.getValue(o.invoke(ctx, executeAll(elCtx, vars, o)), elCtx, vars);
          }
          else {
            return o.invoke(ctx, executeAll(elCtx, vars, o));
          }
        }
        catch (IllegalArgumentException e) {
          if (coercionNeeded) throw e;

          coercionNeeded = true;
          return executeOverrideTarget(o, ctx, elCtx, vars);
        }
      }
      catch (Exception e2) {
        throw new RuntimeException("unable to invoke method", e2);
      }
    }
    else {
      try {
        if (nextNode != null) {
          return nextNode.getValue(o.invoke(ctx, executeAndCoerce(o.getParameterTypes(), elCtx, vars, o.isVarArgs())), elCtx, vars);
        }
        else {
          return o.invoke(ctx, executeAndCoerce(o.getParameterTypes(), elCtx, vars, o.isVarArgs()));
        }
      }
      catch (IllegalAccessException e) {
        throw new RuntimeException("unable to invoke method (expected target: " + method.getDeclaringClass().getName() + "::" + method.getName() + "; " +
            "actual target: " + ctx.getClass().getName() + "::" + method.getName() + "; coercionNeeded=" + (coercionNeeded ? "yes" : "no") + ")");
      }
      catch (Exception e2) {
        throw new RuntimeException("unable to invoke method (expected target: " + method.getDeclaringClass().getName() + "::" + method.getName() + "; " +
            "actual target: " + ctx.getClass().getName() + "::" + method.getName() + "; coercionNeeded=" + (coercionNeeded ? "yes" : "no") + ")");
      }
    }
  }

  private Object[] executeAll(Object ctx, VariableResolverFactory vars, Method m) {
    if (length == 0) return GetterAccessor.EMPTY;

    Object[] vals = new Object[length];
    for (int i = 0; i < length - (m.isVarArgs() ? 1 : 0); i++) {
      vals[i] = parms[i].getValue(ctx, vars);
    }

    if (m.isVarArgs()) {
     if(parms == null){
        vals[length -1] = new Object[0];
     }
     else if (parms.length == length) {
          Object lastParam = parms[length - 1].getValue(ctx, vars);
          vals[length - 1] = lastParam == null || lastParam.getClass().isArray() ? lastParam : new Object[] {lastParam};
      } else {
        Object[] vararg = new Object[parms.length - length + 1];
        for (int i = 0; i < vararg.length; i++) vararg[i] = parms[length - 1 + i].getValue(ctx, vars);
        vals[length - 1] = vararg;
      }
    }

    return vals;
  }

  public Method getMethod() {
    return method;
  }

  public void setMethod(Method method) {
    this.method = method;
    this.length = (this.parameterTypes = this.method.getParameterTypes()).length;
  }

  public ExecutableStatement[] getParms() {
    return parms;
  }

  public void setParms(ExecutableStatement[] parms) {
    this.parms = parms;
  }

  public MethodAccessor() {
  }

  public MethodAccessor(Method method, ExecutableStatement[] parms) {
    setMethod(method);
    this.parms = parms;
  }

  public Object setValue(Object ctx, Object elCtx, VariableResolverFactory variableFactory, Object value) {
    try {
      return nextNode.setValue(method.invoke(ctx, executeAll(elCtx, variableFactory, method)), elCtx, variableFactory, value);
    }
    catch (IllegalArgumentException e) {
      if (ctx != null && method.getDeclaringClass() != ctx.getClass()) {
        Method o = getBestCandidate(parameterTypes, method.getName(), ctx.getClass(), ctx.getClass().getMethods(), true);
        if (o != null) {
          return nextNode.setValue(executeOverrideTarget(o, ctx, elCtx, variableFactory), elCtx, variableFactory, value);
        }
      }

      coercionNeeded = true;
      return setValue(ctx, elCtx, variableFactory, value);
    }
    catch (Exception e) {
      throw new RuntimeException("cannot invoke method", e);
    }
  }

  public Class getKnownEgressType() {
    return method.getReturnType();
  }
}


text:
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="CircleIndicator">
        <attr name="ci_width" format="dimension"/>
        <attr name="ci_height" format="dimension"/>
        <attr name="ci_margin" format="dimension"/>
        <attr name="ci_animator" format="reference"/>
        <attr name="ci_animator_reverse" format="reference"/>
        <attr name="ci_drawable" format="reference"/>
        <attr name="ci_drawable_unselected" format="reference"/>

        <attr name="ci_orientation" format="enum">
            <!-- Defines an horizontal widget. -->
            <enum name="horizontal" value="0"/>
            <!-- Defines a vertical widget. -->
            <enum name="vertical" value="1"/>
        </attr>

        <attr name="ci_gravity">
            <!-- Push object to the top of its container, not changing its size. -->
            <flag name="top" value="0x30"/>
            <!-- Push object to the bottom of its container, not changing its size. -->
            <flag name="bottom" value="0x50"/>
            <!-- Push object to the left of its container, not changing its size. -->
            <flag name="left" value="0x03"/>
            <!-- Push object to the right of its container, not changing its size. -->
            <flag name="right" value="0x05"/>
            <!-- Place object in the vertical center of its container, not changing its size. -->
            <flag name="center_vertical" value="0x10"/>
            <!-- Grow the vertical size of the object if needed so it completely fills its container. -->
            <flag name="fill_vertical" value="0x70"/>
            <!-- Place object in the horizontal center of its container, not changing its size. -->
            <flag name="center_horizontal" value="0x01"/>
            <!-- Grow the horizontal size of the object if needed so it completely fills its container. -->
            <flag name="fill_horizontal" value="0x07"/>
            <!-- Place the object in the center of its container in both the vertical and horizontal axis, not changing its size. -->
            <flag name="center" value="0x11"/>
            <!-- Grow the horizontal and vertical size of the object if needed so it completely fills its container. -->
            <flag name="fill" value="0x77"/>
            <!-- Additional option that can be set to have the top and/or bottom edges of
            the child clipped to its container's bounds.
            The clip will be based on the vertical gravity: a top gravity will clip the bottom
            edge, a bottom gravity will clip the top edge, and neither will clip both edges. -->
            <flag name="clip_vertical" value="0x80"/>
            <!-- Additional option that can be set to have the left and/or right edges of
            the child clipped to its container's bounds.
            The clip will be based on the horizontal gravity: a left gravity will clip the right
            edge, a right gravity will clip the left edge, and neither will clip both edges. -->
            <flag name="clip_horizontal" value="0x08"/>
            <!-- Push object to the beginning of its container, not changing its size. -->
            <flag name="start" value="0x00800003"/>
            <!-- Push object to the end of its container, not changing its size. -->
            <flag name="end" value="0x00800005"/>
        </attr>

    </declare-styleable>

</resources>


text:
import numpy
from six import moves

from chainer import cuda
from chainer import function
from chainer.utils import conv
from chainer.utils import type_check

if cuda.cudnn_enabled:
    cudnn = cuda.cudnn
    libcudnn = cuda.cudnn.cudnn
    _cudnn_version = libcudnn.getVersion()
    _fwd_pref = libcudnn.CUDNN_CONVOLUTION_FWD_SPECIFY_WORKSPACE_LIMIT
    if _cudnn_version >= 4000:
        _bwd_filter_pref = \
            libcudnn.CUDNN_CONVOLUTION_BWD_FILTER_SPECIFY_WORKSPACE_LIMIT
        _bwd_data_pref = \
            libcudnn.CUDNN_CONVOLUTION_BWD_DATA_SPECIFY_WORKSPACE_LIMIT

def _pair(x):
    if hasattr(x, '__getitem__'):
        return x
    return (x, x)

class Deconvolution2DFunction(function.Function):

    def __init__(self, stride=1, pad=0, outsize=None, use_cudnn=True):
        self.sy, self.sx = _pair(stride)
        self.ph, self.pw = _pair(pad)
        self.use_cudnn = use_cudnn
        self.outh, self.outw = (None, None) if outsize is None else outsize

    def check_type_forward(self, in_types):
        n_in = in_types.size()
        type_check.expect(2 <= n_in, n_in <= 3)
        x_type, w_type = in_types[:2]

        type_check.expect(
            x_type.dtype == numpy.float32,
            w_type.dtype == numpy.float32,
            x_type.ndim == 4,
            w_type.ndim == 4,
            x_type.shape[1] == w_type.shape[0]
        )

        if self.outh is not None:
            type_check.expect(
                x_type.shape[2] ==
                conv.get_conv_outsize(self.outh, w_type.shape[2],
                                      self.sy, self.ph),
            )
        if self.outw is not None:
            type_check.expect(
                x_type.shape[3] ==
                conv.get_conv_outsize(self.outw, w_type.shape[3],
                                      self.sx, self.pw),
            )

        if n_in.eval() == 3:
            b_type = in_types[2]
            type_check.expect(
                b_type.dtype == numpy.float32,
                b_type.ndim == 1,
                b_type.shape[0] == w_type.shape[1]
            )

    def forward_cpu(self, inputs):
        x, W = inputs[:2]
        b = inputs[2] if len(inputs) == 3 else None
        kh, kw = W.shape[2:]
        _, _, h, w = x.shape
        gcol = numpy.tensordot(W, x, (0, 1))
        # - k, m, n: shape of out_channel
        # - b: number of inputs
        # - h, w: height and width of kernels
        # k, m, n, b, h, w -> b, k, m, n, h, w
        gcol = numpy.rollaxis(gcol, 3)
        if self.outh is None:
            self.outh = conv.get_deconv_outsize(h, kh, self.sy, self.ph)
        if self.outw is None:
            self.outw = conv.get_deconv_outsize(w, kw, self.sx, self.pw)
        y = conv.col2im_cpu(
            gcol, self.sy, self.sx, self.ph, self.pw, self.outh, self.outw)
        # b, k, h, w
        if b is not None:
            y += b.reshape(1, b.size, 1, 1)
        return y,

    def forward_gpu(self, inputs):
        x, W = inputs[:2]
        b = inputs[2] if len(inputs) == 3 else None
        kh, kw = W.shape[2:]
        n, in_c, in_h, in_w = x.shape
        c = W.shape[1]  # out_c
        if self.outh is None:
            self.outh = conv.get_deconv_outsize(in_h, kh, self.sy, self.ph)
        if self.outw is None:
            self.outw = conv.get_deconv_outsize(in_w, kw, self.sx, self.pw)
        if cuda.cudnn_enabled and self.use_cudnn:
            x = cuda.cupy.ascontiguousarray(x)
            W = cuda.cupy.ascontiguousarray(W)
            if b is not None:
                b = cuda.cupy.ascontiguousarray(b)

            handle = cudnn.get_handle()
            x_desc = cudnn.create_tensor_descriptor(x)
            y = cuda.cupy.empty((n, c, self.outh, self.outw),
                                dtype=numpy.float32)
            y_desc = cudnn.create_tensor_descriptor(y)

            self.filter_desc = cudnn.create_filter_descriptor(W)
            self.conv_desc = cudnn.create_convolution_descriptor(
                (self.ph, self.pw), (self.sy, self.sx))
            if b is not None:
                self.bias_desc = cudnn.create_tensor_descriptor(
                    b[None, :, None, None])

            one = numpy.array(1, dtype=x.dtype).ctypes
            zero = numpy.array(0, dtype=x.dtype).ctypes

            if _cudnn_version >= 4000:
                self.max_workspace_size = c * kh * kw * 4
                algo = libcudnn.getConvolutionBackwardDataAlgorithm(
                    handle, self.filter_desc.value, x_desc.value,
                    self.conv_desc.value, y_desc.value, _bwd_data_pref,
                    self.max_workspace_size)
                workspace_size = \
                    libcudnn.getConvolutionBackwardDataWorkspaceSize(
                        handle, self.filter_desc.value, x_desc.value,
                        self.conv_desc.value, y_desc.value, algo)
                workspace = cuda.cupy.empty(
                    (max(workspace_size // 4, 1),), dtype=x.dtype)

                libcudnn.convolutionBackwardData_v3(
                    handle, one.data, self.filter_desc.value, W.data.ptr,
                    x_desc.value, x.data.ptr, self.conv_desc.value,
                    algo, workspace.data.ptr, workspace_size,
                    zero.data, y_desc.value, y.data.ptr)
            else:
                libcudnn.convolutionBackwardData_v2(
                    handle, one.data, self.filter_desc.value, W.data.ptr,
                    x_desc.value, x.data.ptr, self.conv_desc.value,
                    zero.data, y_desc.value, y.data.ptr)

            if b is not None:
                libcudnn.addTensor_v2(
                    handle, libcudnn.CUDNN_ADD_SAME_C,
                    one.data, self.bias_desc.value, b.data.ptr,
                    one.data, y_desc.value, y.data.ptr)
        else:
            W_mat = W.reshape(in_c, c * kh * kw)
            x_mats = x.reshape(n, in_c, in_h * in_w)
            gcol = cuda.cupy.empty(
                (n, c, kh, kw, in_h, in_w), dtype=numpy.float32)
            gcol_mats = gcol.reshape(n, c * kh * kw, in_h * in_w)
            for i in moves.range(n):
                cuda.cupy.dot(W_mat.T, x_mats[i], gcol_mats[i])
            y = conv.col2im_gpu(
                gcol, self.sy, self.sx, self.ph, self.pw, self.outh, self.outw)
            if b is not None:
                y += b.reshape(1, b.size, 1, 1)
        return y,

    def backward_cpu(self, inputs, grad_outputs):
        x, W = inputs[:2]
        b = inputs[2] if len(inputs) == 3 else None
        gy = grad_outputs[0]
        kh, kw = W.shape[2:]
        col = conv.im2col_cpu(
            gy, kh, kw, self.sy, self.sx, self.ph, self.pw)
        gW = numpy.tensordot(x, col, ([0, 2, 3], [0, 4, 5]))
        gx = numpy.tensordot(col, W, ([1, 2, 3], [1, 2, 3]))
        gx = numpy.rollaxis(gx, 3, 1)

        if b is None:
            return gx, gW
        else:
            gb = gy.sum(axis=(0, 2, 3))
            return gx, gW, gb

    def backward_gpu(self, inputs, grad_outputs):
        x, W = inputs[:2]
        b = inputs[2] if len(inputs) == 3 else None
        gy = grad_outputs[0]
        n, in_c, in_h, in_w = x.shape
        _, out_channels, kh, kw = W.shape
        c, h, w = gy.shape[1:]
        gx = cuda.cupy.empty((n, in_c, in_h, in_w), dtype=numpy.float32)

        if cuda.cudnn_enabled and self.use_cudnn:
            x = cuda.cupy.ascontiguousarray(x)
            W = cuda.cupy.ascontiguousarray(W)
            gy = cuda.cupy.ascontiguousarray(gy)

            handle = cudnn.get_handle()
            gy_desc = cudnn.create_tensor_descriptor(gy)
            gx_desc = cudnn.create_tensor_descriptor(gx)

            # chance to choose implicit-precomp-gemm algorithm
            self.max_workspace_size = out_channels * kh * kw * 4
            algo = libcudnn.getConvolutionForwardAlgorithm(
                handle, gy_desc.value, self.filter_desc.value,
                self.conv_desc.value, gx_desc.value, _fwd_pref,
                self.max_workspace_size)
            workspace_size = libcudnn.getConvolutionForwardWorkspaceSize(
                handle, gy_desc.value, self.filter_desc.value,
                self.conv_desc.value, gx_desc.value, algo)
            workspace = cuda.cupy.empty(
                (max(workspace_size // 4, 1),), dtype=numpy.float32)

            one = numpy.array(1, dtype=x.dtype).ctypes
            zero = numpy.array(0, dtype=x.dtype).ctypes

            libcudnn.convolutionForward(
                handle, one.data, gy_desc.value, gy.data.ptr,
                self.filter_desc.value, W.data.ptr,
                self.conv_desc.value, algo, workspace.data.ptr, workspace_size,
                zero.data, gx_desc.value, gx.data.ptr)
            # bias backward
            if b is not None:
                gb = cuda.cupy.empty_like(b)
                libcudnn.convolutionBackwardBias(
                    handle, one.data, gy_desc.value, gy.data.ptr,
                    zero.data, self.bias_desc.value, gb.data.ptr)
            gW = cuda.cupy.empty_like(W)
            # filter backward
            if _cudnn_version >= 4000:
                self.max_workspace_size = c * kh * kw * 4
                algo = libcudnn.getConvolutionBackwardFilterAlgorithm(
                    handle, gy_desc.value, gx_desc.value,
                    self.conv_desc.value, self.filter_desc.value,
                    _bwd_filter_pref, self.max_workspace_size)
                workspace_size = \
                    libcudnn.getConvolutionBackwardFilterWorkspaceSize(
                        handle, gy_desc.value, gx_desc.value,
                        self.conv_desc.value, self.filter_desc.value, algo)
                workspace = cuda.cupy.empty(
                    (max(workspace_size // 4, 1),), dtype=x.dtype)

                libcudnn.convolutionBackwardFilter_v3(
                    handle, one.data, gy_desc.value, gy.data.ptr,
                    gx_desc.value, x.data.ptr, self.conv_desc.value,
                    algo, workspace.data.ptr, workspace_size,
                    zero.data, self.filter_desc.value, gW.data.ptr)
            else:
                libcudnn.convolutionBackwardFilter_v2(
                    handle, one.data, gy_desc.value, gy.data.ptr,
                    gx_desc.value, x.data.ptr, self.conv_desc.value,
                    zero.data, self.filter_desc.value, gW.data.ptr)
        else:
            # Implementation using im2col
            col = conv.im2col_gpu(
                gy, kh, kw, self.sy, self.sx, self.ph, self.pw)

            W_mat = W.reshape(in_c, c * kh * kw)
            col_mats = col.reshape(
                n, c * kh * kw, in_h * in_w)
            gx_mats = gx.reshape(n, in_c, in_h * in_w)
            for i in moves.range(n):
                gx_mats[i] = W_mat.dot(col_mats[i])

            # bias backward
            if b is not None:
                gb = gy.sum(axis=(0, 2, 3))

            # filter backward
            gW = cuda.cupy.zeros_like(W)
            gW_mat = gW.reshape(in_c, c * kh * kw)
            x_mats = x.reshape(n, in_c, in_h * in_w)
            for i in moves.range(n):
                gW_mat += x_mats[i].dot(col_mats[i].T)

        if b is None:
            return gx, gW
        else:
            return gx, gW, gb

def deconvolution_2d(x, W, b=None, stride=1, pad=0,
                     outsize=None, use_cudnn=True):
    """Two dimensional deconvolution function.

    This is an implementation of two-dimensional deconvolution.
    It takes three variables: input image ``x``,
    the filter weight ``W``, and the bias vector ``b``.

    Args:
        x (~chainer.Variable): Input variable of shape :math:`(n, c_I, h, w)`
        W (~chainer.Variable): Weight variable of shape
        :math:`(c_I, c_O, k_H, k_W)`.
        b (~chainer.Variable): Bias variable of length :math:`c_O` (optional).
        stride (int or pair of ints): Stride of filter applications.
            ``stride=s`` and ``stride=(s, s)`` are equivalent.
        pad (int or pair of ints): Spatial padding width for input arrays.
            ``pad=p`` and ``pad=(p, p)`` are equivalent.
        outsize (tuple): Expected output size of deconvolutional operation.
            It should be pair of height and width :math:`(out_H, out_W)`.
            Default value is ``None`` and the outsize is estimated by
            input size, stride and pad.
        use_cudnn (bool): If True, then this function uses CuDNN if available.

    The filter weight has four dimensions :math:`(c_I, c_O, k_H, k_W)`
    which indicate the number of the number of input channels, output channels,
    height and width of the kernels, respectively.

    The bias vector is of size :math:`c_O`.

    Let :math:`X` be the input tensor of dimensions :math:`(n, c_I, h, w)`,
    :math:`(s_Y, s_X)` the stride of filter application, and
    :math:`(p_H, p_W)` the spatial padding size. Then, the output size
    :math:`(h_O, w_O)` is determined by the following equations:

    .. math::

       h_O &= s_Y (h - 1) + k_H - 2p_H,\\\\
       w_O &= s_X (w - 1) + k_W - 2p_W.

    """
    func = Deconvolution2DFunction(stride, pad, outsize, use_cudnn)
    if b is None:
        return func(x, W)
    else:
        return func(x, W, b)


text:
namespace apps {
struct BrowserAppInstance;
class BrowserAppInstanceRegistry;
}  // namespace apps

namespace ash {
class ShelfModel;
struct ShelfItem;
}  // namespace ash

namespace aura {
class Window;
}

class ShelfSpinnerController;
class ChromeShelfItemFactory;

// Updates the shelf model in response to |BrowserAppInstanceRegistry| events.
//
// Observes the |BrowserAppInstanceRegistry| for lifecycle events of
// - browser-based apps in tabs and windows (web apps, system web apps) in Ash
//   and Lacros,
// - browser windows in Ash and Lacros.
//
// Updates to the shelf model:
// - sets shelf item status when an app is running or stopped,
// - creates or removes shelf items when necessary.
class BrowserAppShelfController : public apps::BrowserAppInstanceObserver,
                                  public ash::ShelfModelObserver {
 public:
  BrowserAppShelfController(
      Profile* profile,
      apps::BrowserAppInstanceRegistry& browser_app_instance_registry,
      ash::ShelfModel& model,
      ChromeShelfItemFactory& shelf_item_factory,
      ShelfSpinnerController& shelf_spinner_controller);

  BrowserAppShelfController(const BrowserAppShelfController&) = delete;
  BrowserAppShelfController& operator=(const BrowserAppShelfController&) =
      delete;

  ~BrowserAppShelfController() override;

  // apps::BrowserAppInstanceObserver overrides:
  void OnBrowserWindowAdded(
      const apps::BrowserWindowInstance& instance) override;
  void OnBrowserWindowRemoved(
      const apps::BrowserWindowInstance& instance) override;
  void OnBrowserAppAdded(const apps::BrowserAppInstance& instance) override;
  void OnBrowserAppUpdated(const apps::BrowserAppInstance& instance) override;
  void OnBrowserAppRemoved(const apps::BrowserAppInstance& instance) override;

  // ash::ShelfModelObserver overrides:
  void ShelfItemAdded(int index) override;

 private:
  // Creates a shelf item if it doesn't exist and sets its status.
  void CreateOrUpdateShelfItem(const ash::ShelfID& id,
                               ash::ShelfItemStatus status);
  // Sets shelf item status to closed and removes it if it's not pinned.
  void SetShelfItemClosed(const ash::ShelfID& id);
  void UpdateShelfItemStatus(const ash::ShelfItem& item,
                             ash::ShelfItemStatus status);
  // Updates Aura window's app-related keys when the active app associated with
  // this window changes.
  void MaybeUpdateWindowProperties(aura::Window* window);
  // Updates app-related properties of all the windows containing this app.
  void MaybeUpdateWindowPropertiesForApp(const std::string& app_id);

  Profile* profile_;
  ash::ShelfModel& model_;
  ChromeShelfItemFactory& shelf_item_factory_;
  ShelfSpinnerController& shelf_spinner_controller_;

  apps::BrowserAppInstanceRegistry& browser_app_instance_registry_;

  base::ScopedObservation<apps::BrowserAppInstanceRegistry,
                          apps::BrowserAppInstanceObserver>
      registry_observation_{this};
  base::ScopedObservation<ash::ShelfModel, ash::ShelfModelObserver>
      shelf_model_observation_{this};
};

#endif  // CHROME_BROWSER_UI_ASH_SHELF_BROWSER_APP_SHELF_CONTROLLER_H_


text:
package com.chikara.strategist.entity;

import org.springframework.security.core.GrantedAuthority;

public enum Role implements GrantedAuthority
{
    USER("ROLE_USER"),
    ADMIN("ROLE_ADMIN"),
    FACULTY("ROLE_FACULTY");

    private String authority;

    Role(String authority)
    {
        this.authority = authority;
    }

    @Override
    public String getAuthority()
    {
        return this.authority;
    }
}


text:
package com.simplaapliko.trips.domain.interactor;

import com.simplaapliko.trips.domain.model.Place;
import com.simplaapliko.trips.domain.repository.PlaceRepository;

import javax.inject.Inject;

import rx.Observable;

public class ReadPlaceInteractor extends Interactor<Place, Long> {

    private long mPlaceId;
    private long mTripId;
    private PlaceRepository mPlaceRepository;

    @Inject
    public ReadPlaceInteractor(long tripId, long placeId, PlaceRepository placeRepository) {
        mTripId = tripId;
        mPlaceId = placeId;
        mPlaceRepository = placeRepository;
    }

    @Override
    protected Observable<Place> buildObservable(Long placeId) {
        Observable<Place> observable;
        if (mPlaceId == Place.NEW_ID) {
            observable = Observable.just(new Place.Builder()
                    .setTripId(mTripId)
                    .build());
        } else {
            observable = mPlaceRepository.selectById(mPlaceId);
        }
        return observable;
    }
}


text:
using System;
using System.ComponentModel;

namespace Azure.ResourceManager.Relay.Models
{
    /// <summary> This determines if traffic is allowed over public network. By default it is enabled. </summary>
    public readonly partial struct RelayPublicNetworkAccess : IEquatable<RelayPublicNetworkAccess>
    {
        private readonly string _value;

        /// <summary> Initializes a new instance of <see cref="RelayPublicNetworkAccess"/>. </summary>
        /// <exception cref="ArgumentNullException"> <paramref name="value"/> is null. </exception>
        public RelayPublicNetworkAccess(string value)
        {
            _value = value ?? throw new ArgumentNullException(nameof(value));
        }

        private const string EnabledValue = "Enabled";
        private const string DisabledValue = "Disabled";
        private const string SecuredByPerimeterValue = "SecuredByPerimeter";

        /// <summary> Enabled. </summary>
        public static RelayPublicNetworkAccess Enabled { get; } = new RelayPublicNetworkAccess(EnabledValue);
        /// <summary> Disabled. </summary>
        public static RelayPublicNetworkAccess Disabled { get; } = new RelayPublicNetworkAccess(DisabledValue);
        /// <summary> SecuredByPerimeter. </summary>
        public static RelayPublicNetworkAccess SecuredByPerimeter { get; } = new RelayPublicNetworkAccess(SecuredByPerimeterValue);
        /// <summary> Determines if two <see cref="RelayPublicNetworkAccess"/> values are the same. </summary>
        public static bool operator ==(RelayPublicNetworkAccess left, RelayPublicNetworkAccess right) => left.Equals(right);
        /// <summary> Determines if two <see cref="RelayPublicNetworkAccess"/> values are not the same. </summary>
        public static bool operator !=(RelayPublicNetworkAccess left, RelayPublicNetworkAccess right) => !left.Equals(right);
        /// <summary> Converts a string to a <see cref="RelayPublicNetworkAccess"/>. </summary>
        public static implicit operator RelayPublicNetworkAccess(string value) => new RelayPublicNetworkAccess(value);

        /// <inheritdoc />
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override bool Equals(object obj) => obj is RelayPublicNetworkAccess other && Equals(other);
        /// <inheritdoc />
        public bool Equals(RelayPublicNetworkAccess other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase);

        /// <inheritdoc />
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override int GetHashCode() => _value?.GetHashCode() ?? 0;
        /// <inheritdoc />
        public override string ToString() => _value;
    }
}


text:
/******************************************************************************
 *
 * Author(s): Amar Lior
 *
 *****************************************************************************/

#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>

#include <msx_debug.h>
#include <msx_error.h>
#include <parse_helper.h>
#include <Mapper.h>
#include <MapperInternal.h>
#include <MapperBuilder.h>

static int getAllDirFiles(const char *dirName, char ***fileList, int *fileNum);
static int buildFromText(mapper_t map, char **fileList, int fileNum);
static int addTextPartner(mapper_t map, char *fileName);
static int buildFromBin(mapper_t map, char **fileList, int fileNum);
static int addBinPartner(mapper_t map, char *fileName);

mapper_t BuildPartnersMap(const char *partnerDir, partner_map_t type) {

	mapper_t   map = NULL;
	int        fileNum = 0, res;
	char     **fileList = NULL;

	map = mapperInit(0);
	if(!map)
		return map;

	// Get all files from the directory
	if(!getAllDirFiles(partnerDir, &fileList, &fileNum))
		goto failed;

	if(fileNum == 0 )
                goto failed;

	switch(type) {
	    case PARTNER_SRC_TEXT:
		    res = buildFromText(map, fileList, fileNum);
		    break;
	    case PARTNER_SRC_BIN:
		    res = buildFromBin(map, fileList, fileNum);
		    break;
	    default:
		    debug_lr(MAP_DEBUG, "Error type %d no supported\n", type);
		    goto failed;
	}
	if(!res)
		goto failed;

	if(!isMapValid(map))
		goto failed;

	// Build is compleate so we finalize it
	mapperFinalizeBuild(map);
        for(int i=0 ; i<fileNum ; i++)
                if(fileList[i])
                        free(fileList[i]);
        free(fileList);
	return map;

 failed:
	mapperDone(map);
	if(fileList) {
                for(int i=0 ; i<fileNum ; i++)
                        if(fileList[i])
                                free(fileList[i]);
		free(fileList);
        }
	return NULL;
}

int getAllDirFiles(const char *dirName, char ***fileList, int *fileNum) {
	DIR            *dir;
	struct dirent  *dirEnt;
	int             i;
	char          **list;
	char            tmpBuff[256];
	struct stat     statBuff;

	if(!dirName)
		return 0;
	dir = opendir(dirName);
	if(!dir) {
		debug_lr(MAP_DEBUG, "Error while opening directory %s\n", dirName);
		return 0;
	}

	list = (char **)malloc(sizeof(char *) * MAPPER_MAX_CLUSTERS);
        bzero(list, sizeof(char *) * MAPPER_MAX_CLUSTERS);

	i=0;
	while((dirEnt = readdir(dir))) {
		if( (strcmp(dirEnt->d_name, ".") == 0) ||
		    (strcmp(dirEnt->d_name, "..") == 0))
			continue;
		// Checking if the file is a directory
		sprintf(tmpBuff, "%s/%s", dirName, dirEnt->d_name);
		if(stat(tmpBuff, &statBuff) == -1) {
			debug_lr(MAP_DEBUG, "Error stating file %s\n", tmpBuff);
			continue;
		}
		if(!S_ISREG(statBuff.st_mode))
			continue;

		list[i++] = strdup(tmpBuff);
		if(i == MAPPER_MAX_CLUSTERS) {
			debug_lr(MAP_DEBUG, "Reached max cluster limit in building partner map\n");
			break;
		}
	}

	closedir(dir);
	*fileList = list;
	*fileNum = i;
        debug_lr(MAP_DEBUG, "Got %d files from dir\n", i);
	return 1;
}

char *getClusterName(char *fileName) {
	char *clusterName;

	clusterName = strrchr(fileName, '/');
	if(clusterName) {
		clusterName++;
	} else {
		clusterName = fileName;
	}
	return clusterName;
}

int buildFromText(mapper_t map, char **fileList, int fileNum) {
	int i;

	for(i=0 ; i<fileNum ; i++) {
		debug_lg(MAP_DEBUG, "Processing file: %s\n", fileList[i]);
		addTextPartner(map, fileList[i]);

	}
	return 1;
}

int addTextPartner(mapper_t map, char *fileName) {

	int              res = 0;
	int              size;
	int              linenum=0;
	char            *buffCurrPos = NULL;
	char            *buff = NULL;

	char            *clusterName = NULL;
	cluster_entry_t *cEnt = NULL;
	mapper_cluster_info_t ci;
	mapper_range_info_t   ri;
	int              lineBuffSize = 200;
	char             lineBuff[200];

	char             host_name[255];

	cluster_info_init(&ci);

	buff = getMapSourceBuff(fileName, 0, INPUT_FILE, &size);
	if(!buff) {
		debug_lr(MAP_DEBUG, "Error reading file\n");
		goto out;
	}
	buffCurrPos = (char*) buff;
	if(!buffCurrPos)
		goto out;

	// Reading the cluster commet/description
	if(lineBuffSize > size)
		lineBuffSize = size;
	buffCurrPos = buff_get_line(lineBuff, lineBuffSize, buffCurrPos);
	if(!buffCurrPos) {
		debug_lr(MAP_DEBUG, "First line is not ok\n");
		goto out;
	}

	linenum++;
	debug_lg(MAP_DEBUG, "Processing line: %s\n", lineBuff);

	ci.ci_desc = strdup(lineBuff);

	// Reading the cluster prio, dont-take dontgo...
	buffCurrPos = buff_get_line(lineBuff, lineBuffSize, buffCurrPos);
	if(!buffCurrPos) {
		debug_lr(MAP_DEBUG, "Second line is ok\n");
		goto out;
	}

	linenum++;
	debug_lg(MAP_DEBUG, "Processing line: %s\n", lineBuff);

	int cango, cantake, canexpend;
	if(sscanf(lineBuff, "%d %d %d %d",
		  &ci.ci_prio, &cango, &cantake, &canexpend) != 4)

	{
		debug_lr(MAP_DEBUG, "Second line is not in correct format\n");
		goto out;
	}
	ci.ci_cango     = (char)cango;
	ci.ci_cantake   = (char)cantake;
	ci.ci_canexpend = (char)canexpend;

	clusterName = getClusterName(fileName);

	if(!mapper_addCluster(map, -1, clusterName, &ci)) {
		debug_lr(MAP_DEBUG, "Failed to add cluster %s\n", clusterName);
		goto out;
	}
	free(ci.ci_desc);
	ci.ci_desc = NULL;

	// Checking that the cluster is not already there
	cEnt = get_cluster_entry_by_name(map, clusterName);
	if(!cEnt) {
		debug_lr(MAP_DEBUG, "Just added cluster is not there\n");
		goto out;
	}

	// Reading the ranges
	int base = 1;
	while( buffCurrPos && !(*buffCurrPos == '\0') )
	{
		linenum++;
		buffCurrPos = buff_get_line(lineBuff, lineBuffSize, buffCurrPos);
		debug_lg(MAP_DEBUG, "Processing line: %s\n", lineBuff);

		// Skeeing comments in map
		if(lineBuff[0] == '#')
		{
			debug_lg(MAP_DEBUG, "\t\tcomment\n");
			continue;
		}
		// Skeeping empty lines
		if(strlen(lineBuff) == 0)
			continue;

		int count, core, participate, proximate;
		if (sscanf(lineBuff, "%s %d %d %d %d",
			   host_name, &count, &core, &participate, &proximate) == 5) {
			debug_lb(MAP_DEBUG, "Found partner range entry %s %d\n",
				 host_name, count);

			ri.ri_core        = (char) core;
			ri.ri_participate = (char) participate;
			ri.ri_proximate   = (char) proximate;

			// If the range is valid adding it to the cluster (the
			// single cluster we have)
			// Doing the initialization part only in the first time
			// the map become old

			if(mapper_addClusterHostRange(map, cEnt, base, host_name, count, &ri))
			{
				base += count;
			}
			else {
				goto out;
			}
		}
		else {
			lineBuff[strlen(lineBuff)] = '\0';
			debug_lr(MAP_DEBUG, "Found bad line %s\n", lineBuff);
			sprintf(map->errorMsg, "Bad line <%s>\n", lineBuff);
			goto out;
		}
	}

	res = 1;

 out:
        if(buff)
		free(buff);
	cluster_info_free(&ci);
	return res;
}

int buildFromBin(mapper_t map, char **fileList, int fileNum)
{
	int i;

	for(i=0 ; i<fileNum ; i++) {
		debug_lg(MAP_DEBUG, "Processing file: %s\n", fileList[i]);
		addBinPartner(map, fileList[i]);

	}
	return 1;
}

struct bin_partner {
        unsigned int    ip;        /* first IP in range */
        int             n;         /* number of IP's in range, or 0=alias */
        char            dontgo;
        char            donttake;
        char            proximate; /* no need for compression */
        char            outsider;  /* processes without -G{n} cannot go there */
        unsigned short  priority;  /* lower=better */
        unsigned short  its_me;    /* 0 in our case! */
        unsigned int    alias_to;  /* IP address.  0 for a regular range */
};

int addBinPartner(mapper_t map, char *fileName) {
	int                 res = 0;
	int                 size, i;
	char               *buff;
	struct bin_partner *partnerArr;
	int                 rangeNum;
	char               *clusterName = NULL;

	cluster_entry_t *cEnt;
	mapper_cluster_info_t ci;
	mapper_range_info_t   ri;

	buff = getMapSourceBuff(fileName, 0, INPUT_FILE_BIN, &size);
	if(!buff) {
		debug_lr(MAP_DEBUG, "Error reading file\n");
		goto out;
	}
	if(size == 0 || (size % sizeof(struct bin_partner)) != 0) {
		debug_lr(MAP_DEBUG, "Error number of records is not integer (%d %d)\n",
			 size, sizeof(struct bin_partner));
		goto out;
	}

	clusterName = getClusterName(fileName);
	partnerArr = (struct bin_partner *) buff;
	rangeNum = size / sizeof(struct bin_partner);

	// Adding the cluster using the first range
	ci.ci_prio      =  partnerArr[0].priority;
	ci.ci_cango     =  !partnerArr[0].dontgo;
	ci.ci_cantake   =  !partnerArr[0].donttake;
	ci.ci_canexpend = 0;
	ci.ci_desc      = NULL;

	clusterName = getClusterName(fileName);

	if(!mapper_addCluster(map, -1, clusterName, &ci)) {
		debug_lr(MAP_DEBUG, "Failed to add cluster %s\n", clusterName);
		goto out;
	}
	// Checking that the cluster is not already there
	cEnt = get_cluster_entry_by_name(map, clusterName);
	if(!cEnt) {
		debug_lr(MAP_DEBUG, "Just added cluster is not there\n");
		goto out;
	}

	// Adding all the ranges
	int base = 1;
	for(i = 0 ; i < rangeNum ; i++) {
		ri.ri_core        =  0;
		ri.ri_participate =  1;
		ri.ri_proximate   =  partnerArr[i].proximate;

		struct in_addr addr;
		addr.s_addr = htonl(partnerArr[i].ip);

		//printf("Got range %s %d\n", inet_ntoa(addr), partnerArr[i].n);
		// If the range is valid adding it to the cluster (the single cluster we have)
		if(mapper_addClusterAddrRange(map, cEnt, base, &addr, partnerArr[i].n, &ri))
		{
			base += partnerArr[i].n;
		}
		else {
			goto out;
		}
	}

	res = 1;
 out:
	if(buff)
		free(buff);
	return res;
}

/// Writer Part /////

int generateTextPartner(mapper_t map, const char *clusterName,
                        char *buff, int *size)
{
	int                    res = 0;
	mapper_cluster_info_t  ci;
	mapper_range_iter_t    rIter;
	char                  *currPtr = buff;
	int                    currSize = 0, sz;

	cluster_info_init(&ci);
	if(!mapper_getClusterInfo(map, clusterName, &ci)) {
		debug_lr(MAP_DEBUG, "Very strange cluster %s has no info\n",
			 clusterName);
		goto out;
	}
	sz = sprintf(currPtr, "%s\n", ci.ci_desc);
	currSize += sz; currPtr  += sz;

	sz = sprintf(currPtr, "%d  %hhd %hhd %hhd\n",
		     ci.ci_prio, ci.ci_cango, ci.ci_cantake, ci.ci_canexpend);
	currSize += sz; currPtr  += sz;
	// Print the cluster ranges
	rIter = mapperRangeIter(map, clusterName);
	if(!rIter)
		goto out;

	mapper_range_t       mr;
	mapper_range_info_t  ri;
	while(mapperRangeIterNext(rIter, &mr, &ri)) {
		struct hostent  *hostent;
		char            *hostname;

		if ((hostent = gethostbyaddr(&mr.baseIp, sizeof(struct in_addr), AF_INET)))
			hostname = hostent->h_name;
		else
			hostname = inet_ntoa(mr.baseIp);

		sz = sprintf(currPtr,"%s %d %hhd %hhd %hhd\n",
			     hostname, mr.count,
			     ri.ri_core, ri.ri_participate, ri.ri_proximate);
		currSize += sz; currPtr  += sz;
		if(currSize > *size) {
			debug_lr(MAP_DEBUG, "Not enough memory in buffer to hold a single partner file???\n");
			goto out;
		}

	}

        *size = currSize;
	res = 1;
 out:

	mapperRangeIterDone(rIter);
	cluster_info_free(&ci);
	return res;
}

int generateBinPartner(mapper_t map, const char *clusterName,
			      char *buff, int *size)
{
	int                    res = 0;
	mapper_cluster_info_t  ci;
	mapper_range_iter_t    rIter;
	int                    currSize = 0;
	struct bin_partner    *binPartner;
	int                    rangeNum;

        binPartner = (struct bin_partner *) buff;

	cluster_info_init(&ci);
	if(!mapper_getClusterInfo(map, clusterName, &ci)) {
		debug_lr(MAP_DEBUG, "Very strange cluster %s has no info\n",
			 clusterName);
		goto out;
	}

	// Print the cluster ranges
	rIter = mapperRangeIter(map, clusterName);
	if(!rIter)
		goto out;

	rangeNum = 0;
	mapper_range_t       mr;
	mapper_range_info_t  ri;
	while(mapperRangeIterNext(rIter, &mr, &ri)) {

                bzero(&binPartner[rangeNum], sizeof(struct bin_partner));
                binPartner[rangeNum].ip        =  ntohl(mr.baseIp.s_addr);
		binPartner[rangeNum].n         =  mr.count;
                binPartner[rangeNum].proximate =  ri.ri_proximate;
                binPartner[rangeNum].dontgo    = !ci.ci_cango;
                binPartner[rangeNum].donttake  = !ci.ci_cantake;
                binPartner[rangeNum].outsider  = 1;
                binPartner[rangeNum].priority  = ci.ci_prio;

                currSize += sizeof(struct bin_partner);
		if(currSize > *size) {
			debug_lr(MAP_DEBUG, "Buffer too small to hold a single partner file!!\n");
			goto out;
		}
	}

        *size = currSize;
	res = 1;
 out:

	mapperRangeIterDone(rIter);
	cluster_info_free(&ci);
	return res;
}

int _writePartnerMap(mapper_t map, const char *dirName, partner_map_t type) {

	int                    res = 0;
	mapper_cluster_iter_t  cIter = NULL;
	char                  *clusterName;
	char                  *tmpBuff = NULL;
	int                    tmpBuffSize = 4096;
	int                    size = 0;
	int                    fd = -1;
	char                   fileName[MAPPER_MAX_CLUSTER_NAME];

	tmpBuff = malloc(tmpBuffSize);
	if(!tmpBuff)
		goto out;

	cIter = mapperClusterIter(map);
	if(!cIter)
		goto out;

	while(mapperClusterIterNext(cIter, &clusterName)) {
		// Print the cluster details
		size = tmpBuffSize;
                switch (type) {
                    case PARTNER_SRC_TEXT:
                            generateTextPartner(map, clusterName, tmpBuff, &size);
                            break;
                    case PARTNER_SRC_BIN:
                            generateBinPartner(map, clusterName, tmpBuff, &size);
                            break;
                    default:
                            goto out;
                }
		sprintf(fileName, "%s/%s", dirName, clusterName);

		fd = open(fileName, O_WRONLY | O_CREAT | O_TRUNC, 0644);
		if(fd == -1) {
			debug_lr(MAP_DEBUG, "Error opening partner file\n");
			goto out;
		}
		if(write(fd, tmpBuff, size) != size) {
			debug_lr(MAP_DEBUG, "Error writing partner to file\n");
			goto out;
		}
		close(fd);
		fd = -1;
	}
	mapperClusterIterDone(cIter);
        cIter = NULL;
	res = 1;

 out:
	if(tmpBuff)
		free(tmpBuff);
	if(fd >= 0 )
		close(fd);
        if(cIter)
                mapperClusterIterDone(cIter);

	return res;
}

int WritePartnerMap(mapper_t map, const char *partnerDir)
{
        return _writePartnerMap(map, partnerDir, PARTNER_SRC_TEXT);
}
int WriteBinPartnerMap(mapper_t map, const char *partnerDir) {
        return _writePartnerMap(map, partnerDir, PARTNER_SRC_BIN);
}


text:
"""Generates .rst files for .py files encountered in the SRC_DIR

:author: Eric Vasquez
:contact: eric.vasquez@calxeda.com
:copyright: (c) 2012-2013, Calxeda Inc.

"""

import os
import sys
import glob

# #
# The actual NAME of your API, as if you were to import it.
API_NAME = 'cxmanage_api'

# #
# SRC_DIR is one directory level up from the docs dir
# assuming a file structure like:
# +--API/
#       |---src_file1.py
#       |---src_fileN.py
#       +---docs/
#               |--Makefile
#               +--generate_api_rst.py
SRC_DIR = os.path.dirname(os.path.abspath('.'))
RST_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'source')

# #
# Any files you don't want docs generated for (no extension needed)
#
# EXAMPLE: To exclude foo.py and bar.py ...
# BLACK_LIST = ['foo', 'bar']
#
BLACKLIST = ['__init__']

# #
# Add any custom title you want for a specific python source file.
#
# EXAMPLE:
# TITLES = {'some_obscure_script_name' : 'Some Less Obscure Title'}
#
TITLES = {
          'simg' : 'SIMG',
          'crc32' : 'CRC32',
          'ubootenv' : 'U-Boot Environment',
         }

def get_source(source_dir):
    """Iterates recursively over dirs and gets all of the <filename>.py files.

    :param source_dir: The (absolute) path to the source directory.
    :type source_dir: string

    :return: A mapping of file names to filename Titles.
    :rtype: dictionary
    """
    if (not source_dir.endswith('/')):
        source_dir += '/'

    source = {API_NAME : {}}
    paths = glob.glob(os.path.join(source_dir, '*.py'))
    for path in paths:
        f_path, _ = os.path.splitext(path)
        f_name = f_path.split(source_dir)[1]
        if (not f_name in BLACKLIST):
            if TITLES.has_key(f_name):
                source[API_NAME][f_name] = TITLES[f_name]
            else:
                source[API_NAME][f_name] = f_name.title()
        else:
            print 'Skipping docgen for source file: %s' % path

    return source

def parse_source(src_file):
    """Parses a given source file to get class and function names.

    :param src_file: A file path. (abspath)
    :type src_file: string
    :return: a dictionary mapping class to methods and a list of functions
    :rtype: dictionary

    """
    def _get_object_name(line):
        """Takes a class, function or method declaration and gets the name."""
        name = line.split()[1].split('(')[0].strip()
        return name.rstrip(':')

    #
    # Parse Source
    #
    classes, functions = {}, []
    with open(src_file, 'r') as file_:
        class_ = None
        lines = file_.readlines()

        for line in lines:
            if (line.startswith('class ')):
                name = _get_object_name(line)
                class_ = name
                classes[name] = []
            elif (line.startswith('    def ') and line.count('(')):
                if (class_):
                    name = _get_object_name(line)
                    if (not name.startswith('_')):
                        classes[class_].append(name)
            elif (line.startswith('def ') and line.count('(')):
                functions.append(_get_object_name(line))

    for class_name, function_names in classes.items():
        classes[class_name] = sorted(list(set(function_names)))

    return classes, sorted(list(set(functions)))

def main():
    """Entry point for this script."""
    src_files = get_source(SRC_DIR)
    for package, module in src_files.items():
        for module_name, module_title in module.items():
            doc = os.path.join(RST_DIR, '%s.rst' % module_name)
            with open('%s' % doc, 'w') as rst_file:
                print 'Generating Sphinx Docs for: %s' % doc
                py_src = os.path.join(SRC_DIR, '%s.py' % module_name)
                classes, functions = parse_source(py_src)
                rst_file.write(module_title + '\n')
                rst_file.write('_' * len(module_title) + '\n\n')

                if (len(functions) > 0):
                    rst_file.write('.. currentmodule:: %s.%s\n\n' %
                                   (package, module_name))
                    rst_file.write('.. autosummary::\n')
                    rst_file.write('    :nosignatures:\n\n')
                    for func in functions:
                        rst_file.write('    %s\n' % func)
                    rst_file.write('\n')

                if (classes != {}):
                    rst_file.write('.. currentmodule:: %s.%s\n\n' %
                                   (package, module_name))
                    rst_file.write('.. autosummary::\n')
                    rst_file.write('    :nosignatures:\n\n')
                    for class_name in classes.keys():
                        rst_file.write('    %s\n' % class_name)
                    rst_file.write('\n')
                    for class_name, function_list in classes.items():
                        if (len(function_list) > 0):
                            rst_file.write('    .. automethod::\n')
                            for function_name in function_list:
                                rst_file.write('        %s.%s\n' %
                                               (class_name, function_name))
                        rst_file.write('\n\n')

                for func in functions:
                    rst_file.write('.. autofunction:: %s\n' % func)

                for class_name in classes.keys():
                    rst_file.write('.. autoclass:: %s\n' % class_name)
                    rst_file.write('    :members:\n')
                    if (module_name not in BLACKLIST):
                        rst_file.write('    :inherited-members:\n')
                    rst_file.write('    :show-inheritance:\n')
                    rst_file.write('\n')

# Go!
if __name__ == '__main__':
    sys.exit(main())

# End of file: ./docs/generate_api_rst.py