text:
/// WARNING: Users of TensorFlow Lite should not include this file directly,
/// but should instead include
/// "third_party/tensorflow/lite/c/c_api_experimental.h".
/// Only the TensorFlow Lite implementation itself should include this
/// file directly.
#ifndef TENSORFLOW_LITE_CORE_C_C_API_EXPERIMENTAL_H_
#define TENSORFLOW_LITE_CORE_C_C_API_EXPERIMENTAL_H_

#include "tensorflow/lite/builtin_ops.h"
#include "tensorflow/lite/core/c/c_api.h"
#include "tensorflow/lite/core/c/common.h"

#ifdef __cplusplus
extern "C" {
#endif  // __cplusplus

// --------------------------------------------------------------------------
// Opaque types used by the C API.

/// TfLiteSignatureRunner is used to run inference on a signature.
///
/// Note: A signature is used to define a computation in a TF model. A model can
/// have multiple signatures. Each signature contains three components:
///   * Signature Key: A unique string to identify a signature
///   * Inputs: A list of names, each mapped to an input tensor of a signature
///   * Outputs: A list of names, each mapped to an output tensor of a signature
///
/// To learn more about signatures in TFLite, refer to:
/// https://www.tensorflow.org/lite/guide/signatures
///
/// Using the TfLiteSignatureRunner, for a particular signature, you can set its
/// inputs, invoke (i.e. execute) the computation, and retrieve its outputs.
typedef struct TfLiteSignatureRunner TfLiteSignatureRunner;

// --------------------------------------------------------------------------
/// Resets all variable tensors to zero.
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT extern TfLiteStatus TfLiteInterpreterResetVariableTensors(
    TfLiteInterpreter* interpreter);

/// Adds an op registration for a builtin operator.
///
/// Op registrations are used to map ops referenced in the flatbuffer model
/// to executable function pointers (`TfLiteRegistration`s).
///
/// NOTE: The interpreter will make a shallow copy of `registration` internally,
/// so the caller should ensure that its contents (function pointers, etc...)
/// remain valid for the duration of the interpreter's lifetime. A common
/// practice is making the provided `TfLiteRegistration` instance static.
///
/// Code that uses this function should NOT call
/// `TfLiteInterpreterOptionsSetOpResolver` on the same options object.
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT void TfLiteInterpreterOptionsAddBuiltinOp(
    TfLiteInterpreterOptions* options, TfLiteBuiltinOperator op,
    const TfLiteRegistration* registration, int32_t min_version,
    int32_t max_version);

/// Adds an op registration for a custom operator.
///
/// Op registrations are used to map ops referenced in the flatbuffer model
/// to executable function pointers (`TfLiteRegistration`s).
///
/// NOTE: The interpreter will make a shallow copy of `registration` internally,
/// so the caller should ensure that its contents (function pointers, etc...)
/// remain valid for the duration of any created interpreter's lifetime. A
/// common practice is making the provided `TfLiteRegistration` instance static.
///
/// The lifetime of the string pointed to by `name` must be at least as long
/// as the lifetime of the `TfLiteInterpreterOptions`.
///
/// Code that uses this function should NOT call
/// `TfLiteInterpreterOptionsSetOpResolver` on the same options object.
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT void TfLiteInterpreterOptionsAddCustomOp(
    TfLiteInterpreterOptions* options, const char* name,
    const TfLiteRegistration* registration, int32_t min_version,
    int32_t max_version);

/// Registers callbacks for resolving builtin or custom operators.
///
/// The `TfLiteInterpreterOptionsSetOpResolver` function provides an alternative
/// method for registering builtin ops and/or custom ops, by providing operator
/// resolver callbacks.  Unlike using `TfLiteInterpreterOptionsAddBuiltinOp`
/// and/or `TfLiteInterpreterOptionsAddAddCustomOp`, these let you register all
/// the operators in a single call.
///
/// Code that uses this function should NOT call
/// `TfLiteInterpreterOptionsAddBuiltin` or
/// `TfLiteInterpreterOptionsAddCustomOp` on the same options object.
///
/// If `op_resolver_user_data` is non-null, its lifetime must be at least as
/// long as the lifetime of the `TfLiteInterpreterOptions`.
///
/// WARNING: This is an experimental API and subject to change.
void TfLiteInterpreterOptionsSetOpResolver(
    TfLiteInterpreterOptions* options,
    const TfLiteRegistration* (*find_builtin_op)(void* user_data,
                                                 TfLiteBuiltinOperator op,
                                                 int version),
    const TfLiteRegistration* (*find_custom_op)(void* user_data,
                                                const char* custom_op,
                                                int version),
    void* op_resolver_user_data);

/// \private
/// `TfLiteRegistration_V1` version of TfLiteInterpreterOptionsSetOpResolver.
///
/// WARNING: This function is deprecated / not an official part of the API, is
/// only for binary backwards compatibility, and should not be called.
void TfLiteInterpreterOptionsSetOpResolverV1(
    TfLiteInterpreterOptions* options,
    const TfLiteRegistration_V1* (*find_builtin_op_v1)(void* user_data,
                                                       TfLiteBuiltinOperator op,
                                                       int version),
    const TfLiteRegistration_V1* (*find_custom_op_v1)(void* user_data,
                                                      const char* op,
                                                      int version),
    void* op_resolver_user_data);

/// Returns a new interpreter using the provided model and options, or null on
/// failure, where the model uses only the operators explicitly added to the
/// options.  This is the same as `TFLiteInterpreterCreate` from `c_api.h`,
/// except that the only operators that are supported are the ones registered
/// in `options` via calls to `TfLiteInterpreterOptionsSetOpResolver`,
/// `TfLiteInterpreterOptionsAddBuiltinOp`, and/or
/// `TfLiteInterpreterOptionsAddCustomOp`.
///
/// * `model` must be a valid model instance. The caller retains ownership of
///   the object, and can destroy it immediately after creating the interpreter;
///   the interpreter will maintain its own reference to the underlying model
///   data.
/// * `options` should not be null. The caller retains ownership of the object,
///   and can safely destroy it immediately after creating the interpreter.
///
/// NOTE: The client *must* explicitly allocate tensors before attempting to
/// access input tensor data or invoke the interpreter.
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT extern TfLiteInterpreter*
TfLiteInterpreterCreateWithSelectedOps(const TfLiteModel* model,
                                       const TfLiteInterpreterOptions* options);

/// Enable or disable the NN API delegate for the interpreter (true to enable).
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT extern void TfLiteInterpreterOptionsSetUseNNAPI(
    TfLiteInterpreterOptions* options, bool enable);

/// Enable or disable CPU fallback for the interpreter (true to enable).
/// If enabled, TfLiteInterpreterInvoke will do automatic fallback from
/// executing with delegate(s) to regular execution without delegates
/// (i.e. on CPU).
///
/// Allowing the fallback is suitable only if both of the following hold:
/// - The caller is known not to cache pointers to tensor data across
///   TfLiteInterpreterInvoke calls.
/// - The model is not stateful (no variables, no LSTMs) or the state isn't
///   needed between batches.
///
/// When delegate fallback is enabled, TfLiteInterpreterInvoke will
/// behave as follows:
///   If one or more delegates were set in the interpreter options
///   (see TfLiteInterpreterOptionsAddDelegate),
///   AND inference fails,
///   then the interpreter will fall back to not using any delegates.
///   In that case, the previously applied delegate(s) will be automatically
///   undone, and an attempt will be made to return the interpreter to an
///   invokable state, which may invalidate previous tensor addresses,
///   and the inference will be attempted again, using input tensors with
///   the same value as previously set.
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT extern void TfLiteInterpreterOptionsSetEnableDelegateFallback(
    TfLiteInterpreterOptions* options, bool enable);

// Set if buffer handle output is allowed.
//
/// When using hardware delegation, Interpreter will make the data of output
/// tensors available in `tensor->data` by default. If the application can
/// consume the buffer handle directly (e.g. reading output from OpenGL
/// texture), it can set this flag to false, so Interpreter won't copy the
/// data from buffer handle to CPU memory. WARNING: This is an experimental
/// API and subject to change.
TFL_CAPI_EXPORT extern void TfLiteSetAllowBufferHandleOutput(
    const TfLiteInterpreter* interpreter, bool allow_buffer_handle_output);

/// Allow a delegate to look at the graph and modify the graph to handle
/// parts of the graph themselves. After this is called, the graph may
/// contain new nodes that replace 1 more nodes.
/// 'delegate' must outlive the interpreter.
/// Use `TfLiteInterpreterOptionsAddDelegate` instead of this unless
/// absolutely required.
/// Returns one of the following three status codes:
/// 1. kTfLiteOk: Success.
/// 2. kTfLiteDelegateError: Delegation failed due to an error in the
/// delegate. The Interpreter has been restored to its pre-delegation state.
/// NOTE: This undoes all delegates previously applied to the Interpreter.
/// 3. kTfLiteError: Unexpected/runtime failure.
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT extern TfLiteStatus TfLiteInterpreterModifyGraphWithDelegate(
    const TfLiteInterpreter* interpreter, TfLiteDelegate* delegate);

/// Returns the tensor index corresponding to the input tensor
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT extern int32_t TfLiteInterpreterGetInputTensorIndex(
    const TfLiteInterpreter* interpreter, int32_t input_index);

/// Returns the tensor index corresponding to the output tensor
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT extern int32_t TfLiteInterpreterGetOutputTensorIndex(
    const TfLiteInterpreter* interpreter, int32_t output_index);

/// --------------------------------------------------------------------------
/// SignatureRunner APIs
///
/// You can run inference by either:
///
/// (i) (recommended) using the Interpreter to initialize SignatureRunner(s) and
///     then only using SignatureRunner APIs.
///
/// (ii) only using Interpreter APIs.
///
/// NOTE:
/// * Only use one of the above options to run inference, i.e. avoid mixing both
///   SignatureRunner APIs and Interpreter APIs to run inference as they share
///   the same underlying data (e.g. updating an input tensor "A" retrieved
///   using the Interpreter APIs will update the state of the input tensor "B"
///   retrieved using SignatureRunner APIs, if they point to the same underlying
///   tensor in the model; as it is not possible for a user to debug this by
///   analyzing the code, it can lead to undesirable behavior).
/// * The TfLiteSignatureRunner type is conditionally thread-safe, provided that
///   no two threads attempt to simultaneously access two TfLiteSignatureRunner
///   instances that point to the same underlying signature, or access a
///   TfLiteSignatureRunner and its underlying TfLiteInterpreter, unless all
///   such simultaneous accesses are reads (rather than writes).
/// * The lifetime of a TfLiteSignatureRunner object ends when
///   TfLiteSignatureRunnerDelete() is called on it (or when the lifetime of the
///   underlying TfLiteInterpreter ends -- but you should call
///   TfLiteSignatureRunnerDelete() before that happens in order to avoid
///   resource leaks).
/// * You can only apply delegates to the interpreter (via
///   TfLiteInterpreterOptions) and not to a signature.

/// Returns the number of signatures defined in the model.
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT extern int32_t TfLiteInterpreterGetSignatureCount(
    const TfLiteInterpreter* interpreter);

/// Returns the key of the Nth signature in the model, where N is specified as
/// `signature_index`.
///
/// NOTE: The lifetime of the returned key is the same as (and depends on) the
/// lifetime of `interpreter`.
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT extern const char* TfLiteInterpreterGetSignatureKey(
    const TfLiteInterpreter* interpreter, int32_t signature_index);

/// Returns a new signature runner using the provided interpreter and signature
/// key, or nullptr on failure.
///
/// NOTE: `signature_key` is a null-terminated C string that must match the
/// key of a signature in the interpreter's model.
///
/// NOTE: The returned signature runner should be destroyed, by calling
/// TfLiteSignatureRunnerDelete(), before the interpreter is destroyed.
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT extern TfLiteSignatureRunner*
TfLiteInterpreterGetSignatureRunner(const TfLiteInterpreter* interpreter,
                                    const char* signature_key);

/// Returns the number of inputs associated with a signature.
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT extern size_t TfLiteSignatureRunnerGetInputCount(
    const TfLiteSignatureRunner* signature_runner);

/// Returns the (null-terminated) name of the Nth input in a signature, where N
/// is specified as `input_index`.
///
/// NOTE: The lifetime of the returned name is the same as (and depends on) the
/// lifetime of `signature_runner`.
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT extern const char* TfLiteSignatureRunnerGetInputName(
    const TfLiteSignatureRunner* signature_runner, const int32_t input_index);

/// Resizes the input tensor identified as `input_name` to be the dimensions
/// specified by `input_dims` and `input_dims_size`. Only unknown dimensions can
/// be resized with this function. Unknown dimensions are indicated as `-1` in
/// the `dims_signature` attribute of a TfLiteTensor.
///
/// Returns status of failure or success. Note that this doesn't actually resize
/// any existing buffers. A call to TfLiteSignatureRunnerAllocateTensors() is
/// required to change the tensor input buffer.
///
/// NOTE: This function is similar to TfLiteInterpreterResizeInputTensorStrict()
/// and not TfLiteInterpreterResizeInputTensor().
///
/// NOTE: `input_name` must match the name of an input in the signature.
///
/// NOTE: This function makes a copy of the input dimensions, so the caller can
/// safely deallocate `input_dims` immediately after this function returns.
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT extern TfLiteStatus TfLiteSignatureRunnerResizeInputTensor(
    TfLiteSignatureRunner* signature_runner, const char* input_name,
    const int* input_dims, int32_t input_dims_size);

/// Updates allocations for tensors associated with a signature and resizes
/// dependent tensors using the specified input tensor dimensionality.
/// This is a relatively expensive operation and hence should only be called
/// after initializing the signature runner object and/or resizing any inputs.
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT extern TfLiteStatus TfLiteSignatureRunnerAllocateTensors(
    TfLiteSignatureRunner* signature_runner);

/// Returns the input tensor identified by `input_name` in the given signature.
/// Returns nullptr if the given name is not valid.
///
/// NOTE: The lifetime of the returned tensor is the same as (and depends on)
/// the lifetime of `signature_runner`.
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT extern TfLiteTensor* TfLiteSignatureRunnerGetInputTensor(
    TfLiteSignatureRunner* signature_runner, const char* input_name);

/// Runs inference on a given signature.
///
/// Before calling this function, the caller should first invoke
/// TfLiteSignatureRunnerAllocateTensors() and should also set the values for
/// the input tensors. After successfully calling this function, the values for
/// the output tensors will be set.
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT extern TfLiteStatus TfLiteSignatureRunnerInvoke(
    TfLiteSignatureRunner* signature_runner);

/// Returns the number of output tensors associated with the signature.
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT extern size_t TfLiteSignatureRunnerGetOutputCount(
    const TfLiteSignatureRunner* signature_runner);

/// Returns the (null-terminated) name of the Nth output in a signature, where
/// N is specified as `output_index`.
///
/// NOTE: The lifetime of the returned name is the same as (and depends on) the
/// lifetime of `signature_runner`.
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT extern const char* TfLiteSignatureRunnerGetOutputName(
    const TfLiteSignatureRunner* signature_runner, int32_t output_index);

/// Returns the output tensor identified by `output_name` in the given
/// signature. Returns nullptr if the given name is not valid.
///
/// NOTE: The lifetime of the returned tensor is the same as (and depends on)
/// the lifetime of `signature_runner`.
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT extern const TfLiteTensor* TfLiteSignatureRunnerGetOutputTensor(
    const TfLiteSignatureRunner* signature_runner, const char* output_name);

/// Attempts to cancel in flight invocation if any.
/// This will not affect calls to `Invoke` that happend after this.
/// Non blocking and thread safe.
/// Returns kTfLiteError if cancellation is not enabled, otherwise returns
/// kTfLiteOk.
/// NOTE: Calling this function will cancel in-flight invocations
/// in all SignatureRunners built from the same interpreter.
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT extern TfLiteStatus TfLiteSignatureRunnerCancel(
    TfLiteSignatureRunner* signature_runner);

/// Destroys the signature runner.
///
/// WARNING: This is an experimental API and subject to change.
TFL_CAPI_EXPORT extern void TfLiteSignatureRunnerDelete(
    TfLiteSignatureRunner* signature_runner);

#ifdef __cplusplus
}  // extern "C"
#endif  // __cplusplus

#endif  // TENSORFLOW_LITE_CORE_C_C_API_EXPERIMENTAL_H_


text:
package ankios.blog.controller;

import ankios.blog.model.Comment;
import ankios.blog.model.Post;
import ankios.blog.model.PostEditDto;
import ankios.blog.model.User;
import ankios.blog.service.AlreadyVotedException;
import ankios.blog.service.PostService;
import ankios.blog.service.UserService;
import ankios.blog.utils.JsonUtils;

import ankios.blog.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringEscapeUtils;

@Controller
public class PostsController {

    @Autowired
    private UserService userService;

    @Autowired
    private PostService postService;

    @RequestMapping(value = {"/", "/posts"}, method = RequestMethod.GET)
    public String showPostsList(@RequestParam(value = "page", defaultValue = "0") Integer pageNumber, @RequestParam(value = "category", defaultValue = "all") String category, ModelMap model) {
    	Page<Post> postsPage = null;
    	if(null == category || category.isEmpty() || category.equals("all"))
    	postsPage = postService.getPostsPage(pageNumber, 10);
    	else
    		postsPage = postService.getPromoPostsList(pageNumber, 10, category);

        model.addAttribute("postsPage", postsPage);

        // should implement custom Spring Security  UserDetails instead of this, so it will be stored in session
        User currentUser = userService.currentUser();
        if (currentUser != null)
            model.addAttribute("userId", currentUser.getId());

        return StringUtils.POSTS;
    }

    @RequestMapping(value = {"/posts"}, method = RequestMethod.GET, headers="Accept=application/json", produces = "application/json;charset=UTF-8")
    public @ResponseBody String getPostsList(@RequestParam(value = "page", defaultValue = "0") Integer pageNumber, @RequestParam("category") String category,
    		ModelMap model) {
    	List<Post> posts =null;

    	posts = postService.getPostsList(pageNumber, 10);

    	model.addAttribute("category", category);
        return "[" + posts.stream().map(this::toJsonLink).collect(Collectors.joining(", \n")) + "]";
    }

    @RequestMapping(value = {"/posts/top"}, method = RequestMethod.GET, headers="Accept=application/json", produces = "application/json;charset=UTF-8")
    public @ResponseBody String getTopPostsList() {
        List<Post> posts = postService.getTopPostsList();

        return "[" + posts.stream().map(this::toJsonLink).collect(Collectors.joining(", \n")) + "]";
    }

    @RequestMapping(value = "/posts", method = RequestMethod.GET, params = {"tagged"})
    public String searchByTag(@RequestParam("tagged") String tagsStr, @RequestParam(value = "page", defaultValue = "0") Integer pageNumber,
                              ModelMap model, HttpServletRequest request) {
        List<String> tagNames = Arrays.stream(tagsStr.split(",")).map(String::trim).distinct().collect(Collectors.toList());

        if (tagNames.isEmpty()) {
            return "redirect:/posts";
        }

        Page<Post> postsPage = postService.findPostsByTag(tagNames, pageNumber, 10);

        model.addAttribute("postsPage", postsPage);

        model.addAttribute("searchTags", tagNames);

        String query = "tagged=" + request.getParameter("tagged");
        model.addAttribute("searchQuery", query);

        // should implement custom Spring Security  UserDetails instead of this, so it will be stored in session
        User currentUser = userService.currentUser();
        if (currentUser != null)
            model.addAttribute("userId", currentUser.getId());

        return StringUtils.POSTS;
    }

    @RequestMapping(value = "/posts/{postId}", method = RequestMethod.GET)
    public String showPost(@PathVariable("postId") Long postId, ModelMap model) {
        Post post = postService.getPost(postId);

        if(post.getFullPostText().charAt(0)=='\\')
        post.setFullPostText(StringEscapeUtils.unescapeJava( post.getFullPostText() ));

        if(post.getTitle().charAt(0)=='\\')
            post.setTitle(StringEscapeUtils.unescapeJava( post.getTitle() ));

        if (post==null ||(post.isHidden() && !userService.isAdmin()))
            throw new ResourceNotFoundException();

        model.addAttribute("post", post);

        if (userService.isAuthenticated()) {
            model.addAttribute("comment", new Comment());
        }

        // should implement custom Spring Security  UserDetails instead of this, so it will be stored in session
        User currentUser = userService.currentUser();
        if (currentUser != null)
            model.addAttribute("userId", currentUser.getId());

        return "post";
    }

    /*@PreAuthorize("hasRole('ROLE_ADMIN')")*/
    @RequestMapping(value = "/posts/create", method = RequestMethod.GET)
    public String showCreatePostForm(ModelMap model) {
        model.addAttribute("post", new PostEditDto());

        model.addAttribute("edit", false);

        return StringUtils.EDIT_POST;
    }

    /*@PreAuthorize("hasRole('ROLE_ADMIN')")*/
    @RequestMapping(value = "/posts/create", method = RequestMethod.POST)
    public String createPost(ModelMap model, @Valid @ModelAttribute("post") PostEditDto post, RedirectAttributes redirectAttributes, BindingResult result) {
        if (result.hasErrors()) {
            model.addAttribute("edit", false);

            return StringUtils.EDIT_POST;
        }

        postService.saveNewPost(post);
        boolean isAdmin = userService.isAdmin();
        if(!isAdmin)
        	{
        		redirectAttributes.addFlashAttribute("msg", true);
        	}
        else
        	{
        		redirectAttributes.addFlashAttribute("msg", false);
        	}
        return "redirect:/posts";
        }

    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @RequestMapping(value = "/posts/{postId}/edit", method = RequestMethod.GET)
    public String showEditPostForm(@PathVariable("postId") Long postId, ModelMap model) {
        PostEditDto post = postService.getEditablePost(postId);

        if (post == null)
            throw new ResourceNotFoundException();

        model.addAttribute("post", post);

        model.addAttribute("edit", true);

        return StringUtils.EDIT_POST;
    }

    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @RequestMapping(value = "/posts/{postId}/edit", method = RequestMethod.POST)
    public String updatePost(ModelMap model, @Valid @ModelAttribute("post") PostEditDto post, BindingResult result,
                                   @PathVariable("postId") Long postId) {
        post.setId(postId);

        if (result.hasErrors()) {
            model.addAttribute("edit", true);

            return StringUtils.EDIT_POST;
        }

        postService.updatePost(post);

        return "redirect:/posts/" + postId;
    }

    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @RequestMapping(value = "/posts/{postId}/hide", method = RequestMethod.POST)
    public @ResponseBody String hidePost(@PathVariable("postId") Long postId) {
        postService.setPostVisibility(postId, true);

        return StringUtils.OK;
    }

    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @RequestMapping(value = "/posts/{postId}/unhide", method = RequestMethod.POST)
    public @ResponseBody String unhidePost(@PathVariable("postId") Long postId) {
        postService.setPostVisibility(postId, false);

        return StringUtils.OK;
    }

    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @RequestMapping(value = "/posts/{postId}/delete", method = RequestMethod.POST)
    public @ResponseBody String deletePost(@PathVariable("postId") Long postId) {
        postService.deletePost(postId);

        return StringUtils.OK;
    }

    private String toJsonLink(Post post) {
        return "{" + JsonUtils.toJsonField("id", post.getId().toString()) + ", " + JsonUtils.toJsonField("title", post.getTitle()) + "}";
    }

    @PreAuthorize("hasRole('ROLE_USER')")
    @RequestMapping(value = "/posts/{postId}/like", method = RequestMethod.POST)
    public @ResponseBody String like(@PathVariable("postId") Long postId) {
        try {
            postService.vote(postId, true);
        } catch (AlreadyVotedException e) {
            return "already_voted";
        }

        return StringUtils.OK;
    }

    @PreAuthorize("hasRole('ROLE_USER')")
    @RequestMapping(value = "/posts/{postId}/dislike", method = RequestMethod.POST)
    public @ResponseBody String dislike(@PathVariable("postId") Long postId) {
        try {
            postService.vote(postId, false);
        } catch (AlreadyVotedException e) {
            return "already_voted";
        }

        return StringUtils.OK;
    }

}

redpajama_set_name: RedPajamaGithub


text:
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package entity;

import java.io.Serializable;
import java.util.Collection;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

/**
 *
 * @author Milhouse
 */
@Entity
@Table(name = "roles")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Roles.findAll", query = "SELECT r FROM Roles r"),
    @NamedQuery(name = "Roles.findByRoleid", query = "SELECT r FROM Roles r WHERE r.roleid = :roleid"),
    @NamedQuery(name = "Roles.findByRolename", query = "SELECT r FROM Roles r WHERE r.rolename = :rolename"),
    @NamedQuery(name = "Roles.findByCanceled", query = "SELECT r FROM Roles r WHERE r.canceled = :canceled")})
public class Roles implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "roleid")
    private Integer roleid;
    @Basic(optional = false)
    @Column(name = "rolename")
    private String rolename;
    @Column(name = "canceled")
    private Boolean canceled;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "rolesRoleid")
    private Collection<PersonsHasRoles> personsHasRolesCollection;

    public Roles() {
    }

    public Roles(Integer roleid) {
        this.roleid = roleid;
    }

    public Roles(Integer roleid, String rolename) {
        this.roleid = roleid;
        this.rolename = rolename;
    }

    public Integer getRoleid() {
        return roleid;
    }

    public void setRoleid(Integer roleid) {
        this.roleid = roleid;
    }

    public String getRolename() {
        return rolename;
    }

    public void setRolename(String rolename) {
        this.rolename = rolename;
    }

    public Boolean getCanceled() {
        return canceled;
    }

    public void setCanceled(Boolean canceled) {
        this.canceled = canceled;
    }

    @XmlTransient
    public Collection<PersonsHasRoles> getPersonsHasRolesCollection() {
        return personsHasRolesCollection;
    }

    public void setPersonsHasRolesCollection(Collection<PersonsHasRoles> personsHasRolesCollection) {
        this.personsHasRolesCollection = personsHasRolesCollection;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (roleid != null ? roleid.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Roles)) {
            return false;
        }
        Roles other = (Roles) object;
        if ((this.roleid == null && other.roleid != null) || (this.roleid != null && !this.roleid.equals(other.roleid))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return " " + rolename + " ";
    }

}


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
Grevillea 9(no. 52): 131 (1881)

#### Original name
Agaricus montagnei Kalchbr.

### Remarks
null


text:
''' Returns entries read in from config files to be used
to generates statement policies'''
import re
import sys
import ConfigParser
from c3.utils import logging

def read_config(config):
    ''' Read in config ini file for policies '''
    ini = ConfigParser.ConfigParser()
    ini.read(config)
    if ini.sections():
        return ini
    else:
        return False

def gen_s3_entry(ini, user, user_account):
    ''' Generate entries from config '''
    entry = list()
    pattern = re.compile("path")
    if ini.sections():
        for action in ini.sections():
            try:
                effect = ini.get(action, 'effect')
            except ConfigParser.NoOptionError, msg:
                logging.warn(msg)
            if ini.has_option(action, 'condition'):
                condition = ini.get(action, 'condition')
            else:
                condition = 'empty'
            for item in ini.items(action):
                if pattern.match(item[0]):
                    path = item[1]
                    entry.append('%s|%s|%s|%s|%s|%s' % (effect, action, user,
                                                        user_account, path,
                                                        condition))
    return sorted(entry)


text:
package com.owera.xapsws.impl;

import java.rmi.RemoteException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.owera.common.db.NoAvailableConnectionException;
import com.owera.common.log.Logger;
import com.owera.xaps.dbi.Unittype;
import com.owera.xaps.dbi.Unittype.ProvisioningProtocol;
import com.owera.xaps.dbi.UnittypeParameter;
import com.owera.xaps.dbi.UnittypeParameterFlag;
import com.owera.xaps.dbi.Unittypes;
import com.owera.xaps.dbi.User;
import com.owera.xaps.dbi.XAPS;

import com.owera.xapsws.AddOrChangeUnittypeRequest;
import com.owera.xapsws.AddOrChangeUnittypeResponse;
import com.owera.xapsws.Parameter;
import com.owera.xapsws.ParameterList;

public class AddOrChangeUnittype {

	private static Logger logger = new Logger();

	private XAPS xaps;
	private XAPSWS xapsWS;

	private void addOrChangeUnittypeImpl(Unittype unittypeXAPS, AddOrChangeUnittypeRequest gur) throws NoAvailableConnectionException, SQLException, RemoteException {
		unittypeXAPS.setDescription(gur.getUnittype().getDescription());
		//		unittypeXAPS.setMatcherId(gur.getUnittype().getMatcherId());
		unittypeXAPS.setProtocol(ProvisioningProtocol.toEnum(gur.getUnittype().getProtocol()));
		unittypeXAPS.setVendor(gur.getUnittype().getVendor());
		ParameterList parameterList = gur.getUnittype().getParameters();
		List<UnittypeParameter> acUtpList = new ArrayList<UnittypeParameter>();
		List<UnittypeParameter> dUtpList = new ArrayList<UnittypeParameter>();
		if (parameterList != null && parameterList.getParameterArray() != null) {
			for (Parameter param : parameterList.getParameterArray()) {
				UnittypeParameter utp = unittypeXAPS.getUnittypeParameters().getByName(param.getName());
				if (param.getFlags() != null && !param.getFlags().equals("D") && !param.getFlags().equals("AC"))
					throw XAPSWS.error(logger, "Flag for parameter " + param.getName() + " had value " + param.getFlags() + ", but must be either D or AC");
				if (param.getFlags() == null || param.getFlags().equals("AC")) {
					if (utp == null)
						acUtpList.add(new UnittypeParameter(unittypeXAPS, param.getName(), new UnittypeParameterFlag(param.getValue())));
					else {
						utp.setFlag(new UnittypeParameterFlag(param.getValue()));
						acUtpList.add(utp);
					}
				} else if (param.getFlags().equals("D") && utp != null) {
					dUtpList.add(utp);
				}
			}
		}
		//		System.out.println("AOC: Unitypes object: " + xapsWS.getXAPS().getUnittypes());
		xapsWS.getXAPS().getUnittypes().addOrChangeUnittype(unittypeXAPS, xaps);
		for (UnittypeParameter utp : dUtpList) {
			//			System.out.println("D: Unittype: " + unittypeXAPS + ", UTP:" + utp.getName() + ", " + utp.getFlag().getFlag());
			unittypeXAPS.getUnittypeParameters().deleteUnittypeParameter(utp, xaps);
		}
		for (UnittypeParameter utp : acUtpList) {
			//			System.out.println("AOC: Unittype: " + unittypeXAPS + ", UTP:" + utp.getName() + ", " + utp.getFlag().getFlag());
			unittypeXAPS.getUnittypeParameters().addOrChangeUnittypeParameter(utp, xaps);
		}
	}

	public AddOrChangeUnittypeResponse addOrChangeUnittype(AddOrChangeUnittypeRequest gur) throws RemoteException {
		try {

			xapsWS = XAPSWSFactory.getXAPSWS(gur.getLogin());
			xaps = xapsWS.getXAPS();
			User user = xapsWS.getId().getUser();
			if (gur.getUnittype() == null || gur.getUnittype().getName() == null)
				throw XAPSWS.error(logger, "No unittype name specified");
			boolean isAdmin = user.getPermissions().getPermissions().length == 0;
			Unittypes unittypes = xaps.getUnittypes();
			Unittype unittypeXAPS = null;
			if (unittypes.getByName(gur.getUnittype().getName()) == null) { // make new unittype
				if (isAdmin) {// allow if login is admin
					com.owera.xapsws.Unittype uWS = gur.getUnittype();
					unittypeXAPS = new Unittype(uWS.getName(), uWS.getVendor(), uWS.getDescription(), ProvisioningProtocol.toEnum(uWS.getProtocol()));
					addOrChangeUnittypeImpl(unittypeXAPS, gur);
				} else {
					throw XAPSWS.error(logger, "The unittype " + gur.getUnittype().getName() + " does not exist, your login does not have the permissions to create it.");
				}
			} else { // change an existing one
				unittypeXAPS = xapsWS.getUnittypeFromXAPS(gur.getUnittype().getName());
				addOrChangeUnittypeImpl(unittypeXAPS, gur);
			}
			return new AddOrChangeUnittypeResponse(ConvertXAPS2WS.convert(unittypeXAPS));
		} catch (Throwable t) {
			if (t instanceof RemoteException)
				throw (RemoteException) t;
			else {
				throw XAPSWS.error(logger, t);
			}
		}

	}
}


text:
select
  'rcomments,All' as repo_group,
  round(count(distinct id) / {{n}}, 2) as result
from
  gha_comments
where
  created_at >= '{{from}}'
  and created_at < '{{to}}'
  and (lower(dup_actor_login) {{exclude_bots}})
union select sub.repo_group,
  round(count(distinct sub.id) / {{n}}, 2) as result
from (
  select 'rcomments,' || coalesce(ecf.repo_group, r.repo_group) as repo_group,
    t.id
  from
    gha_repos r,
    gha_comments t
  left join
    gha_events_commits_files ecf
  on
    ecf.event_id = t.event_id
  where
    r.id = t.dup_repo_id
    and t.created_at >= '{{from}}'
    and t.created_at < '{{to}}'
    and (lower(t.dup_actor_login) {{exclude_bots}})
  ) sub
where
  sub.repo_group is not null
group by
  sub.repo_group
order by
  result desc,
  repo_group asc
;


text:
<?php

require_once('Database_dev.php');
require_once('User.php');

class UserFactory
{
	static $class = 'User';

	public static function insert( $device )
	{
		$db = DatabaseConnectionFactory::getConnection();

		$query = "INSERT INTO user ( device ) VALUES ( '" .
				$db->escape_string( $device ) . "' )";

		if ( ( $db->query( $query ) === true ) &&
			 ( $id = $db->insert_id ) )
		{
			Util::log( __METHOD__ . "() created new user {$id} for device {$device}" );
			return self::getUser( $id );
		}
		else
			Util::log( __METHOD__ . "() ERROR failed to create new user for device {$device}" );

		return false;
	}

	public static function getUser( $id )
	{
		$db = DatabaseConnectionFactory::getConnection();
		$user = null;

		if ( ( $result = $db->query( "SELECT * FROM user WHERE id='" . $db->escape_string( $id ) . "'" ) ) &&
				( $result->num_rows ) )
		{
			$user = $result->fetch_object( self::$class );
			$result->close();
		}

		return $user;
	}

	public static function getUserByDevice( $device )
	{
		$db = DatabaseConnectionFactory::getConnection();
		$user = null;

		if ( ( $result = $db->query( "SELECT * FROM user WHERE device='" . $db->escape_string( $device ) . "'" ) ) &&
				( $result->num_rows ) )
		{
			$user = $result->fetch_object( self::$class );
			$result->close();
		}

		return $user;
	}

	/**
	* @desc update user record identified by $old with diffs in $new
	* @param User $old object instantiated from current DB record for user
	* @param User $new object instantiated from client data
	*/
	public static function update( User $old, User $new )
	{
		$db = DatabaseConnectionFactory::getConnection();

		$update = '';

		$noAppVersion = true;
		//$fields = (array) $old;
		foreach ( $new->getPersonalInfo() as $key => $value )
		{
			// only update values if non-null or '0'

			if ( !empty( $value ) || is_numeric( $value ) )
			{
				//and only if it's not the email address, handle that elsewhere
				//if($key != 'email'){
				Util::log( "updating {$key}\t=> '{$value}'" );
				if ( !empty( $update ) )
					$update .= ', ';

				$update .= "{$key}='" . $db->escape_string( $value ) . "'";
				//}
				if($key == 'email'){
					//add the email address to the email table as well
					self::addEmail( $value );

				}
				if($key == 'app_version'){
					$noAppVersion = false;
				}
			}
		}
		if($noAppVersion){
			if ( !empty( $update ) )
					$update .= ', ';
			$update .= "app_version='1.0'";
		}
		// sanity check - ensure we have at least one field to update
		// and a valid user.id to work with
		if ( $update && isset( $old->id ) && $old->id )
		{
			// build update query
			$query = "UPDATE user SET {$update} WHERE id='" . $db->escape_string( $old->id ) . "' LIMIT 1";

			if ( $db->query( $query ) )
			{
				Util::log( __METHOD__ . "() updated user {$old->id}:" );
				Util::log( $query );
				return self::getUser( $old->id );
			}
			else
				Util::log( __METHOD__ . "() ERROR failed to update user {$old->id}" );
		}
		else
			Util::log( __METHOD__ . " nothing to do" );

		return false;
	}

	public static function addEmail( $email )
	{
		$db = DatabaseConnectionFactory::getConnection();
//		$query = "INSERT into email (email_address) VALUES ('".$db->escape_string( $email )."')";
		$query = "INSERT into email (email_address) SELECT '".$db->escape_string( $email )."' FROM email WHERE email_address='".$db->escape_string( $email )."' HAVING COUNT(*)=0";
		if ( $db->query( $query ) )
		{
			Util::log( __METHOD__ . "() added email {$email}:" );
			Util::log( $query );
		}
		else
			Util::log( __METHOD__ . "() ERROR failed to add email {$email}" );
	}
}


text:
@implementation TimeTool
+ (NSString *)shijianchuodate:(NSString *)string{
    if (![string isEqual:[NSNull null]]) {

        // 格式化时间
        NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
        formatter.timeZone = [NSTimeZone systemTimeZone];
        [formatter setDateFormat:@"YYYY-MM-dd"];

        // 毫秒值转化为秒
        NSDate* date = [NSDate dateWithTimeIntervalSince1970:[string doubleValue]];

        NSString* dateString = [formatter stringFromDate:date];
        return dateString;
    }
    return @"0";
}
+ (NSString *)shijianchuotime:(NSString *)string{

    // 格式化时间
    NSDateFormatter* formatter1 = [[NSDateFormatter alloc] init];
    formatter1.timeZone = [NSTimeZone systemTimeZone];
    [formatter1 setDateFormat:@"HH:mm:ss"];
    // 毫秒值转化为秒
    NSDate* date1 = [NSDate dateWithTimeIntervalSince1970:[string doubleValue]];

    NSString *timeStr = [formatter1 stringFromDate:date1];
    return timeStr;
}
+ (NSString *)dayCount:(NSString *)endStr beginStr:(NSString *)beginStr{
    //创建日期格式化对象
    NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm"];

    //取两个日期对象的时间间隔:
    //这里的NSTimeInterval 并不是对象,是基本型,其实是double类型,是由c定义的:typedef double NSTimeInterval;
    if (![endStr isEqual:[NSNull null]] && ![beginStr isEqual:[NSNull null]] ) {
        NSDate *endDate = [NSDate dateWithTimeIntervalSince1970:[endStr doubleValue]];

        NSDate *beginDate = [NSDate dateWithTimeIntervalSince1970:[beginStr doubleValue]];

        NSTimeInterval time= [endDate timeIntervalSinceDate:beginDate];

        int days=((int)time)/(3600*24);
        //    int hours=((int)time)%(3600*24)/3600;
        NSString *dateContent=[[NSString alloc] initWithFormat:@"%i",days];
        return dateContent;
    }
    return @"1";
}

+ (NSString *)shijianchuodate:(NSString *)string staus:(NSString *)status{
    // 格式化时间
    if (![string isEqual:[NSNull null]]) {

        NSDateFormatter* formatter1 = [[NSDateFormatter alloc] init];
        formatter1.timeZone = [NSTimeZone systemTimeZone];
        [formatter1 setDateFormat:status];
        // 毫秒值转化为秒
        NSDate* date1 = [NSDate dateWithTimeIntervalSince1970:[string doubleValue]];

        NSString *timeStr = [formatter1 stringFromDate:date1];
        return timeStr;
    }
    return @"0";
}

@end


text:
namespace Caliburn.Micro.SimpleNavigation {
    public class ShellViewModel : Conductor<object> {
        public ShellViewModel() {
            ShowPageOne();
        }

        public void ShowPageOne() {
            ActivateItem(new PageOneViewModel());
        }

        public void ShowPageTwo() {
            ActivateItem(new PageTwoViewModel());
        }
    }
}


text:
package org.apache.spark.deploy.k8s.features

import java.nio.file.Paths
import java.util.UUID

import io.fabric8.kubernetes.api.model.{ContainerBuilder, HasMetadata, PodBuilder, VolumeBuilder, VolumeMountBuilder}

import org.apache.spark.deploy.k8s.{KubernetesConf, KubernetesDriverSpecificConf, KubernetesRoleSpecificConf, SparkPod}
import org.apache.spark.deploy.k8s.Config._

private[spark] class LocalDirsFeatureStep(
    conf: KubernetesConf[_ <: KubernetesRoleSpecificConf],
    defaultLocalDir: String = s"/var/data/spark-${UUID.randomUUID}")
  extends KubernetesFeatureConfigStep {

  // Cannot use Utils.getConfiguredLocalDirs because that will default to the Java system
  // property - we want to instead default to mounting an emptydir volume that doesn't already
  // exist in the image.
  // We could make utils.getConfiguredLocalDirs opinionated about Kubernetes, as it is already
  // a bit opinionated about YARN and Mesos.
  private val resolvedLocalDirs = Option(conf.sparkConf.getenv("SPARK_LOCAL_DIRS"))
    .orElse(conf.getOption("spark.local.dir"))
    .getOrElse(defaultLocalDir)
    .split(",")
  private val useLocalDirTmpFs = conf.get(KUBERNETES_LOCAL_DIRS_TMPFS)

  override def configurePod(pod: SparkPod): SparkPod = {
    val localDirVolumes = resolvedLocalDirs
      .zipWithIndex
      .map { case (localDir, index) =>
        new VolumeBuilder()
          .withName(s"spark-local-dir-${index + 1}")
          .withNewEmptyDir()
            .withMedium(if (useLocalDirTmpFs) "Memory" else null)
          .endEmptyDir()
          .build()
      }
    val localDirVolumeMounts = localDirVolumes
      .zip(resolvedLocalDirs)
      .map { case (localDirVolume, localDirPath) =>
        new VolumeMountBuilder()
          .withName(localDirVolume.getName)
          .withMountPath(localDirPath)
          .build()
      }
    val podWithLocalDirVolumes = new PodBuilder(pod.pod)
      .editSpec()
        .addToVolumes(localDirVolumes: _*)
        .endSpec()
      .build()
    val containerWithLocalDirVolumeMounts = new ContainerBuilder(pod.container)
      .addNewEnv()
        .withName("SPARK_LOCAL_DIRS")
        .withValue(resolvedLocalDirs.mkString(","))
        .endEnv()
      .addToVolumeMounts(localDirVolumeMounts: _*)
      .build()
    SparkPod(podWithLocalDirVolumes, containerWithLocalDirVolumeMounts)
  }

  override def getAdditionalPodSystemProperties(): Map[String, String] = Map.empty

  override def getAdditionalKubernetesResources(): Seq[HasMetadata] = Seq.empty
}


text:
inlets = 1;
outlets = 1;

// global variables
var exampleDefs = {
	"S": many(concat(value("S"), or(ref("R"), ref("D")))),
	"R": concat(value("R"), or(ref("G"), empty())),
	"G": concat(value("G") ,or(ref("P"), ref("R"))),
	"P": concat(value("P"), or(ref("D"), ref("G"))),
	"D": concat(value("D"), or(empty(), ref("P")))
};

var currentState = exampleDefs["S"];

function many(e) {
	return {"Type": "ZeroOrMore", "Expr": e}
}

function concat(e1, e2) {
	return {"Type": "Concat", "Expr": e1, "Expr2": e2}
}

function or(e1, e2) {
	return {"Type": "Or", "Expr": e1, "Expr2": e2}
}

function value(v) {
	return {"Type": "Value", "Value": v}
}

function ref(v) {
	return {"Type": "Reference", "Name": v}
}

function emptyset() {
	return {"Type": "Value", "Value": "emptyset"}
}

function empty() {
	return {"Type": "Value", "Value": "empty"}
}

function nullable(refs, expr) {
	switch (expr.Type) {
	case "Value":
		switch (expr.Value) {
		case "empty":
			return true
		case "emptyset":
			return false
		}
		return false
	case "Or":
		return nullable(refs, expr.Expr) || nullable(refs, expr.Expr2)
	case "Concat":
		return nullable(refs, expr.Expr) && nullable(refs, expr.Expr2)
	case "ZeroOrMore":
		return true
	case "Reference":
		return nullable(refs, refs[expr.Name])
	default:
		console.log("unknown type: " + expr.Type)
	}
}

function toStr(expr) {
	switch (expr.Type) {
	case "Value":
		return "\"" + expr.Value + "\""
	case "Or":
		return "or(" + toStr(expr.Expr) + ", " + toStr(expr.Expr2) + ")"
	case "Concat":
		return "concat(" + toStr(expr.Expr) + ", " + toStr(expr.Expr2) + ")"
	case "ZeroOrMore":
		return "many(" + toStr(expr.Expr) + ")"
	case "Reference":
		return "ref(" + expr.Name + ")"
	default:
		throw("unknown type: " + JSON.stringify(expr))
	}
}

function isEmpty(expr) {
	return (expr.Type == "Value") && (expr.Value == "empty")
}

function isEmptySet(expr) {
	return (expr.Type == "Value") && (expr.Value == "emptyset")
}

function simplify(expr) {
	switch (expr.Type) {
	case "Value":
		return expr
	case "Or":
		var left = simplify(expr.Expr);
		var right = simplify(expr.Expr2);
		if (isEmptySet(left)) {
			return right
		}
		if (isEmptySet(right)) {
			return left
		}
		if (JSON.stringify(left) == JSON.stringify(right)) {
			return left
		}
		return or(left, right)
	case "Concat":
		var left = simplify(expr.Expr);
		var right = simplify(expr.Expr2);
		if (isEmpty(left)) {
			return right
		}
		if (isEmptySet(left)) {
			return emptyset()
		}
		if (isEmptySet(right)) {
			return emptyset()
		}
		return concat(left, right)
	case "ZeroOrMore":
		return many(simplify(expr.Expr))
	case "Reference":
		return expr
	default:
		throw("unknown type: " + JSON.stringify(expr))
	}
}

function satis(refs, expr) {
	switch (expr.Type) {
	case "Value":
		switch (expr.Value) {
		case "empty":
			return true
		case "emptyset":
			return false
		}
		return true
	case "Or":
		return satis(refs, expr.Expr) || satis(refs, expr.Expr2)
	case "Concat":
		return satis(refs, expr.Expr) && satis(refs, expr.Expr2)
	case "ZeroOrMore":
		return true
	case "Reference":
		return satis(refs, refs[expr.Name])
	default:
		throw("unknown type: " + JSON.stringify(expr))
	}
}

function deriv(refs, expr, c) {
	switch (expr.Type) {
	case "Value":
		switch (expr.Value) {
		case "empty":
			return emptyset()
		case "emptyset":
			return emptyset()
		}
		if (expr.Value == c) {
			return empty()
		} else {
			return emptyset()
		}
	case "Or":
		var left = deriv(refs, expr.Expr, c);
		var right = deriv(refs, expr.Expr2, c);
		return or(left, right)
	case "Concat":
		if (nullable(refs, expr.Expr)) {
			var left = deriv(refs, expr.Expr, c);
			var right = deriv(refs, expr.Expr2, c);
			return or(concat(left, expr.Expr2), right)
		} else {
			var left = deriv(refs, expr.Expr, c);
			return concat(left, expr.Expr2)
		}
	case "ZeroOrMore":
		var e = deriv(refs, expr.Expr, c);
		return concat(e, expr)
	case "Reference":
		return deriv(refs, refs[expr.Name], c)
	default:
		throw("unknown type: " + JSON.stringify(expr))
	}
}

function midiToNote(v) {
	switch (v % 12) {
	case 0:
		return 'S';
	case 1:
		return 'r';
	case 2:
		return 'R';
	case 3:
		return 'g';
	case 4:
		return 'G';
	case 5:
		return 'm';
	case 6:
		return 'M';
	case 7:
		return 'P';
	case 8:
		return 'd';
	case 9:
		return 'D';
	case 10:
		return 'n';
	case 11:
		return 'N';
	default:
		return 'X';
	}
}

function msg_int(note)
{
	var notestr = midiToNote(note);
	var newState = deriv(exampleDefs, currentState, notestr);
	newState = simplify(newState);
	if (satis(exampleDefs, newState)) {
		currentState = newState;
	} else {
		note = 0;
	}
	outlet(0, note);
}


text:
/**
 * spark_src
 */
package com.xiongyingqi.util;

import java.lang.Thread.State;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;

/**
 * 线程池帮助类

 * 如果要使用本类调用线程,请使用 public static void invoke(Runnable);

 * 如果要使用代理线程来调用方法则使用 public static void invoke(Object instance, Method method,
 * Object... parameters);

 * 如果要使用代理线程来调用方法并且需要获取其返回值则使用 public static void invoke(Object
 * callBackInstance, Method callBackMethod, Object instance, Method method,
 * Object... parameters)

 * 初始化时默认使用大小为5的线程池,如果要设置大小,请一定要在使用任何调用方法之前或当线程任务全部执行完之后再执行 public static void
 * setPoolSize(int) 方法

 *
 *

 * public static void callBack(Object object, Throwable throwable, Object... parameters) {
 * 	System.out.println(object);
 * 	throwable.printStackTrace();
 * 	for (int i = 0; i < parameters.length; i++) {
 * 		Object parameter = parameters[i];
 * 		System.out.println("parameter ======== " + parameter);
 * 	}
 * }
 *
 * public static void main(String[] args) {
 * 	try {
 * 		ThreadPool.invoke(null, ThreadPool.class.getDeclaredMethod("callBack", Object.class,
 * 				Throwable.class, Object[].class), null, Integer.class.getDeclaredMethod("parseInt",
 * 				String.class), "ss");
 * 	} catch (SecurityException e) {
 * 		e.printStackTrace();
 * 	} catch (NoSuchMethodException e) {
 * 		e.printStackTrace();
 * 	}
 * }
 *

 *
 * @author 瑛琪 xiongyingqi.com
 * @version 2013-9-10 下午4:12:07
 */
public class ThreadPool {
	private static ExecutorService pool = new ScheduledThreadPoolExecutor(5);

	private static PoolStatus status = PoolStatus.STOPED;

	/**
	 * PoolStatus
	 *
	 * @return the status
	 */
	public static PoolStatus getStatus() {
		return status;
	}

	/**
	 * PoolStatus
	 *
	 * @param status
	 *            the status to set
	 */
	public static void setStatus(PoolStatus status) {
		ThreadPool.status = status;
	}

	static enum PoolStatus {
		STARTING, STARTED, STOPING, STOPED, WAITING
	}

	public static void setPoolSize(int poolSize) throws ThreadPoolException {
		if (poolSize < 0) {
			throw new IllegalArgumentException("参数个数不能小于0!");
		} else if (status != PoolStatus.STOPED) {
			throw new ThreadPoolException("线程池已经开始运行,不能重新设置大小");
		} else {
			pool = new ScheduledThreadPoolExecutor(poolSize);
		}
	}

	public static void invoke(Runnable runnable) {
		try {
			pool.execute(runnable);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 带回调函数的代理线程,本方法将创建新线程在线程池内运行

	 * 注意:回调函数一定要是带三个参数的方法:

	 * 第一个参数来接收代理函数执行方法的返回值,

	 * 第二个参数用来接收代理函数执行过程中抛出的异常,

	 * 第三个参数用来回调调用时传给代理线程的参数列表

	 *

	 *

	 * 回调方法的获取方法

	 *
	 *

	 * Class.getDeclaredMethod("callBack", Object.class, Throwable.class, Object[].class);
	 *

	 *
	 * 2013-9-16 下午9:30:29
	 *
	 * @param callBackInstance
	 *            接收代理线程执行完成之后调用方法所在对象,如果为静态方法则该参数可为null
	 * @param callBackMethod
	 *            代理线程执行完后的回调函数,必须是method(Object, Throwable, Object...)形式的函数
	 * @param instance
	 *            调用实例,如果为静态方法则该参数可为null
	 * @param method
	 *            调用方法
	 * @param parameters
	 *            参数列表
	 */
	public static void invoke(Object callBackInstance, Method callBackMethod, Object instance,
			Method method, Object... parameters) {
		if (method != null) {
			ProxyThread proxyThread = new ProxyThread(callBackInstance, callBackMethod, instance,
					method, parameters);
			pool.execute(proxyThread);
		} else {
			EntityHelper.print("空对象");
			StackTraceHelper.printStackTrace();
		}
	}

	/**
	 * 代理线程,本方法将创建新线程在线程池内运行

	 * 2013-9-16 下午9:38:12
	 *
	 * @param instance
	 *            调用实例,如果为静态方法则该参数可为null
	 * @param method
	 *            调用方法
	 * @param parameters
	 *            参数列表,必须是Method对应的
	 */
	public static void invoke(Object instance, Method method, Object... parameters) {
		invoke(null, null, instance, method, parameters);
	}

	public static void shutDown() {
		status = PoolStatus.STOPING;
		new Thread(new StateThread()).start();
	}

	private static void shutDowned() {
		status = PoolStatus.STOPED;
	}

	static class ProxyThread implements Runnable {
		private Object instance;
		private Method method;
		private Object[] parameters;
		private Method callBackMethod;
		private Object callBackInstance;

		public ProxyThread() {

		}

		public ProxyThread(Object callBackInstance, Method callBackMethod, Object instance,
				Method method, Object... parameters) {
			this.instance = instance;
			this.method = method;
			this.parameters = parameters;
			this.callBackMethod = callBackMethod;
			this.callBackInstance = callBackInstance;
			// EntityHelper.printDetail(instance);
			// EntityHelper.printDetail(method);
			// EntityHelper.printDetail(parameters);
		}

		/**
		 *

		 * 2013-9-10 下午4:38:38
		 *
		 * @see java.lang.Runnable#run()
		 */
		@Override
		public void run() {
			try {
				Object object = method.invoke(instance, parameters);
				if (callBackMethod != null) {
					try {
						callBackMethod.invoke(callBackInstance, object, null, parameters);
					} catch (IllegalArgumentException e) {
						e.printStackTrace();
					} catch (IllegalAccessException e) {
						e.printStackTrace();
					} catch (InvocationTargetException e) {
						//						e.printStackTrace();
						Throwable t = e.getTargetException();
						t.printStackTrace();

					}
				}
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				Throwable t = e.getTargetException();
				try {
					callBackMethod.invoke(callBackInstance, null, t, parameters);
				} catch (IllegalArgumentException e1) {
					e1.printStackTrace();
				} catch (IllegalAccessException e1) {
					e1.printStackTrace();
				} catch (InvocationTargetException e1) {
					e1.printStackTrace();
				}
			}
		}

		/**
		 * Method
		 *
		 * @return the callBackMethod
		 */
		public Method getCallBackMethod() {
			return this.callBackMethod;
		}

		/**
		 * Method
		 *
		 * @param callBackMethod
		 *            the callBackMethod to set
		 */
		public void setCallBackMethod(Method callBackMethod) {
			this.callBackMethod = callBackMethod;
		}

		/**
		 * Object
		 *
		 * @return the callBackInstance
		 */
		public Object getCallBackInstance() {
			return this.callBackInstance;
		}

		/**
		 * Object
		 *
		 * @param callBackInstance
		 *            the callBackInstance to set
		 */
		public void setCallBackInstance(Object callBackInstance) {
			this.callBackInstance = callBackInstance;
		}

		/**
		 * Object
		 *
		 * @return the instance
		 */
		public Object getInstance() {
			return instance;
		}

		/**
		 * Object
		 *
		 * @param instance
		 *            the instance to set
		 */
		public void setInstance(Object instance) {
			this.instance = instance;
		}

		/**
		 * Method
		 *
		 * @return the method
		 */
		public Method getMethod() {
			return method;
		}

		/**
		 * Method
		 *
		 * @param method
		 *            the method to set
		 */
		public void setMethod(Method method) {
			this.method = method;
		}

		/**
		 * Object[]
		 *
		 * @return the parameters
		 */
		public Object[] getParameters() {
			return parameters;
		}

		/**
		 * Object[]
		 *
		 * @param parameters
		 *            the parameters to set
		 */
		public void setParameters(Object[] parameters) {
			this.parameters = parameters;
		}

	}

	static class StateThread implements Runnable {
		@Override
		public void run() {
			ExecutorService executorService = ThreadPool.pool;
			while (true) {
				Thread[] leastThreads = new Thread[Thread.activeCount()];
				int length = Thread.enumerate(leastThreads);

				boolean isAllWaiting = false;
				for (int i = 0; i < leastThreads.length; i++) {
					Thread thread = leastThreads[i];
					System.out.println("thread: " + thread.toString());
					System.out.println(thread.getState());

					System.out.println("thread.getState() == State.WAITING: "
							+ (thread.getState() == State.WAITING));

					if (thread.getName().startsWith("pool")) {
						if (thread.getState() == State.WAITING) {
							isAllWaiting = true;
							// thread.interrupt();
							// System.out.println("等待线程结束:" + thread);
						} else {
							isAllWaiting = false;
						}
					}
					// System.out.println(Thread.currentThread().getId());
				}
				if (isAllWaiting) {
					executorService.shutdownNow();
					if (executorService.isShutdown()) {
						System.out.println("pool.isShutdown() ================= "
								+ executorService.isShutdown());
						shutDowned();
						return;
					}
				}
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static void callBack(Object object, Throwable throwable, Object... parameters) {
		System.out.println(object);
		if(throwable != null){
			throwable.printStackTrace();
		}
		for (int i = 0; i < parameters.length; i++) {
			Object parameter = parameters[i];
			System.out.println("parameter ======== " + parameter);
		}
		System.out.println(TimerHelper.getTime(1));
	}

	public static void main(String[] args) {
		try {
//			TimerHelper.getTime(1);
//			Thread.sleep(1000);
			for (int i = 0; i < 100000; i++) {
				ThreadPool.invoke(null, ThreadPool.class.getDeclaredMethod("callBack", Object.class,
						Throwable.class, Object[].class), null, Integer.class.getDeclaredMethod(
								"parseInt", String.class), "124124");
			}
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
	}
}


text:
/* Sequences and replication (not delayed) are resolved in this class.
   Number of elements to which a delayed replication applies are recomputed to
   take account of the expansion.
   Expanded descriptors cannot contain sequences and only delayed replication
   can appear
*/

#include "grib_api_internal.h"
/*
This is used by make_class.pl

START_CLASS_DEF
CLASS      = accessor
SUPER      = grib_accessor_class_long
IMPLEMENTS = unpack_long;pack_long
IMPLEMENTS = unpack_double
IMPLEMENTS = init;dump;destroy
IMPLEMENTS = value_count; get_native_type
MEMBERS    = const char* unexpandedDescriptors
MEMBERS    = const char* sequence
MEMBERS    = const char* expandedName
MEMBERS    = const char* tablesAccessorName
MEMBERS    = bufr_descriptors_array* expanded
MEMBERS    = int rank
MEMBERS    = grib_accessor* expandedAccessor
MEMBERS    = int do_expand
MEMBERS    = grib_accessor* tablesAccessor

END_CLASS_DEF

*/

/* START_CLASS_IMP */

/*

Don't edit anything between START_CLASS_IMP and END_CLASS_IMP
Instead edit values between START_CLASS_DEF and END_CLASS_DEF
or edit "accessor.class" and rerun ./make_class.pl

*/

static int  get_native_type(grib_accessor*);
static int pack_long(grib_accessor*, const long* val,size_t *len);
static int unpack_double(grib_accessor*, double* val,size_t *len);
static int unpack_long(grib_accessor*, long* val,size_t *len);
static int value_count(grib_accessor*,long*);
static void destroy(grib_context*,grib_accessor*);
static void dump(grib_accessor*, grib_dumper*);
static void init(grib_accessor*,const long, grib_arguments* );
static void init_class(grib_accessor_class*);

typedef struct grib_accessor_expanded_descriptors {
    grib_accessor          att;
/* Members defined in gen */
/* Members defined in long */
/* Members defined in expanded_descriptors */
	const char* unexpandedDescriptors;
	const char* sequence;
	const char* expandedName;
	const char* tablesAccessorName;
	bufr_descriptors_array* expanded;
	int rank;
	grib_accessor* expandedAccessor;
	int do_expand;
	grib_accessor* tablesAccessor;
} grib_accessor_expanded_descriptors;

extern grib_accessor_class* grib_accessor_class_long;

static grib_accessor_class _grib_accessor_class_expanded_descriptors = {
    &grib_accessor_class_long,                      /* super                     */
    "expanded_descriptors",                      /* name                      */
    sizeof(grib_accessor_expanded_descriptors),  /* size                      */
    0,                           /* inited */
    &init_class,                 /* init_class */
    &init,                       /* init                      */
    0,                  /* post_init                      */
    &destroy,                    /* free mem                       */
    &dump,                       /* describes himself         */
    0,                /* get length of section     */
    0,              /* get length of string      */
    &value_count,                /* get number of values      */
    0,                 /* get number of bytes      */
    0,                /* get offset to bytes           */
    &get_native_type,            /* get native type               */
    0,                /* get sub_section                */
    0,               /* grib_pack procedures long      */
    0,                 /* grib_pack procedures long      */
    &pack_long,                  /* grib_pack procedures long      */
    &unpack_long,                /* grib_unpack procedures long    */
    0,                /* grib_pack procedures double    */
    &unpack_double,              /* grib_unpack procedures double  */
    0,                /* grib_pack procedures string    */
    0,              /* grib_unpack procedures string  */
    0,          /* grib_pack array procedures string    */
    0,        /* grib_unpack array procedures string  */
    0,                 /* grib_pack procedures bytes     */
    0,               /* grib_unpack procedures bytes   */
    0,            /* pack_expression */
    0,              /* notify_change   */
    0,                /* update_size   */
    0,            /* preferred_size   */
    0,                    /* resize   */
    0,      /* nearest_smaller_value */
    0,                       /* next accessor    */
    0,                    /* compare vs. another accessor   */
    0,     /* unpack only ith value          */
    0,     /* unpack a subarray         */
    0,              		/* clear          */
    0,               		/* clone accessor          */
};

grib_accessor_class* grib_accessor_class_expanded_descriptors = &_grib_accessor_class_expanded_descriptors;

static void init_class(grib_accessor_class* c)
{
	c->next_offset	=	(*(c->super))->next_offset;
	c->string_length	=	(*(c->super))->string_length;
	c->byte_count	=	(*(c->super))->byte_count;
	c->byte_offset	=	(*(c->super))->byte_offset;
	c->sub_section	=	(*(c->super))->sub_section;
	c->pack_missing	=	(*(c->super))->pack_missing;
	c->is_missing	=	(*(c->super))->is_missing;
	c->pack_double	=	(*(c->super))->pack_double;
	c->pack_string	=	(*(c->super))->pack_string;
	c->unpack_string	=	(*(c->super))->unpack_string;
	c->pack_string_array	=	(*(c->super))->pack_string_array;
	c->unpack_string_array	=	(*(c->super))->unpack_string_array;
	c->pack_bytes	=	(*(c->super))->pack_bytes;
	c->unpack_bytes	=	(*(c->super))->unpack_bytes;
	c->pack_expression	=	(*(c->super))->pack_expression;
	c->notify_change	=	(*(c->super))->notify_change;
	c->update_size	=	(*(c->super))->update_size;
	c->preferred_size	=	(*(c->super))->preferred_size;
	c->resize	=	(*(c->super))->resize;
	c->nearest_smaller_value	=	(*(c->super))->nearest_smaller_value;
	c->next	=	(*(c->super))->next;
	c->compare	=	(*(c->super))->compare;
	c->unpack_double_element	=	(*(c->super))->unpack_double_element;
	c->unpack_double_subarray	=	(*(c->super))->unpack_double_subarray;
	c->clear	=	(*(c->super))->clear;
	c->make_clone	=	(*(c->super))->make_clone;
}

/* END_CLASS_IMP */

#define MYDEBUG 0

typedef struct change_coding_params {
    int associatedFieldWidth;
    int localDescriptorWidth;
    int extraWidth;
    int extraScale;
    int newStringWidth;
    double referenceFactor;
} change_coding_params ;

/* Handy macro to catch errors.
 * Arguments: array is a pointer to 'bufr_descriptors_array', result is pointer to 'bufr_descriptor' */
#define DESCRIPTORS_POP_FRONT_OR_RETURN(array,result) {\
       if(array->n == 0) { *err=GRIB_INTERNAL_ERROR; return 0; } \
       result=grib_bufr_descriptors_array_pop_front(array); \
    }

static void init(grib_accessor* a, const long len , grib_arguments* args )
{
    grib_accessor_expanded_descriptors* self = (grib_accessor_expanded_descriptors*)a;
    int n=0;
    self->tablesAccessorName=grib_arguments_get_name(grib_handle_of_accessor(a),args,n++);
    self->expandedName=grib_arguments_get_name(grib_handle_of_accessor(a),args,n++);
    self->rank=grib_arguments_get_long(grib_handle_of_accessor(a),args,n++);
    if (self->rank!=0) {
        self->expandedAccessor=grib_find_accessor(grib_handle_of_accessor(a),self->expandedName);
    } else {
        self->expandedAccessor=0;
    }
    self->unexpandedDescriptors=grib_arguments_get_name(grib_handle_of_accessor(a),args,n++);
    self->sequence=grib_arguments_get_name(grib_handle_of_accessor(a),args,n++);
    self->do_expand=1;
    self->expanded=0;
    a->length = 0;
}

static void dump(grib_accessor* a, grib_dumper* dumper)
{
    grib_dump_long(dumper,a,NULL);
}

static bufr_descriptors_array* do_expand(grib_accessor* a,bufr_descriptors_array* unexpanded,change_coding_params* ccp,int *err);

#if MYDEBUG
static int global_depth=-1;
#endif

static size_t __expand(grib_accessor* a, bufr_descriptors_array* unexpanded, bufr_descriptors_array* expanded,
        change_coding_params* ccp, int* err)
{
    int k,j,i;
    grib_accessor_expanded_descriptors* self = (grib_accessor_expanded_descriptors*)a;
    size_t size=0;
    long* v=NULL;
    bufr_descriptor* u=NULL;
    bufr_descriptor* vv=NULL;
    bufr_descriptor** ur=NULL;
    bufr_descriptor* urc=NULL;
    int idx;
    bufr_descriptor* u0=NULL;
    grib_context* c=a->context;
    bufr_descriptor* us=NULL;
    bufr_descriptors_array* inner_expanded=NULL;
    bufr_descriptors_array* inner_unexpanded=NULL;
#if MYDEBUG
    int idepth;
#endif

    if (grib_bufr_descriptors_array_used_size(unexpanded)==0) return 0;

    us=grib_bufr_descriptor_clone(grib_bufr_descriptors_array_get(unexpanded,0));

    *err=0;
#if MYDEBUG
    for (idepth=0;idepth<global_depth;idepth++) printf("\t");
    printf("expanding ==> %d-%02d-%03d\n",us->F,us->X,us->Y);
#endif
    switch (us->F) {
    case 3:
        /* sequence */
        DESCRIPTORS_POP_FRONT_OR_RETURN(unexpanded,u);
#if MYDEBUG
        for (idepth=0;idepth<global_depth;idepth++) printf("\t");
        printf("+++ pop  %06ld\n",u->code);
#endif
        /*this is to get the sequence elements of the sequence unexpanded[i] */
        *err=grib_set_long(grib_handle_of_accessor(a),self->sequence,u->code);
        *err=grib_get_size(grib_handle_of_accessor(a),self->sequence,&size);
        grib_bufr_descriptor_delete(u);
        if (*err) return 0;
        v=(long*)grib_context_malloc_clear(c,sizeof(long)*size);
        *err=grib_get_long_array(grib_handle_of_accessor(a),self->sequence,v,&size);
        if (*err) return 0;
        inner_unexpanded=grib_bufr_descriptors_array_new(c,100,100);
        for (i=0;i<size;i++) {
            vv=grib_bufr_descriptor_new(self->tablesAccessor,v[i],err);
            inner_unexpanded=grib_bufr_descriptors_array_push(inner_unexpanded,vv);
        }
        grib_context_free(c,v);
        inner_expanded=do_expand(a,inner_unexpanded,ccp,err);
        grib_bufr_descriptors_array_delete(inner_unexpanded);
#if MYDEBUG
        for (i=0;i<inner_expanded->n;i++) {
            for (idepth=0;idepth<global_depth;idepth++) printf("\t");
            printf("+++ push %06ld\n",inner_expanded->v[i]->code);
        }
#endif
        size=grib_bufr_descriptors_array_used_size(inner_expanded);
        expanded=grib_bufr_descriptors_array_append(expanded,inner_expanded);
        break;

    case 1:
        if (us->Y==0) {
            /* delayed replication */
            bufr_descriptor* uidx=0;
            DESCRIPTORS_POP_FRONT_OR_RETURN(unexpanded,u);
#if MYDEBUG
            for (idepth=0;idepth<global_depth;idepth++) printf("\t");
            printf("+++ pop  %06ld\n",u->code);
            for (idepth=0;idepth<global_depth;idepth++) printf("\t");
            printf("+++ push %06ld\n",u->code);
#endif
            grib_bufr_descriptors_array_push(expanded,u);
            idx=expanded->n-1;
            size=0;
            inner_unexpanded=grib_bufr_descriptors_array_new(c,100,100);

            for (j=0;j<us->X+1;j++) {
                DESCRIPTORS_POP_FRONT_OR_RETURN(unexpanded, u0);
                grib_bufr_descriptors_array_push(inner_unexpanded,u0);
#if MYDEBUG
                for (idepth=0;idepth<global_depth;idepth++) printf("\t");
                printf("+++ pop  %06ld\n",u0->code);
#endif
            }
            inner_expanded=do_expand(a,inner_unexpanded,ccp,err);
            grib_bufr_descriptors_array_delete(inner_unexpanded);
            size=grib_bufr_descriptors_array_used_size(inner_expanded);
#if MYDEBUG
            for (i=0;i<inner_expanded->n;i++) {
                for (idepth=0;idepth<global_depth;idepth++) printf("\t");
                printf("+++ push %06ld\n",inner_expanded->v[i]->code);
            }
#endif
            expanded=grib_bufr_descriptors_array_append(expanded,inner_expanded);
            uidx=grib_bufr_descriptors_array_get(expanded,idx);
            grib_bufr_descriptor_set_code(0,(size-1)*1000+100000,uidx);
            size++;
        } else {
            DESCRIPTORS_POP_FRONT_OR_RETURN(unexpanded,u);
#if MYDEBUG
            for (idepth=0;idepth<global_depth;idepth++) printf("\t");
            printf("+++ pop  %06ld\n",u->code);
#endif
            grib_bufr_descriptor_delete(u);
            size=us->X*us->Y;
            ur=(bufr_descriptor**)grib_context_malloc_clear(c,us->X*sizeof(bufr_descriptor));
            for (j=0;j<us->X;j++) {
                DESCRIPTORS_POP_FRONT_OR_RETURN(unexpanded,ur[j]);
#if MYDEBUG
                for (idepth=0;idepth<global_depth;idepth++) printf("\t");
                printf("+++ pop  %06ld\n",ur[j]->code);
#endif
            }
            inner_unexpanded=grib_bufr_descriptors_array_new(c,100,100);
            for (j=0;j<us->X;j++) {
                urc=grib_bufr_descriptor_clone(ur[j]);
                grib_bufr_descriptors_array_push(inner_unexpanded,urc);
            }
            for (k=1;k<us->Y;k++) {
                for (j=0;j<us->X;j++) {
                    urc=grib_bufr_descriptor_clone(ur[j]);
                    grib_bufr_descriptors_array_push(inner_unexpanded,urc);
                }
            }
            for (i=0;i<us->X;i++) grib_bufr_descriptor_delete(ur[i]);
            grib_context_free(c,ur);
            inner_expanded=do_expand(a,inner_unexpanded,ccp,err);
            grib_bufr_descriptors_array_delete(inner_unexpanded);
#if MYDEBUG
            for (i=0;i<inner_expanded->n;i++) {
                for (idepth=0;idepth<global_depth;idepth++) printf("\t");
                printf("+++ push %06ld\n",inner_expanded->v[i]->code);
            }
#endif
            size=grib_bufr_descriptors_array_used_size(inner_expanded);
            expanded=grib_bufr_descriptors_array_append(expanded,inner_expanded);
        }
        break;

    case 0:
        DESCRIPTORS_POP_FRONT_OR_RETURN(unexpanded,u);
        size=1;
        if (ccp->associatedFieldWidth && u->X!=31) {
            bufr_descriptor* au=grib_bufr_descriptor_new(self->tablesAccessor,999999,err);
            au->width=ccp->associatedFieldWidth;
            grib_bufr_descriptor_set_scale(au,0);
            au->shortName=grib_context_strdup(c,"associatedField");
            /* au->name=grib_context_strdup(c,"associated field");  See ECC-489 */
            au->units=grib_context_strdup(c,"associated units");
#if MYDEBUG
            for (idepth=0;idepth<global_depth;idepth++) printf("\t");
            printf("+++ push %06ld (%ld %g %ld)",au->code,au->scale,au->reference,au->width);
#endif
            grib_bufr_descriptors_array_push(expanded,au);
            size++;
        }
#if MYDEBUG
        for (idepth=0;idepth<global_depth;idepth++) printf("\t");
        printf("+++ pop  %06ld\n",u->code);
        for (idepth=0;idepth<global_depth;idepth++) printf("\t");
        printf("+++ push %06ld [type=%d] (%ld %g %ld)",u->code,
                u->type,u->scale,u->reference,u->width);
#endif
        if ( u->type!=BUFR_DESCRIPTOR_TYPE_FLAG  &&
                u->type!=BUFR_DESCRIPTOR_TYPE_TABLE &&
                u->type!=BUFR_DESCRIPTOR_TYPE_STRING  ) {
            if (ccp->localDescriptorWidth>0) {
                u->width=ccp->localDescriptorWidth;
                u->reference=0;
                grib_bufr_descriptor_set_scale(u,0);
                ccp->localDescriptorWidth=0;
            } else {
                u->width += ccp->extraWidth;
                u->reference *= ccp->referenceFactor;
                grib_bufr_descriptor_set_scale(u,u->scale+ccp->extraScale);
            }
        } else if (u->type==BUFR_DESCRIPTOR_TYPE_STRING && ccp->newStringWidth!=0) {
            u->width=ccp->newStringWidth;
        }
#if MYDEBUG
        printf("->(%ld %g %ld)\n",u->scale,u->reference,u->width);
#endif
        grib_bufr_descriptors_array_push(expanded,u);
        break;

    case 2:
        DESCRIPTORS_POP_FRONT_OR_RETURN(unexpanded,u);
#if MYDEBUG
        for (idepth=0;idepth<global_depth;idepth++) printf("\t");
        printf("+++ pop  %06ld\n",u->code);
#endif
        switch(us->X) {
        case 1:
            ccp->extraWidth = us->Y ? us->Y-128 : 0;
            size=0;
            grib_bufr_descriptor_delete(u);
            break;
        case 2:
            ccp->extraScale = us->Y ? us->Y-128 : 0;
            size=0;
            grib_bufr_descriptor_delete(u);
            break;
        case 4:
            /* associated field*/
            ccp->associatedFieldWidth=us->Y;
            grib_bufr_descriptor_delete(u);
            break;
        case 6:
            /*signify data width*/
            ccp->localDescriptorWidth=us->Y;
            size=0;
            grib_bufr_descriptor_delete(u);
            break;
        case 7:
            if (us->Y) {
                ccp->extraScale = us->Y;
                ccp->referenceFactor=grib_power(us->Y,10);
                ccp->extraWidth=((10*us->Y)+2)/3;
            } else {
                ccp->extraWidth=0;
                ccp->extraScale=0;
                ccp->referenceFactor=1;
            }
            size=0;
            grib_bufr_descriptor_delete(u);
            break;
        case 8:
            ccp->newStringWidth = us->Y * 8 ;
            break;
        default:
#if MYDEBUG
            for (idepth=0;idepth<global_depth;idepth++) printf("\t");
            printf("+++ push %06ld\n",u->code);
#endif
            grib_bufr_descriptors_array_push(expanded,u);
            size=1;
        }
        break;

        default:
            DESCRIPTORS_POP_FRONT_OR_RETURN(unexpanded,u);
#if MYDEBUG
            for (idepth=0;idepth<global_depth;idepth++) printf("\t");
            printf("+++ pop  %06ld\n",u->code);
            for (idepth=0;idepth<global_depth;idepth++) printf("\t");
            printf("+++ push %06ld\n",u->code);
#endif
            grib_bufr_descriptors_array_push(expanded,u);
            size=1;
    }
#if MYDEBUG
    for (idepth=0;idepth<global_depth;idepth++) printf("\t");
    printf("expanding <== %d-%.2d-%.3d (size=%ld)\n\n",us->F,us->X,us->Y,size);
#endif
    if (us) grib_bufr_descriptor_delete(us);
    return size;
}

static bufr_descriptors_array* do_expand(grib_accessor* a,bufr_descriptors_array* unexpanded,change_coding_params* ccp,int *err)
{
    bufr_descriptors_array* expanded=NULL;
    grib_context* c=a->context;
#if MYDEBUG
    int idepth;
    global_depth++;
#endif

    expanded=grib_bufr_descriptors_array_new(c,100,100);

#if MYDEBUG
    {
        int i;
        for (idepth=0;idepth<global_depth;idepth++) printf("\t");
        printf("to be expanded ==> \n");
        for (i=0;i<unexpanded->n;i++) {
            bufr_descriptor* xx=grib_bufr_descriptors_array_get(unexpanded,i);
            for (idepth=0;idepth<global_depth;idepth++) printf("\t");
            printf("%06ld\n",xx->code);
        }
        for (idepth=0;idepth<global_depth;idepth++) printf("\t");
        printf("to be expanded <== \n\n");
    }
#endif
    while (unexpanded->n) {
        __expand(a,unexpanded,expanded,ccp,err);
    }
#if MYDEBUG
    {
        int i;
        for (idepth=0;idepth<global_depth;idepth++) printf("\t");
        printf("expanded ==> \n");
        for (i=0;i<expanded->n;i++) {
            bufr_descriptor* xx=grib_bufr_descriptors_array_get(expanded,i);
            for (idepth=0;idepth<global_depth;idepth++) printf("\t");
            printf("==  %-6d== %06ld ",i,xx->code);
            printf("%ld %g %ld",xx->scale,xx->reference,xx->width);
            printf("\n");
        }
        for (idepth=0;idepth<global_depth;idepth++) printf("\t");
        printf("expanded <== \n\n");
    }
#endif

#if MYDEBUG
    global_depth--;
#endif

    return expanded;
}

static bufr_descriptors_array* expanded_descriptors_list_get(grib_context* c,const char* key,long* u,size_t size) {
  bufr_descriptors_map_list*  expandedUnexpandedMapList;
  size_t i=0;
  int found=0;

  if (!c->expanded_descriptors) {
    c->expanded_descriptors=(grib_trie*)grib_trie_new(c);
    return NULL;
  }
  expandedUnexpandedMapList=(bufr_descriptors_map_list*)grib_trie_get(c->expanded_descriptors,key);
  found=0;
  while (expandedUnexpandedMapList) {
    if (expandedUnexpandedMapList->unexpanded->n==size) {
      found=1;
      for (i=0;i<size;i++) {
        if (expandedUnexpandedMapList->unexpanded->v[i]->code!=u[i]) {
          found=0;
          break;
        }
      }
    }
    if (found) return expandedUnexpandedMapList->expanded;
    expandedUnexpandedMapList=expandedUnexpandedMapList->next;
  }

  return NULL;
}

static void expanded_descriptor_list_push(grib_context* c,grib_trie* expanded_descriptors,const char* key,bufr_descriptors_array* expanded,bufr_descriptors_array* unexpanded) {
  bufr_descriptors_map_list* descriptorsList=NULL;
  bufr_descriptors_map_list* next=NULL;
  bufr_descriptors_map_list*  newdescriptorsList=NULL;

  newdescriptorsList=(bufr_descriptors_map_list*)grib_context_malloc_clear(c,sizeof(bufr_descriptors_map_list));
  newdescriptorsList->expanded=expanded;
  newdescriptorsList->unexpanded=unexpanded;

  descriptorsList=(bufr_descriptors_map_list*)grib_trie_get(expanded_descriptors,key);
  if (descriptorsList) {
    next=descriptorsList;
    while(next->next) {
      next=next->next;
    }
    next->next=newdescriptorsList;
  } else {
    grib_trie_insert(expanded_descriptors,key,newdescriptorsList);
  }
}

static int expand(grib_accessor* a)
{
    grib_accessor_expanded_descriptors* self = (grib_accessor_expanded_descriptors*)a;
    int err=0;
    size_t unexpandedSize=0;
    /* grib_iarray* unexp=0; */
    int i;
    long* u=0;
    char key[50]={0,};
    long centre,masterTablesVersionNumber,localTablesVersionNumber,masterTablesNumber;
    change_coding_params ccp;
    bufr_descriptors_array* unexpanded=NULL;
    bufr_descriptors_array* unexpanded_copy=NULL;
    bufr_descriptors_array* expanded=NULL;
    grib_context* c=a->context;
    grib_handle* h=grib_handle_of_accessor(a);
    int operator206yyy_width = 0; /* width specified by operator 206YYY */

    if (!self->do_expand) {
        return err;
    }
    self->do_expand=0;
    if (self->rank!=0) {
        err=expand(self->expandedAccessor);
        self->expanded=((grib_accessor_expanded_descriptors*)self->expandedAccessor)->expanded;
        return err;
    }

    err=grib_get_size(grib_handle_of_accessor(a),self->unexpandedDescriptors,&unexpandedSize);
    if (err) return err;
    if (unexpandedSize==0) {
        grib_context_log(c, GRIB_LOG_ERROR, "%s: Unexpanded size is zero!", a->name);
        return GRIB_DECODING_ERROR;
    }
    u=(long*)grib_context_malloc_clear(c,sizeof(long)*unexpandedSize);
    if (!u) {err=GRIB_OUT_OF_MEMORY; return err;}
    err=grib_get_long_array(grib_handle_of_accessor(a),self->unexpandedDescriptors,u,&unexpandedSize);
    if (err) return err;

    err=grib_get_long(h,"bufrHeaderCentre",&centre);
    if (err) return err;
    err=grib_get_long(h,"masterTablesVersionNumber",&masterTablesVersionNumber);
    if (err) return err;
    err=grib_get_long(h,"localTablesVersionNumber",&localTablesVersionNumber);
    if (err) return err;
    err=grib_get_long(h,"masterTableNumber",&masterTablesNumber);
    if (err) return err;

    sprintf(key,"%ld_%ld_%ld_%ld_%ld",centre,masterTablesVersionNumber,localTablesVersionNumber,masterTablesNumber,u[0]);
    expanded=expanded_descriptors_list_get(c,key,u,unexpandedSize);
    if (expanded) {
      self->expanded=expanded;
      grib_context_free(c,u);
      return err;
    }

    if (!self->tablesAccessor) {
        self->tablesAccessor=grib_find_accessor(grib_handle_of_accessor(a),self->tablesAccessorName);
        Assert(self->tablesAccessor);
    }

    unexpanded=grib_bufr_descriptors_array_new(c,unexpandedSize,100);
    unexpanded_copy=grib_bufr_descriptors_array_new(c,unexpandedSize,100);
    operator206yyy_width = 0;
    for (i=0;i<unexpandedSize;i++) {
        bufr_descriptor* aDescriptor1 = grib_bufr_descriptor_new(self->tablesAccessor, u[i], &err);
        bufr_descriptor* aDescriptor2 = grib_bufr_descriptor_new(self->tablesAccessor, u[i], &err);

        /* ECC-433: Operator 206YYY */
        if (aDescriptor1->F == 2 && aDescriptor1->X == 6) {
            Assert(aDescriptor1->type == BUFR_DESCRIPTOR_TYPE_OPERATOR);
            operator206yyy_width = aDescriptor1->Y; /* Store the width for the following descriptor */
            DebugAssert(operator206yyy_width > 0);
        }
        else if (operator206yyy_width>0) {
            if (err == GRIB_NOT_FOUND) {
                DebugAssert( aDescriptor1->type == BUFR_DESCRIPTOR_TYPE_UNKNOWN );
                err = 0;     /* Clear any error generated due to local descriptor */
                aDescriptor1->nokey = aDescriptor2->nokey = 1;   /* Do not show this descriptor in dump */
            }
            /* The width specified by operator takes precedence over element's own width */
            aDescriptor1->width = aDescriptor2->width = operator206yyy_width;
            operator206yyy_width = 0; /* Restore. Operator no longer in scope */
        }

        grib_bufr_descriptors_array_push(unexpanded,      aDescriptor1);
        grib_bufr_descriptors_array_push(unexpanded_copy, aDescriptor2);
    }

    grib_context_free(c,u);

    ccp.extraWidth=0;
    ccp.localDescriptorWidth=-1;
    ccp.extraScale=0;
    ccp.referenceFactor=1;
    ccp.associatedFieldWidth=0;
    ccp.newStringWidth=0;
    self->expanded=do_expand(a,unexpanded,&ccp,&err);
    expanded_descriptor_list_push(c,c->expanded_descriptors,key,self->expanded,unexpanded_copy);
    grib_bufr_descriptors_array_delete(unexpanded);

    return err;
}

int grib_accessor_class_expanded_descriptors_set_do_expand(grib_accessor* a,long do_expand)
{
    grib_accessor_expanded_descriptors* self = (grib_accessor_expanded_descriptors*)a;
    self->do_expand=do_expand;
    return 0;
}

bufr_descriptors_array* grib_accessor_class_expanded_descriptors_get_expanded(grib_accessor* a,int* err)
{
    grib_accessor_expanded_descriptors* self = (grib_accessor_expanded_descriptors*)a;
    *err=expand(a);
    return self->expanded;
}

static int unpack_double(grib_accessor* a, double* val, size_t *len)
{
    grib_accessor_expanded_descriptors* self = (grib_accessor_expanded_descriptors*)a;
    int ret=0;
    int i;
    size_t expandedSize;

    if (self->rank!=2) {
        long* lval=(long*)grib_context_malloc_clear(a->context,*len*sizeof(long));
        ret=unpack_long(a,lval,len);
        if (ret) return ret;
        for (i=0;i<*len;i++) val[i]=(double)lval[i];
        grib_context_free(a->context,lval);
    } else {
        ret=expand(a);
        if (ret) return ret;

        expandedSize=grib_bufr_descriptors_array_used_size(self->expanded);
        if(*len < expandedSize)
        {
            grib_context_log(a->context, GRIB_LOG_ERROR,
                    " wrong size (%ld) for %s it contains %d values ",*len, a->name , expandedSize);
            *len = 0;
            return GRIB_ARRAY_TOO_SMALL;
        }
        *len = expandedSize;
        for (i=0;i<*len;i++) val[i]=self->expanded->v[i]->reference;
    }
    return ret;
}

static int unpack_long(grib_accessor* a, long* val, size_t *len)
{
    grib_accessor_expanded_descriptors* self = (grib_accessor_expanded_descriptors*)a;
    int ret=0;
    size_t rlen=0;
    size_t i;

    ret=expand(a);
    rlen=grib_bufr_descriptors_array_used_size(self->expanded);
    if (ret) return ret;

    if(*len < rlen)
    {
        grib_context_log(a->context, GRIB_LOG_ERROR,
                " wrong size (%ld) for %s it contains %d values ",*len, a->name , rlen);
        *len = 0;
        return GRIB_ARRAY_TOO_SMALL;
    }

    *len = rlen;
    switch (self->rank) {
    case 0:
        for (i=0;i<*len;i++) val[i]=self->expanded->v[i]->code;
        break;
    case 1:
        for (i=0;i<*len;i++) val[i]=self->expanded->v[i]->scale;
        break;
    case 2:
        return GRIB_INVALID_TYPE;
        break;
    case 3:
        for (i=0;i<*len;i++) val[i]=self->expanded->v[i]->width;
        break;
    case 4:
        for (i=0;i<*len;i++) val[i]=self->expanded->v[i]->type;
        break;
    }

    return GRIB_SUCCESS;
}

static int pack_long(grib_accessor* a, const long* val, size_t *len)
{
    grib_accessor_expanded_descriptors* self = (grib_accessor_expanded_descriptors*)a;
    self->do_expand=1;
    return GRIB_NOT_IMPLEMENTED;
}

static int value_count(grib_accessor* a,long* rlen)
{
    grib_accessor_expanded_descriptors* self = (grib_accessor_expanded_descriptors*)a;
    int ret=0;
    grib_context* c=a->context;
    *rlen=0;

    ret=expand(a);
    *rlen=grib_bufr_descriptors_array_used_size(self->expanded);
    if (ret) {
        grib_context_log(c,GRIB_LOG_ERROR,"%s unable to compute size",a->name);
        return ret;
    }

    return ret;
}

static void destroy(grib_context* c,grib_accessor* a)
{
    /* grib_accessor_expanded_descriptors* self = (grib_accessor_expanded_descriptors*)a; */
    /* if (self->rank==0 && self->expanded) { */
       /* grib_bufr_descriptors_array_delete(self->expanded); */
    /* } */
}

static int  get_native_type(grib_accessor* a)
{
    grib_accessor_expanded_descriptors* self = (grib_accessor_expanded_descriptors*)a;
    if (self->rank==2) return GRIB_TYPE_DOUBLE;
    else return GRIB_TYPE_LONG;
}